Invalid channel name - What could be causing this? - node.js
I am working on a site that will have a chatbox on it, basically it has a bunch of channels for different languages as well a channel for moderators and a channel for announcements.
I am getting an error [join] invalid channel name and since i'm so new with coding/developing I thought i'd share my code in hopes someone here can tell me where I messed something up.
CHAT.JS
var assert = require('assert');
var CBuffer = require('CBuffer');
var events = require('events');
var util = require('util');
var _ = require('lodash');
var debug = require('debug')('app:chat');
var db = require('./database');
var lib = require('./lib');
//Mute users by ip/username and store muted users in the database
var CHAT_HISTORY_SIZE = 100;
var SPECIAL_CHANNELS = {
all: {
desc: 'Channel where all messages are broadcasted, read only',
writable: false,
modsOnly: false
},
moderators: {
desc: 'Channel for moderators only, they are joinedds',
writable: true,
modsOnly: true
}
//This is the behaviour for all the other channels:
//defaultProps: {
// desc: '',
// writable: true,
// modsOnly: false
//}
};
// There is a mods channel for every channel
// The mods are joined to a channel called mod:channelName
function Chat(io) {
var self = this;
self.io = io;
// Number of connected clients
self.clientCount = 0;
/*
Collection of muted users.
key: Username
value: Object with the following fields
time: Date object when the user was muted
moderator: The username of the moderator that muted the user
timespec: Initial (nominal diff) time the user has been muted
end: Until when the user is muted
shadow: If the mute is a shadow mute
*/
self.muted = {};
io.on('connection', onConnection);
function onConnection(socket) { //socket.user is attached on the login middleware
debug('socket connection event received');
//Attach disconnect handler
socket.on('disconnect', function() {
--self.clientCount;
console.log('Client disconnect, left: ', self.clientCount);
debug('client disconnect');
});
//Join to a Room
socket.on('join', function(channelName) {
debug('join event received from user %s', socket.user ? socket.user.username : '~guest~');
self.join(socket, channelName);
});
//Register the message event
socket.on('say', function(message, isBot, customChannelName) {
self.onSay(socket, message, isBot, customChannelName);
});
++self.clientCount;
console.log('Client joined: ', self.clientCount, ' - ', socket.user ? socket.user.username : '~guest~'); //TODO: Add ip address
}
events.EventEmitter.call(self); //Call event emitter 'constructor' function
}
util.inherits(Chat, events.EventEmitter);
Chat.prototype.join = function(socket, channelName) {
var self = this;
var moderator = socket.user && socket.user.moderator;
//Check channelName variable and avoid users to join the mods channel
**if(isChannelNameInvalid(channelName) || isChannelNameModsOnly(channelName))
return sendError(socket, '[join] Invalid channel name');**
//Check if the channel is moderators only
if(SPECIAL_CHANNELS.hasOwnProperty(channelName))
if(SPECIAL_CHANNELS[channelName].modsOnly && !moderator)
return sendError(socket, '[join] This channel is moderators only');
//Check if the user was joined to another room before, if it was leave that room
if(socket.currentChannel)
socket.leave(socket.currentChannel);
//If mod leave the mods channel for this channel
if(socket.modCurrentChannel)
socket.leave(socket.modCurrentChannel);
//Save the name of the current room in the socket, this can also be used to check if the user is joined into a channel
socket.currentChannel = channelName;
//Get user history of a room and send it to the user
self.getHistory(channelName, function(err, history) {
//If we couldn't reach the history send an empty history to the user
if(err) {
history = [];
}
var res = {
history: history,
username: socket.user ? socket.user.username : null,
channel: channelName,
moderator: moderator
};
//Actually join the socket.io room
socket.join(channelName);
//If the user is mod and is not on the mods channel join him to the channel mod:channelName
if(moderator && channelName !== 'moderators') {
var chan = 'mod:'+channelName;
socket.join(chan);
socket.modCurrentChannel = chan;
}
//Return join info to the user
socket.emit('join', res);
});
};
Chat.prototype.onSay = function(socket, message, isBot, customChannelName) {
if (!socket.user)
return sendError(socket, '[say] you must be logged in to chat');
if (!socket.currentChannel)
return sendError(socket, '[say] you must be joined before you can chat');
//Check if the message is for a custom channel
var channelName;
if(customChannelName)
if(isChannelNameInvalid(customChannelName))
return sendError(socket, '[say] invalid channel name');
else
channelName = customChannelName;
else
channelName = socket.currentChannel;
//Check if the message is for a non writable channel ('all')
if(SPECIAL_CHANNELS.hasOwnProperty(channelName) && !SPECIAL_CHANNELS[channelName].writable)
return sendErrorChat(socket, 'The all channel is read only');
//Message validation
message = message.trim();
if (typeof message !== 'string')
return sendError(socket, '[say] no message');
if (message.length == 0 || message.length > 500)
return sendError(socket, '[say] invalid message size');
var cmdReg = /^\/([a-zA-z]*)\s*(.*)$/;
var cmdMatch = message.match(cmdReg);
if (cmdMatch) //If the message is a command try to execute it
this.doChatCommand(socket.user, cmdMatch, channelName, socket);
else //If not broadcast the message
this.say(socket, socket.user, message, channelName, isBot);
};
Chat.prototype.doChatCommand = function(user, cmdMatch, channelName, socket) {
var self = this;
var cmd = cmdMatch[1];
var rest = cmdMatch[2];
switch (cmd) {
case 'shutdown':
return sendErrorChat(socket, '[shutdown] deprecated feature boss');
case 'mute':
case 'shadowmute':
if (user.moderator) {
var muteReg = /^\s*([a-zA-Z0-9_\-]+)\s*([1-9]\d*[dhms])?\s*$/;
var muteMatch = rest.match(muteReg);
if (!muteMatch)
return sendErrorChat(socket, 'Usage: /mute <user> [time]');
var username = muteMatch[1];
var timespec = muteMatch[2] ? muteMatch[2] : "30m";
var shadow = cmd === 'shadowmute';
self.mute(shadow, user, username, timespec, channelName,
function (err) {
if (err)
return sendErrorChat(socket, err);
});
} else {
return sendErrorChat(socket, '[mute] Not a moderator.');
}
break;
case 'unmute':
if (user.moderator) {
var unmuteReg = /^\s*([a-zA-Z0-9_\-]+)\s*$/;
var unmuteMatch = rest.match(unmuteReg);
if (!unmuteMatch)
return sendErrorChat(socket, 'Usage: /unmute <user>');
var username = unmuteMatch[1];
self.unmute(
user, username, channelName,
function (err) {
if (err) return sendErrorChat(socket, err);
});
}
break;
default:
sendErrorChat(socket, 'Unknown command ' + cmd);
break;
}
};
Chat.prototype.getHistory = function (channelName, callback) {
if(channelName === 'all')
db.getAllChatTable(CHAT_HISTORY_SIZE, fn);
else
db.getChatTable(CHAT_HISTORY_SIZE, channelName, fn);
function fn (err, history) {
if(err) {
console.error('[INTERNAL_ERROR] got error ', err, ' loading chat table');
return callback(err);
}
callback(null, history);
}
};
Chat.prototype.say = function(socket, user, message, channelName, isBot) {
var self = this;
var date = new Date();
isBot = !!isBot;
var msg = {
date: date,
type: 'say',
username: user.username,
role: user.userclass,
message: message,
bot: isBot,
channelName: channelName
};
//Check if the user is muted
if (lib.hasOwnProperty(self.muted, user.username)) {
var muted = self.muted[user.username];
if (muted.end < date) {
// User has been muted before, but enough time has passed.
delete self.muted[user.username];
} else if (muted.shadow) {
// User is shadow muted. Echo the message back to the
// user but don't broadcast.
self.sendMessageToUser(socket, msg);
return;
} else {
self.sendMessageToUser(socket, {
date: date,
type: 'info',
username: user.username,
role: user.userclass,
message: 'You\'re muted. ' + lib.printTimeString(muted.end - date) + ' remaining',
bot: false,
channelName: channelName
});
return;
}
}
self.sendMessageToChannel(channelName, msg, user.id);
};
/** Send a message to the user of this socket **/
Chat.prototype.sendMessageToUser = function(socket, msg) {
socket.emit('msg', msg);
};
/** Send a message to a channel and to the all channel and store it in the database **/
Chat.prototype.sendMessageToChannel = function(channelName, msg, userID) {
console.assert(msg.hasOwnProperty('bot') && msg.date, msg.hasOwnProperty('message') && msg.type);
this.io.to(channelName).emit('msg', msg);
this.io.to('all').emit('msg', msg);
this.saveChatMessage(userID, msg.message, channelName, msg.bot, msg.date);
};
Chat.prototype.saveChatMessage = function(userId, message, channelName, isBot, date) {
db.addChatMessage(userId, date, message, channelName, isBot, function(err) {
if(err)
console.error('[INTERNAL_ERROR] got error ', err, ' saving chat message of user id ', userId);
});
};
Chat.prototype.mute = function(shadow, moderatorUser, username, time, channelName, callback) {
var self = this;
var now = new Date();
var ms = lib.parseTimeString(time);
var end = new Date(Date.now() + ms);
// Query the db to make sure that the username exists.
db.getUserByName(username, function(err, userInfo) {
if (err) {
if(typeof err === 'string') //USERNAME_DOES_NOT_EXIST
callback(err);
else
console.error('[INTERNAL_ERROR] got error ', err, ' muting user ', userInfo.username);
return;
}
assert(userInfo);
// Overriding previous mutes.
self.muted[userInfo.username] = {
date: now,
moderator: moderatorUser.username,
timespec: time,
end: end,
shadow: shadow
};
var msg = {
date: now,
type: 'mute',
message: null,
moderator: moderatorUser.username,
username: userInfo.username,
timespec: time,
shadow: shadow,
bot: false
};
//If mute shadow inform only mods about it
if (shadow) {
self.io.to('moderators').emit('msg', msg);
self.io.to('mod:'+channelName).emit('msg', msg);
//If regular mute send mute message to the channel
} else {
self.io.to(channelName).emit('msg', msg);
self.io.to('moderators').emit('msg', msg);
}
callback(null);
});
};
Chat.prototype.unmute = function(moderatorUser, username, channelName, callback) {
var self = this;
var now = new Date();
if (!lib.hasOwnProperty(self.muted, username))
return callback('USER_NOT_MUTED');
var shadow = self.muted[username].shadow;
delete self.muted[username];
var msg = {
date: now,
type: 'unmute',
message: null,
moderator: moderatorUser.username,
username: username,
shadow: shadow,
bot: false
};
//If mute shadow inform only mods about it
if (shadow) {
self.io.to('moderators').emit('msg', msg);
self.io.to('mod:'+channelName).emit('msg', msg);
//If regular mute send mute message to the channel
} else {
self.io.to(channelName).emit('msg', msg);
self.io.to('moderators').emit('msg', msg);
}
callback(null);
};
//Send an error to the chat to a client's socket
function sendErrorChat(socket, message) {
socket.emit('msg', {
date: new Date(),
type: 'error',
message: message
});
}
//Send an error event to a client's socket
function sendError(socket, description) {
console.warn('Chat client error ', description);
socket.emit('err', description);
}
function isChannelNameInvalid(channelName) {
return (typeof channelName !== 'string' || channelName.length < 1 || channelName.length > 100);
}
function isChannelNameModsOnly(channelName) {
return /^mod:/.test(channelName);
}
module.exports = Chat;
Well, I may be wrong, but I feel like that's not a piece of code you wrote, so you lack the deep knowledge of what's going on behind the hood. I'd suggest you to start something 100% from scratch without copying from tutorials to build a more solid knowledge of the tech you're using, but you're free to follow any path you prefer. Anyway, the error is clearly given from the method :
function isChannelNameInvalid(channelName) {
return (typeof channelName !== 'string' || channelName.length < 1 || channelName.length > 100);
}
So I guess you should give us a bit more insight on the channel name you used.
Related
How do I pass socket.io room name from one client to another?
I'm using socket.io v4 with NodeJS (Express). So, the situation that I have is that I have a chat window for client and the client can enter their email and message. Now, I want to create a room based on that email and have another client join that room. My current implementation doesn't work. It creates the room but the other client is unable to join it. Server Side Code: io.of(/^\/dynamic-[a-zA-Z0-9]+$/).on("connection", (socket) => { let email; const namespace = socket.nsp.name; let namespaceToCheck = namespace.split('-'); //console.log(namespaceToCheck[1]) User.findOne({apiKey: namespaceToCheck[1]}) .then((doc)=> { if(namespaceToCheck[1] == doc.apiKey) { socket.once("pass-email", (data) => { io.of(namespace).emit("pass-email", data); email = data; }) console.log("Valid Connection"); socket.on("chat-message", (msg) => { socket.join(email, function(){ //console.log(`Socket now in ${socket.rooms}`); }); //console.log(msg); console.log(socket.rooms); Message.findOne({namespace: namespace}) .then((doc) => { // console.log(doc); doc.messages.push(msg); doc.save().then((saved) => { return Promise.resolve(saved) }); }) // console.log(socket.handshake); //io.of(namespace).sockets.in(data).emit("chat-message", msg); console.log(email); io.of(namespace).to(email).emit("chat-message", msg); }) } }) .catch((err)=> { console.log(err); }) }); Client Socket Code (from which I'm passing the email) var chatSocket = io("http://localhost:3000/dynamic-8171d2a713d65c5edf81e45af4d14558a2c62275df05c73ca198a94d422e5948"); var chatBtn = document.querySelector('.chat-btn'); var input = document.querySelector('.chat-input'); var messages = document.querySelector(".messages"); var emailInputTag = document.querySelector(".email-input"); input.addEventListener("keypress", function(event) { if (event.key === "Enter") { event.preventDefault(); if (input.value && emailInputTag.value) { chatSocket.emit('create-room', emailInputTag.value); //chatSocket.join(emailInputTag.value) chatSocket.emit('chat-message', emailInputTag.value + ':' + input.value); input.value = ''; } } }); chatBtn.addEventListener('click', function(e) { e.preventDefault(); if (input.value && emailInputTag.value) { chatSocket.emit('chat-message', emailInputTag.value + ':' + input.value); input.value = ''; } }); chatSocket.on('chat-message', function(msg) { var item = document.createElement('div'); item.classList.add('msg'); item.textContent = msg; messages.appendChild(item); window.scrollTo(0, document.body.scrollHeight); }); This is the rooms that this socket is in: Client chat socket code (from which I want to receive room event and join the received room) var chatSocket = io(`http://localhost:3000/dynamic-${ApiKey}`); chatSocket.on("connect", function () { console.log("Connected-test-succeeded"); // Connected, let's sign-up for to receive messages for this room }); chatSocket.on("pass-email", (val) => { console.log(val); console.log("Listening"); }); var chatBtn = document.querySelector(".chat-btn"); var input = document.querySelector(".chat-input"); var messages = document.querySelector(".messages"); input.addEventListener("keypress", function (event) { if (event.key === "Enter") { event.preventDefault(); if (input.value) { chatSocket.emit(); chatSocket.emit( "chat-message", "Owner" + ":" + input.value ); input.value = ""; } } }); chatBtn.addEventListener("click", function (e) { e.preventDefault(); if (input.value) { chatSocket.emit( "chat-message", "Owner" + ":" + input.value ); input.value = ""; } }); chatSocket.on("chat-message", function (msg) { console.log("Message received: " + msg); var item = document.createElement("div"); item.classList.add("msg"); item.textContent = msg; messages.appendChild(item); window.scrollTo(0, document.body.scrollHeight); }); P.S: I know that the code is a bit messy but what I'm trying to do here is making a tawk.to clone so different namespace for each website url and the rooms are different in the said namespace for different users.
Microsoft bot framework save separately conversations or sessions
I got a Microsoft bot framework chatbot deployed on Azure and I´m using Tedious to save my conversations, thing is, bot it's being used on a web and many persons can open it to interact simultaneosly, but when I save a conversation from an user, it saves all the other interactions that have been made by other users at the same time, I need that each user has it's own conversation saved separately even if they are interacting with the chatbot at the same time... Here's my code, maybe I'm missing something: Bot.js //SQL Connection var Connection = require('tedious').Connection; var config = { server: 'myserver', authentication: { type: 'default', options: { userName: 'myuser', password: 'mypass' } }, options: { encrypt: true, database: 'mydatabase' } }; const connection = new Connection(config); connection.on('connect', function(err) { console.log("Connected"); }); var Request = require('tedious').Request var TYPES = require('tedious').TYPES; // Function to save the conversation and bot ids function executeConversationStatement(bot, cid, ulg ) { request = new Request("INSERT INTO table (bot_id, conversationID, conversation_date, userlogged) VALUES (#bot, #cid, CURRENT_TIMESTAMP, #ulg); SELECT ##IDENTITY AS ID",function(err) { if (err) { console.log(err);} }); request.addParameter('bot', TYPES.Int, bot); request.addParameter('cid', TYPES.NVarChar, cid); request.addParameter('ulg', TYPES.NVarChar, ulg); request.on('row', function(columns) { insertedcid = columns[0].value; // This is the id I pass later columns.forEach(function(column) { if (column.value === null) { console.log('NULL'); } else { console.log("Conversation id of inserted item is " + column.value); } }); }); connection.execSql(request); } // Here on members added I save the conversation id generated by the framework class BOT extends ActivityHandler { constructor(conversationState,userState,telemetryClient) { super(); this.conversationState = conversationState; this.userState = userState; this.dialogState = conversationState.createProperty("dialogState"); this.previousIntent = this.conversationState.createProperty("previousIntent"); this.conversationData = this.conversationState.createProperty('conservationData'); const qnaMaker = new QnAMaker({ knowledgeBaseId: process.env.QnAKnowledgebaseId, endpointKey: process.env.QnAEndpointKey, host: process.env.QnAEndpointHostName }); this.qnaMaker = qnaMaker; this.onMessage(async (context, next) => { await this.dispatchToIntentAsync(context); await next(); }); this.onDialog(async (context, next) => { await this.conversationState.saveChanges(context, false); await this.userState.saveChanges(context, false); await next(); }); this.onMembersAdded(async (context, next) => { const { channelId, membersAdded } = context.activity; actid = context._activity.id; if (channelId === 'directline' || channelId === 'webchat') { for (let member of membersAdded) { if (member.id === context.activity.recipient.id) { await context.sendActivity("Hi, I´m a chatbot to guide You"); try{ var saveqna = new executeConversationStatement(context._activity.id , 'Invitado'); } catch{ console.log('Not saved'); } } } } await next(); }); } //Finally, here I save the interaction: async dispatchToIntentAsync(context) { var result = await this.qnaMaker.getAnswers(context); // Statement to save interaction with the insertedcid obtained above var saveqnaint = new executeInteractionStatement(insertedcid, context._activity.text, result); } No matter if I use thet generated Id or the databse pk, I always keep the same identifier when multiple users are chatting, how can I got a separately Id for each session ?
SNS publish and Firebase Save Data does nothing in AWS Node.JS Lambda
I have been trying to use Cloud Messaging with my Lambda Function to send push notifications. At first I tried to use SNS linked to Firebase. But calling SNS.publish does nothing... no errors, no timeouts just seems to ignore the call. Here is a snippet of where it goes wrong: const intentName = event.request.intent.name; // Dispatch to your skill's intent handlers if (intentName === 'Temperature') { getPatientTemperature(intent, context, function (internalcontext, speechOutput) { //sns //var outmessage = {Display: speechOutput}; var sns = new AWS.SNS({region:'us-east-1'}); //console.log(sns); console.log('sending push'); sns.publish({ Message: speechOutput, TopicArn: "arn:aws:sns:us-east-1:*************:MedicalAssistantDisplayUpdates", Subject: "TestSNS" }, function(err, data) { //context.callbackWaitsForEmptyEventLoop = false; console.log("SNS here 2"); if (err) { console.log(err.stack); return; } console.log('push sent'); console.log(data); console.log("SNS here 3"); }); context.succeed( buildResponse({}, buildSpeechletResponse("Sent",speechOutput, "no text", true))); console.log("That's all folks"); }); } else { throw new Error('Invalid intent'); } It's full code: /* eslint-disable func-names */ /* eslint-disable no-console */ //const Alexa = require('ask-sdk-core'); var mysql = require('mysql'); var AWS = require("aws-sdk"); var connection = mysql.createConnection({ host: "********************", port: "****", user: "*******", password: "*****", database: "**************" }); //========================================================================================================================================= //TODO: The items below this comment need your attention. //========================================================================================================================================= const SKILL_NAME = 'Medical Assistant'; const GET_TEMPERATURE_MESSAGE = '\'s temperature is '; const HELP_MESSAGE = 'You can say tell me the latest tempearture of patient patient ID, or, you can say exit... What can I help you with?'; const HELP_REPROMPT = 'What can I help you with?'; const FALLBACK_MESSAGE = 'The Medical Assistant can\'t help you with that. It can help you retrieve a patient\'s tempearture. What can I help you with?'; const FALLBACK_REPROMPT = 'What can I help you with?'; const STOP_MESSAGE = 'Goodbye!'; // --------------- Helpers that build all of the responses ----------------------- function buildSpeechletResponse(title, output, repromptText, shouldEndSession) { return { outputSpeech: { type: 'PlainText', text: output, }, card: { type: 'Simple', title: `${title}`, content: `${output}`, }, reprompt: { outputSpeech: { type: 'PlainText', text: repromptText, }, }, shouldEndSession, }; } function buildResponse(sessionAttributes, speechletResponse) { return { version: '1.0', sessionAttributes, response: speechletResponse, }; } function getPatientTemperature(intent, context, callback) { const cardTitle = intent.name; const PatientID = intent.slots.PatientID.value; console.log(PatientID); let repromptText = ''; let sessionAttributes = {}; const shouldEndSession = false; let speechOutput = ''; console.log('Then run MySQL code:'); //connection.connect(function(err) { console.log('Inside connection.connect() callback'); //context.callbackWaitsForEmptyEventLoop = false; //if (!err) { console.log("Database is connected ... "); connection.query("SELECT Temperature, Patient_Name FROM (SELECT * FROM (SELECT c.Temperature, p.Patient_Name, c.Recorded_Time FROM ConsultationRecords c, Patients p WHERE (c.Patient_ID = p.Patient_ID) AND c.Patient_ID = '"+ PatientID +"' AND c.Temperature IS NOT NULL)AS Alias ORDER BY Recorded_Time DESC LIMIT 1) AS RequiredTemp", function(err, result) { //connection.end(); console.log("Inside connection.query() callback") if (!err) { console.log("Query Successful! Ending Connection."); //connection.end(); if (result.length > 0) { if(result[0].Temperature == 'null'){ } else{ speechOutput = result[0].Patient_Name+"'s temperature is "+result[0].Temperature; console.log("Returning Response"); } } else{ speechOutput = "Patient ID not found in records"; console.log("Returning invalid ID Response"); } callback(context, speechOutput); } else { console.log("Query error!"); } }); // } else { // console.log("Error connecting database ..." + err.message); // connection.end(); // } console.log("here end"); // }); } function getWelcomeResponse(context) { // If we wanted to initialize the session to have some attributes we could add those here. const sessionAttributes = {}; const cardTitle = 'Welcome'; const speechOutput = 'Welcome to Medical Assistant. ' + 'You can ask for Patient information like Temperature'; // If the user either does not reply to the welcome message or says something that is not // understood, they will be prompted again with this text. const repromptText = 'For example, say: what is the latest temparature of patient 1.'; const shouldEndSession = false; console.log(`Send Welcome Response`); context.succeed(buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession)); } exports.handler = (event, context) => { try { if (event.session.new) { // New Session console.log("NEW SESSION"); } // Fix for hardcoded context from simulator //if(event.context && event.context.System.application.applicationId == 'applicationId'){ // event.context.System.application.applicationId = event.session.application.applicationId; //} switch (event.request.type) { case "LaunchRequest": console.log(`Launch Request`); getWelcomeResponse(context); console.log(`End Launch`); break; case "IntentRequest": // Intent Request console.log(`Intent Request`); const intent = event.request.intent; const intentName = event.request.intent.name; // Dispatch to your skill's intent handlers if (intentName === 'Temperature') { getPatientTemperature(intent, context, function (internalcontext, speechOutput) { //sns //var outmessage = {Display: speechOutput}; var sns = new AWS.SNS({region:'us-east-1'}); //console.log(sns); console.log('sending push'); sns.publish({ Message: speechOutput, TopicArn: "arn:aws:sns:us-east-1:**********:MedicalAssistantDisplayUpdates", Subject: "TestSNS" }, function(err, data) { //context.callbackWaitsForEmptyEventLoop = false; console.log("SNS here 2"); if (err) { console.log(err.stack); return; } console.log('push sent'); console.log(data); console.log("SNS here 3"); }); context.succeed( buildResponse({}, buildSpeechletResponse("Sent",speechOutput, "no text", true))); console.log("That's all folks"); }); } else { throw new Error('Invalid intent'); } break; case "SessionEndedRequest": // Session Ended Request console.log(`SESSION ENDED REQUEST`); break; default: context.fail(`INVALID REQUEST TYPE: ${event.request.type}`); } } catch (error) { context.fail(`Exceptiodn: ${error}`) } }; After console.log('sending push'); it correctly runs context.succeed and the final console.log. For my second attempt I tried to use the Firebase Admin SDK to update the firebase database (figuring I can store my messages there and then trigger a push notification from firebase when an insertion is made). I created a whole new Lambda function to test that and again.. just seems to ignore usersRef.set call. Here is the full code for that function: var admin = require("firebase-admin"); var serviceAccount = require("medicalassistantviewer-firebase-adminsdk-7xw02-266915e453.json"); admin.initializeApp({ credential: admin.credential.cert(serviceAccount), databaseURL: "https://****************.firebaseio.com" }); // As an admin, the app has access to read and write all data, regardless of Security Rules var db = admin.database(); var ref = db.ref(); var usersRef = ref.child("Messages"); exports.handler = (event, context) => { console.log("Let's start"); context.succeed(usersRef.set({ message2: { Message: "testing again", Token: "200" }, message3: { Message: "and again", Token: "300" } }, function(err, data) { //context.callbackWaitsForEmptyEventLoop = false; console.log("messages not sent"); if (err) { console.log(err.stack); return; } console.log('messages sent'); console.log(data); console.log("here"); })); };
Underscore _.contains method always failed inside mongoose promise query
Hi im using mongoose query inside socket.io event, so far so good. I want to check if a user is a member to a private room then fetch messages. So i use underscore method _.contains() but is always return false. I don't know what wrong with the code cuz logging both list and checked item it should return true socket.on('add user', function (data) { var username = data.username; var userId = data.userId; var currentroom = data.room ? data.room : '559c02cfd2ad52cc276b7491'; // we store the username in the socket session for this client socket.username = username; socket.userid = userId; // add the client's username to the global list usernames[username] = username; ++numUsers; socket.emit('login', { numUsers: numUsers }); var room = new roomModel(); return room.getRoomParticipants(currentroom) .then(function(res) { console.log('checking room'); console.log(res); if (!res) { throw new Error('Couldn\'t get room participants!'); } res = res[0]; var participants = res.participants; return participants; }) .then(function(participants) { if (!_.contains(participants, socket.userid)) { console.log('have failed'); return null; } _.each(participants, function(item) { var user = new userModel(); user.getById(item) .then(function(res) { if (res) { rommates[res._id] = res; } }) }); return roommates; }) .then(function(participants) { var message = new messageModel(); message.roomMessages(currentroom, msgLimit) .then(function(res) { _.each(res, function(item) { var data = {}; var user = rommates[res._id]; data.username = user.username; data.message = item.msg; data.time = item.created_at; socket.emit('new message', data); }); }); }) .then(null, function(err) { logger.debug(err); }); });
Solved it by replacing if (!_.contains(participants, socket.userid)) { return null; } with var participants = _.object(res.participants); var allowed = _.find(res.participants, function(item) { return item == socket.userid; }); if (!allowed) { throw new Error('User ' + socket.userid + ' is not allowed to room ' + currentroom); }
How to create online users list using webrtc and nodejs on the server end
I am using webrtc to make a audio, video and chat application where I need keep all the users in a user list in the serverside. Need help how to get this done. Also, how can I remove users from the list when they logout from the system. Need help to implement this. webRTC.rtc.on('connect', function(rtc) { //Client connected }); webRTC.rtc.on('send answer', function(rtc) { //answer sent }); webRTC.rtc.on('disconnect', function(rtc) { //Client disconnect //console.log(webRTC); }); webRTC.rtc.on('chat_msg', function(data, socket) { var roomList = webRTC.rtc.rooms[data.room] || []; for (var i = 0; i < roomList.length; i++) { var socketId = roomList[i]; if (socketId !== socket.id) { var soc = webRTC.rtc.getSocket(socketId); if (soc) { soc.send(JSON.stringify({ "eventName": "receive_chat_msg", "data": { "messages": data.messages, "id": data.id, "from": data.from, "status": data.status, "email": data.email } }), function(error) { if (error) { console.log(error); } }); } } } });
As I was using webrtc.io module, so below are the methods that helped me to create the userlist and maintain the presence. webRTC.rtc.on('join_room', function(data, socket) { // Will get info who joined along with his socket id } And webRTC.rtc.on('room_leave', function(room, socketid) { // Will get info who left the room }
Node.js code: var users = {}; io.sockets.on('connection', function (socket) { socket.emit('connect', true); socket.on('message', function (data) { socket.broadcast.emit('message', data); }); socket.on('new-user', function (username) { users[username] = username; }); socket.on('check-presence', function (username) { var isUserPresent = !! users[username]; socket.emit('presence', isUserPresent); }); socket.on('remove-user', function (username) { var user = users[username]; if (user) delete users[username]; }); }); This may also work (node.js): var users = {}; io.sockets.on('connection', function (socket) { var UserName; socket.emit('connect', true); socket.on('message', function (data) { socket.broadcast.emit('message', data); }); socket.on('new-user', function (username) { users[username] = username; UserName = username; }); socket.on('check-presence', function (username) { var isUserPresent = !! users[username]; socket.emit('presence', isUserPresent); }); // removing user on "disconnect" socket.on('disconnect', function () { var user = users[UserName]; if (user) delete users[UserName]; }); }); For 1st case; client-side code: var socket = io.connect(); socket.on('connect', function () { socket.emit('new-user', 'username'); }); function removeUser() { socket.emit('remove-user', 'username'); } window.onbeforeunload = function () { removeUser(); }; // if someone pressed "F5" key to refresh the page window.onkeyup = function (e) { if (e.keyCode == 116) removeUser(); }; // if someone leaves via <a href> var anchors = document.querySelectorAll('a'), length = anchors.length; for (var i = 0; i < length; i++) { var a = anchors[i]; if (a.href.indexOf('#') !== 0 && a.getAttribute('target') != '_blank') a.onclick = function () { removeUser(); }; } For 2nd case; client side code: var socket = io.connect(); socket.on('connect', function () { socket.emit('new-user', 'username'); }); You can check presence too: socket.on('presence', isUserPresent) { // boolean: user is present or not }); socket.emit('check-presence', 'username');