I want to find the socket instance using the socket id
I saw a solution on stackoverflow and tried it, but it didn't work.
Make specific socket leave the room is in
exports.removeParticipant = ({ data }) => {
const { roomId, toBeRemovedSocketId } = data;
const roomFound = rooms.find((room) => room.id === roomId);
if (roomFound) {
const user = roomFound.connectedUsers.find(
(user) => user.socketId === toBeRemovedSocketId
);
/* Removing the user from the room.connectedUserArray . */
roomFound.connectedUsers = roomFound.connectedUsers.filter(
(user) => user.socketId !== toBeRemovedSocketId
);
//i tried this but it throws error
let socket = io.sockets.connected[toBeRemovedSocketId];
socket.leave(roomId);
}
my own research led me to a solution.
let socket=io.sockets.sockets.get(toBeRemovedSocketId);
socket.leave(roomId)
Related
TypeError: contracts.filter is not a function
at C:\Users\cross\Desktop\ALL AI BOTS\Telegram Contract\bot.js:61:43
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
TypeError: Cannot read properties of undefined (reading 'data')
at C:\Users\cross\Desktop\ALL AI BOTS\Telegram Contract\bot.js:101:32
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
function getRecentVerifiedContracts() {
const url = 'https://api.etherscan.io/api';
const params = {
module: 'contract',
action: 'getsourcecode',
apikey: process.env.ETHERSCAN_API_KEY,
sort: 'desc',
};
return axios.get(url, { params })
.then(response => {
const contracts = response.data.result;
// Filter verified contracts and retrieve contract code
const verifiedContracts = contracts.filter(contract => contract.IsVerified === '1');
const promises = verifiedContracts.map(contract => getContractCode(contract.ContractAddress));
return Promise.all(promises);
})
.then(contractCodes => {
// Filter contracts with at least one link and pass verification
const filteredContracts = contractCodes.filter(contractCode => {
const telegramLink = contractCode.match(/t\.me\/\S+/);
const websiteLink = contractCode.match(/http[s]?:\/\/\S+/);
const twitterLink = contractCode.match(/twitter\.com\/\S+/);
if (telegramLink || websiteLink || twitterLink) {
return checkVerification(contractCode);
}
return false;
});
// Send message for each filtered contract
const promises = filteredContracts.map(contractCode => {
const contractAddress = contractCode.match(/contract (\S+)/)[1];
const telegramLink = contractCode.match(/t\.me\/\S+/);
const websiteLink = contractCode.match(/http[s]?:\/\/\S+/);
const twitterLink = contractCode.match(/twitter\.com\/\S+/);
let messageText = `New verified contract on Etherscan: ${contractAddress}\n`;
if (telegramLink) {
messageText += `Telegram: ${telegramLink}\n`;
}
if (websiteLink) {
messageText += `Website: ${websiteLink}\n`;
}
if (twitterLink) {
messageText += `Twitter: ${twitterLink}\n`;
}
return bot.sendMessage(process.env.TELEGRAM_CHAT_ID, messageText);
});
return Promise.all(promises);
})
.catch(error => {
console.error(error);
console.log(error.response.data);
bot.sendMessage(process.env.TELEGRAM_CHAT_ID, 'An error occurred while retrieving recent verified contracts');
});
}
I'm getting an error from my Node Js, I'm trying to use Etherscan API to get the most recent contracts created on the mainnet. So once you type /recent in the telegram bot chat he should respond with the Twitter, Telegram, Website of that contract (only if it's mentioned in the source code). So when I type /recent bot responds with Telegram, Twitter, Website of the most RECENT contract created on the mainnet, if the most recent contract is NOT verified or does not include any of the socials than that's seen as "invalid".
I am making a chat app, but when I write a message and press send, my node server keep giving me:
TypeError: Cannot read property 'trim' of undefined
or
TypeError: Cannot read property 'room' of undefined
Then it crashes, I don't know why, everything else was working normally, only the server crashes. I've tried fixing it myself to no avail, without the server, you can probably guess what will happen.
Here's the code:
index.js:
var express = require ('express')
var http = require ('http')
var { addUser, removeUser, getUser, getUsersInRoom } = require ('./user')
var router = require ('./router')
var { callbackify } = require('util')
var PORT = process.env.PORT || 5000
var app = express()
var server = http.createServer(app)
var io = require('socket.io')(server, {
cors: {
origin: '*',
}
});
app.use(router)
io.on('connection', (socket) => {
socket.on('join', ({ name, room }, callback) =>{
var { error, user } = addUser({ id: socket.id, name, room })
if(error) return callback(error)
socket.emit('message', { user: 'admin', text: `Now, I- Oh, ${user.name}, welcome to room ${user.room},enjoy your time here!` })
socket.broadcast.to(user.room).emit('message',{user: 'admin', text:`Hey, just coming in to say ${user.name} joined, also, how you guys doin.`})
socket.join(user.room)
callback()
})
socket.on('sendMessage', (message, callback) => {
var user = getUser(socket.id)
io.to(user.room).emit('message', { user: user.name, text: message })
callback()
})
socket.on('disconnect', () => {
console.log('Aw they left :(');
});
});
server.listen(PORT, () => console.log (`This is Index, port ${PORT} secured, lots of unfixable bug`))
user.js(where the problem exist):
const users = []
const addUser = ({ id, name, room }) =>{
name = name.trim().toLowerCase()
room = room.trim().toLowerCase()
const existingUser = users.find((user) => user.room === room && user.name === name)
if(existingUser){
return {error: 'Username is already taken you dumbass'}
}
const user = {id, name, room}
users.push(user);
return{ user }
}
const removeUser = (id) =>{
const index = users.findIndex ((user) => user.id === id)
if(index !== -1) {
return users.splice(index, 1)[0]
}
}
const getUser = (id) => users.find((user) => user.id === id)
const getUsersInRoom = (room) => users.filter((user) => user.room === room)
module.exports = { addUser, removeUser, getUser, getUsersInRoom }
and router.js:
const express = require('express')
const router = express.Router();
router.get('/*', (req,res) =>{
res.send(`Server is up and running`)
})
module.exports = router;
That is all the server file because the problem comes from server, not client (there is not enough words in here so I have to do this)
Thanks in advance!
Both error is due to the application is trying to access a subfunction/subparameter of an undefined value.
Are you sure the client is sending the right param when emitting "join" ?
what you can do on the server side is do some validation and check if its undefined and set a default value if it is.
name = name ? name.trim().toLowerCase() : "default_name";
room = room ? room.trim().toLowerCase() : "default_room";
as for the Room of undefined error is most likely due to this part of the app
const existingUser = users.find((user) => user.room === room && user.name === name)
try checking if users.length, if it's 0 then don't bother doing .find(), or you can add validation inside the .find() function to check if user is undefined,then return false;
const existingUser = users.find((user) => user && user.room === room && user.name === name)
socket.on('join', ({ name, room }, callback) =>{
Where do you get name and room from?
I am trying to develop a live chat app using web sockets and react, but after I try submitting several messages (around 30) the web socket gets stuck on the CONNECTING state. I have it set up so when it does send a message it disabled the send button to prevent users from spamming messages too fast but I unfortunately still get the same issue.
// id is a uuid() string
const ws = new WebSocket(`ws://localhost:3001/chat/${id}`);
useEffect(() => {
ws.onmessage = function(evt){
try{
const user_id = parseInt(evt.data.split("")[0]);
const message = evt.data.slice(1);
const currentTime = new Date();
const currentUTC = currentTime.toUTCString();
const timestamp = new Date(currentUTC);
setMessages(messages => [...messages, {user_id, message, timestamp}])
} catch(e){
console.log(e);
}
}
ws.onclose = function(evt){
console.log("DISCONNECTED!!")
ws.close();
}
ws.onerror = function(evt){
console.log(evt);
ws.close();
}
}, []);
useEffect(() => {
async function postMessageToAPI() {
const messsageToSend = {
unique_id: id,
message: formData.message,
user_id: user.id,
group_chat_id: room.id
}
// Convert to unviersal time UTC and send it to database
let currentUTC = new Date();
currentUTC.toUTCString();
messsageToSend.timestamp = currentUTC;
await AnonChatApi.sendChatMessage(messsageToSend);
}
if(sendMessage){
ws.onopen = function(){
// add user_id to the start of the message string
const message = `${user.id}` + formData.message;
ws.send(message);
}
postMessageToAPI();
resetFormData();
setTimeout(() => {
setSendMessage(false)
}, 1000);
}
}, [sendMessage]);
const goBackHome = () => {
ws.close();
history.push('/');
}
I can see you're using Hooks, so you must also be using Function Components.
Am I correct in thinking that the code to initialize the websocket
const ws = new WebSocket(`ws://localhost:3001/chat/${id}`);
is at the top of the function?
As a reminder, the function which defines your Function Component is run whenever your component is rendered. Anything that isn't saved in state is lost. This includes your websocket - a new one will be created every render, your async functions may sending data on an old websocket (from a previous render), and React may warn you in the console that you have a memory leak.
useEffect is the proper approach here, but the websocket also needs to be saved in state.
YourFunctionComponent() {
const [ws, setWs] = useState(null);
useEffect(() => {
if (ws == null) {
setWs(new WebSocket(`ws://localhost:3001/chat/${id}`));
}
return () => {
// A function returned from useEffect will
// get called on component unmount.
// Use this function to clean up your connection and
// close your websocket!
// clean up, e.g.
// ws.send('closing due to unmount!');
ws.close();
setWs(null);
}
}, [ws, setWs]);
// Add `ws` as a dependency in the useEffect()s you posted above
useEffect(() => {
ws.onmessage = function(evt){
[--snip--]
}
}, [ws]);
useEffect(() => {
async function postMessageToAPI() {
[--snip--]
}
}, [sendMessage, ws]);
}
I want get info about reactions but i can't. I need get reaction and authors this reactions from old message without listeners or something.
This code make something similar https://gist.github.com/acollierr17/c9e7aaf9eba97d8659b59395b5f2046d but don't work for me, var is empty. But i can get message m.channel.fetchMessage(ID)
I don't understand why this does not work, although the message is received to var. How collect all reactions and their authors of message to array?
I try this and few other ways.
if(calcreact == 1 && msg.content.startsWith('/calcreact')) { //start
calcreact = 0; // защита от флуда
let msgid = finddata(msg.content);
//let channel = 709517297664131082;
msg.channel.fetchMessage(msgid)
.then(m => {
//console.log('Message:', message.content);
let reactions = m.reactions;
let reaction = reactions.first();
let users = reaction.users.map((u) => u.toString());
console.log(users);
//console.log(m.reactions.fetch());
//console.log(m.reactions.forEach((reaction) => {}));
m.reactions.forEach((reaction) => console.log(reaction));
m.reactions.forEach((reaction) => console.log(reaction.users));
m.reactions.forEach((reaction) => console.log(reaction.users.map((u) => u.toString())) );
//console.log('Reactions:', );
});
setTimeout(antiflood, 500, 'calcreact');
} //end
From m.reactions.forEach((reaction) => console.log(reaction)); i can get huge info "array" and in marked current reaction(It seems to me https://i.imgur.com/OazszNR.png) but deep (users) empty. This is horrible...
The function bellow groups reactions by users, like this:
{
userId1: ['reactionId1', 'reactionId2'],
userId2: ['reactionId1', 'reactionId2'],
...
}
You can adapt this to get the users and reactions from messages, or any context you like.
OBS: It was written in TypeScript, but if you remove the typing, it turns into JavaScript.
Function:
import { MessageReaction } from "discord.js";
interface IReactionsByUsers {
[userId: string]: Array<string>;
}
DiscordClient.on("messageReactionAdd", (reaction: MessageReaction) => {
const reducer = (acc: IReactionsByUsers, cur: [string, MessageReaction]) => {
const [reactionId, reaction] = cur;
const usersIds = [...reaction.users.cache].map(([userId]) => userId);
for (const userId of usersIds) {
if (acc[userId]) {
acc[userId].push(reactionId);
} else {
acc[userId] = [reactionId];
}
}
return acc;
};
const messageReactions = [...reaction.message.reactions.cache];
const reactionByUsers = messageReactions.reduce(
reducer,
{} as IReactionsByUsers
);
return reactionByUsers;
});
use the client.on("messageReactionAdd" method and save the reactions in an array.
I have tried Firebase cloud function for sending a notification.My project structure
and this is the index.js,
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.pushNotification = functions.database.ref('/messages').onWrite( event => {
console.log('Push notification event triggered');
const message = event.data.val();
const user = event.data.val();
console.log(message);
console.log(user);
const topic = "myTopic";
const payload = {
"data": {
"title": "New Message from " + user,
"detail":message,
}
};
return admin.messaging().sendToTopic(topic, payload);
});
The above code is misconfigured, when I deploy in Node.js, LOG in Function shows:
"TypeError: Cannot read property 'val' of undefined".
What Actually I am trying to do :
I am trying to extract info from snapshot load into that index.js so that when a new child gets added to Real-time database, it should trigger a notification payload with a title and body.
In Android, I use a child listener, for listening when a new record is added
FirebaseDatabase.getInstance().getReference().child("messages")
OnChildAdded(.....){
if (dataSnapshot != null) {
MessageModel messageModel = dataSnapshot.getValue(MessageModel.class);
if (messageModel != null) {
// do whatever
}
}
But in index.js, I could not able to parse that.
A bit guidance how to fixate index.js according to my database structure would be immensely appreciated.
PS- I have never done coding in JS
If you want more context, I'd be happy to provide it.
Change this:
exports.pushNotification = functions.database.ref('/messages').onWrite( event => {
const message = event.data.val();
const user = event.data.val();
});
to this:
exports.pushNotification = functions.database.ref('/messages').onWrite(( change,context) => {
const message = change.after.val();
});
Please check this:
https://firebase.google.com/docs/functions/beta-v1-diff#realtime-database
The cloud functions were changed and now onWrite has two parameters change and context
The change has two properties before and after and each of these is a DataSnapshot with the methods listed here:
https://firebase.google.com/docs/reference/admin/node/admin.database.DataSnapshot
'use strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/NOTIFICATIONS/{UserId}/{{notification_id}').onWrite((change, context) =>
{
const UserId = context.params.UserId;
const notification = context.params.notification;
console.log('The user Id is : ', UserId);
if(!change.after.exists())
{
return console.log('A Notification has been deleted from the database : ', notification_id);
}
if (!change.after.exists())
{
return console.log('A notification has been deleted from the database:', notification);
return null;
}
const deviceToken = admin.database().ref(`/USER/${UserId}/device_token`).once('value');
return deviceToken.then(result =>
{
const token_id = result.val();
const payload = {
notification : {
title : "Friend Request",
body : "You've received a new Friend Request",
icon : "default"
}
};
return admin.messaging().sendToDevice(token_id, payload).then(response => {
console.log('This was the notification Feature');
});
});
});