How can I make my bot receives responses without using force_reply? something like botFather does?
Let say I've sent message to user like this:
bot.sendMessage(chatId, 'What is your name?', { parse_mode: 'HTML' });
Now how do I get user response?
Without the help of force_reply, you'll need to write some custom logic. I've implemented this in my custom bots like so:
Send question to user bot.sendMessage() and remember the ID
Wait for a message bot.on('message')
Check if we're waiting for on a reply from this user
Reply accordingly
// Create bot
const TelegramBot = require('node-telegram-bot-api');
const bot = new TelegramBot('XXXXXXXX:AAEibBwftjTEKuYd9d2X0ACeyyzTk4DLe60', {
polling: true
});
// List of id's we're waiting for
const wait = [];
// Hardcoded chat id
const chatId = 1234567;
// Ask and add to wait list
bot.sendMessage(chatId, 'What is your name?', { parse_mode: 'HTML' });
wait.push(chatId);
// On message
bot.on('message', (msg) => {
// Check we're waiting on this user
if (wait.includes(msg.chat.id)) {
// Send reply
bot.sendMessage(chatId, 'Your name: ' + msg.text );
// Remove from wait list
wait.splice(wait.indexOf(msg.chat.id), 1);
} else {
// Normal message; notify user
bot.sendMessage(chatId, 'Hi! I\'m not expecting a reply from you! How can I help?');
}
});
Note: This is just an example! The code can be extended to include multiple checks, and possibly states to see what message the user is replying on.
Related
I am getting to know the telegram api and I am trying to filter messages from certain groups to redirect the message to a chat if I find a match in the text.
for now I just need that when they write to me from certain groups it captures the message and then I can redirect that message.
this is my current code, what am I doing wrong?
messages are not triggered
const TelegramBot = require("node-telegram-bot-api");
// replace the value below with the Telegram token you receive from #BotFather
const token = "MI_TOKEN";
const bot = new TelegramBot(token, {
polling: true,
chats: ["ID_GROUP_1", "ID_GROUP_2", "ID_GROUP_3", "ID_GROUP_4"],
});
// Listen for any kind of message. There are different kinds of
bot.on("message", (msg) => {
const chatId = msg.chat.id;
// send a message to the chat acknowledging receipt of their message
bot.sendMessage("ID_MY_CHAT_BOT", msg.text);
});
Is it possible for cloud function to listen for specific node for when a child is added and then send a notification to users located on a different node, and if that is possible how so? I am using node.js with Firebase realtime database and not Firestore.
This is my database:
I want the cloud function to listen every time a child is added on "Emergencies", and then notify all the users in the "Registered Admins"
This is the contents of the users in "Registered Admins" node, it has a child "Notification" containing the message, and I want to send that message to all the users, when a child is added on "Emergencies" node.
This is my cloud function using node.js. I've deployed it however it does not work, does not send any notification at all.
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.listen = functions.database.ref("/Emergencies")
.onWrite(async (change, context) => {
change.after.val();
context.params.pushId;
// Get the list of device notification tokens.
const getDeviceTokensPromise = admin.database()
.ref("/Registered Admins/{uid}/Token").once("value");
// The snapshot to the user's tokens.
let tokensSnapshot;
// The array containing all the user's tokens.
let tokens;
const results = await Promise.all([getDeviceTokensPromise]);
tokensSnapshot = results[0];
// Check if there are any device tokens.
if (!tokensSnapshot.hasChildren()) {
return functions.logger.log(
'There are no notification tokens to send to.'
);
}
functions.logger.log(
'There are',
tokensSnapshot.numChildren(),
'tokens to send notifications to.'
);
// Notification details.
const payload = {
notification: {
title: "New Emergency Request!",
body: "Someone needs help check Emergenie App now!",
}
};
// Listing all tokens as an array.
tokens = Object.keys(tokensSnapshot.val());
// Send notifications to all tokens.
const response = await admin.messaging().sendToDevice(tokens, payload);
// For each message check if there was an error.
const tokensToRemove = [];
response.results.forEach((result, index) => {
const error = result.error;
if (error) {
functions.logger.error(
'Failure sending notification to',
tokens[index],
error
);
// Cleanup the tokens who are not registered anymore.
if (error.code === 'messaging/invalid-registration-token' ||
error.code === 'messaging/registration-token-not-registered') {
tokensToRemove.push(tokensSnapshot.ref.child(tokens[index]).remove());
}
}
});
return Promise.all(tokensToRemove);
});
Yes, that sounds possible and is in fact quite close to what the example on notifying users when something interesting happens does.
To send a message to a specific device, you 'll need to know the token for that device. If you want to broadcast a message to multiple users, you could subscribe those users to a topic. Just keep in mind that anyone can subscribe to a topic if they know its name, so you can't use that to send messages that only a certain group of users is allowed to see.
New to JS as you can probably tell. Trying to make a discord bot that forwards its DM's to a channel on my discord.
Currently it works, sends whatever content it is sent via DM to a specific channel ID and replies "Thanks!" to the DM sender.
What code do I need to add so that it would read and send the senders "Username" and then the "Message Content" together to the DC channel?
Thank you
const { Client, Intents } = require('discord.js');
// Initializing your client
const client = new Client({
intents: [
Intents.FLAGS.GUILDS,
Intents.FLAGS.GUILD_MESSAGES,
Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Intents.FLAGS.GUILD_MESSAGE_TYPING,
Intents.FLAGS.DIRECT_MESSAGES,
Intents.FLAGS.DIRECT_MESSAGE_REACTIONS,
Intents.FLAGS.DIRECT_MESSAGE_TYPING,
],
partials: [
'CHANNEL',
]
});
client.on('message', async (message) => {
if(message.author.bot) return;
if(message.guild) return;
await client.channels.cache.get('DISCORD_CH_ID').send(message.content);
console.log(message.content);
message.author.send("Thanks")
return;
});
client.login('TOKEN');
I think this is what you're asking:
await client.channels.cache.get('DISCORD_CH_ID').send(`${message.author.username}: ${message.content}`);
Using Slackbots(https://www.npmjs.com/package/slackbots) I was hoping to build a simple message forwarding bot (i.e. when the bot receives a direct message, it shoots it into a chat room and says who it is from) but I can't seem to get it to push out user names, only user ID's. Any idea here?
var SlackBot = require('slackbots');
var bot = new SlackBot({
token: 'xoxb-',
name: 'helper'
});
bot.on('start', function() {
var params = {
icon_emoji: ':cat:'
};
bot.postMessageToChannel('helpertest', 'meow!', params);
});
bot.on('message', function(data) {
bot.postMessageToChannel('helpertest', data.text + data.user.name);
})
Im building a chat application in node.js , socket.io and mongoose. My goal is to build a one on one chat, it is similar like facebook web chat. So basically whenever I click on a user it will go to that user url and possibly chat with him/her
But the problem, that I'm facing is that I could only emit the message to the targeted user, but not to myself.
Here's the current code
Serverside
socket.on('chatTo', function(data){
User.findOne({ username: data.destinationUsername, socketId: { '$ne': null}}, function(err, foundUser) {
if (foundUser) {
io.to(foundUser.socketId).emit('incomingChat', { sender: user.username, message: data.message });
} else {
io.to(socket.id).emit('deliverError', { error: foundUser + ' is not online' });
}
});
});
Clientside
$(function() {
var socket = io();
function chatTo(message, destinationUsername) {
socket.emit('chatTo', { message: message, destinationUsername });
}
$('#sendMessage').submit(function(){
var input = $('#message').val();
var username = $('#username').val();
chatTo(input, username);
$('#message').val('');
return false;
});
socket.on('incomingChat', function(data) {
var html = data; // Messages to append to media-list
$('.media-list').append(html);
});
});
So what is happening here is that, on the clientside, User A clicks form submit , to submit the message, it will invoke chatTo function and emit the data. Just want to let you guys know, input and username are from html page. It would look something like this
input = "Hello";
username = "jackmoscovi" // user's username
then it will emit both of these data back to server, which is socket.on('chatTo') is listening to. After some MongoDB operation, if found the user then emit to that specific socket.
The result will be
The message that was emitted by batman only shows up on joker's page but not on Batman's page. I know that because I specifically emit to that socket. The real question is How do I force both of these user to be in a unique room? Should I create a new Room mongoose model? and then call socket.join('uniqueRoom')?
and then simply io.to('uniqueRoom').emit("Message?");
How would I implement this room mechanism?
I have been struggling for 2 days already, please someone end this misery :(
First create a mongoose schema like this
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var messageSchema=new Schema({
sender : {
type : String,
},
receiver : {
type : String.
},
message : {
type : String
}
})
mongoose.model('messages',messageSchema);
Then in server code
message = mongoose.model('messages')
socket.on('chatTo', function(data){ // data is json containing sender, receiver and message
User.findOne({ username: data.destinationUsername, socketId: { '$ne': null}}, function(err, foundUser) {
if (foundUser) {
io.to(foundUser.socketId).emit('incomingChat', { sender: user.username, message: data.message });
socket.emit('incomingChat', { sender: user.username, message: data.message });
var newMessage = new message({
sender : data.sender,
receiver : data.receiver,
message : data.message
})
newMessage.save(function (err, data){
if(err)
console.log(err)
})
} else {
io.to(socket.id).emit('deliverError', { error: foundUser + ' is not online' });
}
});
});
This is a little bit of a difficult one to answer because it feels like you are actually asking the wrong question. To understand how you are "supposed" to do this you really have to have solved quite a few other architectural issues first.
The first thing you need to solve is the Authentication/Authorisation problem i.e. when you connect a socket from the browser to the server how does your server know who you are and know that you're not an imposter? I don't have a best practice for this but you might want to check out the socketio-auth package which might give you a few ideas.
The second thing you need to solve is how to associate the authenticated user with the socket. The only source that I could find that has any reference to this is in the chat demo on the socket.io website.
At this point, you should have a collection of sockets in your server that have associated users. When Batman comes online you should check the database for any Chats that he is part of and have him connect to that chat room by id:
Chat.find({usernames: "Batman"}).exec().then(function(chats){
chats.forEach(function(chat){
socket.join(chat.id);
})
});
So this so far is assuming that Joker hasn't already created a chat with Batman, and hence there is not a chat in the database that connects them both.
When Joker wants to chat to batman you need to send a "connect" message down the socket that
creates a chat with both of them in it
finds both their current sockets if they are currently connected to the server and
sends a message that they have connected to each other
example:
socket.on('startChat', function(data){
//assuming that you have assocated the current user with the socket
var currentUser = socket.user;
//who the current user (Joker) wants to connect to
var connectToUser = data.connectToUser; // Batman
Chat.create({
usernames: [currentUser.username, connectToUser.username] // ["Joker", "Batman"]
}).then(function(newChat){
socket.join(newChat.id); // add current user (Joker) to that socket.io room
// this is overly simplified: assuming you have an array collectionOfConnectedSockets which
// contains all currently connected sockets
var otherUserSocket = collectionOfConnectedSockets[connectToUser.username];
//otherUserSocket now is Batman's socket - so make him join the room
otherUserSocket.join(newChat.id);
//send them both a message that a chat has been connected
io.to(newChat.id).emit('You have been connected to a new chat');
});
});
Now this brushes over a lot of the details, and each of those details depend on your application's architecture. Also my syntax may be a little off, the examples are only given as an indication of you should be trying to do and not as a direct solution to your problem.