Repetition Problem With Telegram Bot In Node - javascript

I am trying to make a telegram bot with node js. What my bot do is making phone calls based on what the telegram user input. My bot works fine at the first execution but when I try to do multiple task it get stuck in a weird loop an bassicaly send the message one more time each time I give input.
Its like the code never break the switch and always listen for a number input.
Here is my code in node:
require("dotenv").config();
const axios = require("axios");
const express = require("express");
const port = 5000;
const app = express();
const Voice = require("#signalwire/realtime-api").Voice;
const { TOKEN, SERVER_URL } = process.env;
const URI = `/webhook/${TOKEN}`;
const TelegramBot = require("node-telegram-bot-api");
const { reset, restart } = require("nodemon");
const nodemon = require("nodemon");
var chatId;
// replace the value below with the Telegram token you receive from #BotFather
const token = "<token>";
// Create a bot that uses 'polling' to fetch new updates
const bot = new TelegramBot(token, { polling: true });
bot.on("message", (msg) => {
chatId = msg.chat.id;
if (msg.text == "/call") {
chooseBank();
}
if (msg.text == "/restart") {
recover();
}
});
//GIVE OPTION FOR THE CLIENT
function chooseBank() {
bot.sendMessage(
chatId,
"CHOOSE THE BANK: \n\n1 RBC\n2 CIBC\n3 SCOTIA\n4 BMO\n5 NATIONAL\n6 TD\n7 PC-FINANCIAL\n8 DESJARDINS"
);
bot.on("message", (msg) => {
switch (msg.text) {
case "1":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "2":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "3":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "4":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "5":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "6":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "7":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
break;
case "8":
bot.sendMessage(
chatId,
"ENTER THE CLIENTS NUMBER:\n\nEX: (+15142220000)"
);
}
});
}
function recover(){
chooseBank()
}
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
your text`
Here Are the example of running my bot in telegram:
first execution works fine
repeat itself and add one more every time

on method adds your code as listener as mentioned in doc.
You need to register it only once. Move it outside of chooseBank().

Related

Multipeer connection onicecandidate event won't fire

I'm having problems with the logic to build behind the webRTC multi peer connections handling.
Basically I'm trying to make a Room full of people in a videoconference call.
I'm using the basic WebSocket library provided by js, and React for the frontend and Java (spring boot) for the backend.
As of my understanding right now this is what I managed to write down (filtered based on what I "think" is relevant)
This is my web socket init method (adding listeners)
let webSocketConnection = new WebSocket(webSocketUrl);
webSocketConnection.onmessage = (msg) => {
const message = JSON.parse(msg.data);
switch (message.type) {
case "offer":
handleOfferMessage(message);
break;
case "text":
handleReceivedTextMessage(message);
break;
case "answer":
handleAnswerMessage(message);
break;
case "ice":
handleNewICECandidateMessage(message);
break;
case "join":
initFirstUserMedia(message);
break;
case "room":
setRoomID(message.data);
break;
case "peer-init":
handlePeerConnection(message);
break;
default:
console.error("Wrong type message received from server");
}
Plus of course the 'on error', 'on close' and 'on open' listeners
This is the method handling the incoming offer
const handleOfferMessage = (message) => {
console.log("Accepting Offer Message");
console.log(message);
let desc = new RTCSessionDescription(message.sdp);
let newPeerConnection = new RTCPeerConnection(peerConnectionConfig);
newPeerConnection.onicecandidate = handleICECandidateEvent;
newPeerConnection.ontrack = handleTrackEvent;
if (desc != null && message.sdp != null) {
console.log("RTC Signalling state: " + newPeerConnection.signalingState);
newPeerConnection
.setRemoteDescription(desc)
.then(function () {
console.log("Set up local media stream");
return navigator.mediaDevices.getUserMedia(mediaConstraints);
})
.then(function (stream) {
console.log("-- Local video stream obtained");
localStream = stream;
try {
videoSelf.current.srcObject = localStream;
} catch (error) {
videoSelf.current.src = window.URL.createObjectURL(stream);
}
console.log("-- Adding stream to the RTCPeerConnection");
localStream
.getTracks()
.forEach((track) => newPeerConnection.addTrack(track, localStream));
})
.then(function () {
console.log("-- Creating answer");
return newPeerConnection.createAnswer();
})
.then(function (answer) {
console.log("-- Setting local description after creating answer");
return newPeerConnection.setLocalDescription(answer);
})
.then(function () {
console.log("Sending answer packet back to other peer");
webSocketConnection.send(
JSON.stringify({
from: user,
type: "answer",
sdp: newPeerConnection.localDescription,
destination: message.from
})
);
})
.catch(handleErrorMessage);
}
peerConnections[message.from.id] = newPeerConnection;
console.log("Peer connections updated now ", peerConnections);
};
SN: I got the peer connections defined as an array of RTCPeerConnection indexed by the user unique id
let [peerConnections, setPeerConnections] = useState([]);
And here comes the part that I think I got wrong and on which I'm having trouble understanding
const handleAnswerMessage = (message) => {
console.log("The peer has accepted request");
let currentPeerConnection = peerConnections[message.from.id];
if (currentPeerConnection) {
currentPeerConnection.setRemoteDescription(message.sdp).catch(handleErrorMessage);
peerConnections[message.from.id] = currentPeerConnection;
} else {
console.error("No user was found with id ", message.from.id);
}
console.log("Peer connections updated now ", peerConnections);
};
currentPeerConnection.setRemoteDescription(message.sdp).catch(handleErrorMessage);
peerConnections[message.from.id] = currentPeerConnection;
console.log("Peer connections updated now ", peerConnections);
};
The answer and the offer work perfectly, I can clearly see the two peers communicating one by sending the offer and the other one responding with an answer. The only problem is that after that nothing happens, but from what I read about webRTC it should actually start gathering ice candidates as soon as a local description has been set.
I can understand why the peer handling the answer (caller) actually does not fire up iceecandidate and that's probably because I do not set a local description on the answer message (I don't know if it would be correct). the callee on the other hand, handling the offer message should actually start gathering iceecandidates tho, I'm setting the local description on there.
This some additional code that might help
function getMedia(constraints, peerCnnct, initiator) {
if (localStream) {
localStream.getTracks().forEach((track) => {
track.stop();
});
}
navigator.mediaDevices
.getUserMedia(constraints)
.then(stream => {
return getLocalMediaStream(stream, peerCnnct, initiator);
})
.catch(handleGetUserMediaError);
}
function getLocalMediaStream(mediaStream, peerConnection, initiator) {
localStream = mediaStream;
const video = videoSelf.current;
if (video) {
video.srcObject = mediaStream;
video.play();
}
//localVideo.srcObject = mediaStream;
console.log("Adding stream tracks to the peer connection: ", peerConnection);
if (!initiator) {
localStream
.getTracks()
.forEach((track) => peerConnection.addTrack(track, localStream));
}
}
const handlePeerConnection = (message) => {
console.info("Creating new peer connection for user ", message.from);
let newPeerConnection = new RTCPeerConnection(peerConnectionConfig);
// event handlers for the ICE negotiation process
newPeerConnection.ontrack = handleTrackEvent;
newPeerConnection.onicecandidate = handleICECandidateEvent;
getMedia(mediaConstraints, newPeerConnection, false);
newPeerConnection.onnegotiationneeded = handleNegotiationNeededEvent(newPeerConnection, webSocketConnection, user, message.from);
peerConnections[message.from.id] = newPeerConnection;
};
Here you can clearly see my desperate attempt in finding a solution and creating a peer connection just for the sake of sending the offer.
I cannot index a peer connection that has no end user because I would need his id, that I receive only after I received an answer from him when I first join the room.
(The backend should work but either way putting a debugger on the ice candidate handler method I could clearly see that it's just not fired)
What am I doing wrong?
EDIT: Now the WebSocketMessage Server side has also a destination user. This way the the new peer that connects to the room receives as many peer-init messages as the already connected peers are. Then proceeds to make one offer per peer setting it as a destination.
The problem still persists though
This feels actually wierd but I fixed it calling the getUserMedia() (which means calling the addTrack before adding the onicecandidate event definition to the peerConnection.
This at least fixed my problem

I am trying to add an additional 'Bye' command in the bot in the same way as 'hello' command in botactivityHandler.js I am getting error message

Getting Error- SyntaxError: Unexpected identifier
****const {
TurnContext,
MessageFactory,
TeamsActivityHandler,
CardFactory,
ActionTypes
} = require('botbuilder');
class BotActivityHandler extends TeamsActivityHandler {
constructor() {
super();
/* Teams bots are Microsoft Bot Framework bots.
If a bot receives a message activity, the turn handler sees that incoming activity
and sends it to the onMessage activity handler.
Learn more: https://aka.ms/teams-bot-basics.
NOTE: Ensure the bot endpoint that services incoming conversational bot queries is
registered with Bot Framework.
Learn more: https://aka.ms/teams-register-bot.
*/
// Registers an activity event handler for the message event, emitted for every incoming message activity.
this.onMessage(async (context, next) => {
TurnContext.removeRecipientMention(context.activity);
switch (context.activity.text.trim()) {
case 'Hello':
await this.mentionActivityAsync(context);
break;
case 'Bye':
await this.mentionActivityAsync1(context);
break;
default:
// By default for unknown activity sent by user show
// a card with the available actions.
const value = { count: 0 };
const card = CardFactory.heroCard(
'Lets talk...',
null,
[{
type: ActionTypes.MessageBack,
title: 'Say Hello',
value: value,
text: 'Hello'
}]);
await context.sendActivity({ attachments: [card] });
break;
}
await next();
});
}
/**
* Say hello and # mention the current user.
*/
async mentionActivityAsync(context) {
const TextEncoder = require('html-entities').XmlEntities;
const mention = {
mentioned: context.activity.from,
text: `<at>${ new TextEncoder().encode(context.activity.from.name) }</at>`,
type: 'mention'
};
const replyActivity = MessageFactory.text(`Hi ${ mention.text }`);
replyActivity.entities = [mention];
await context.sendActivity(replyActivity);
}
}
async mentionActivityAsync1(context) {
const TextEncoder = require('html-entities').XmlEntities;
const mention = {
mentioned: context.activity.from,
text: `<at>${ new TextEncoder().encode(context.activity.from.name) }</at>`,
type: 'mention'
};
const replyActivity = MessageFactory.text(`Bye ${ mention.text }`);
replyActivity.entities = [mention];
await context.sendActivity(replyActivity);
}
module.exports.BotActivityHandler = BotActivityHandler;****

TypeError [ERR_INVALID_ARG_TYPE]: The "file" argument must be of type string. Received type object

I followed CodeLyon's tutorial on YouTube to make a discord music bot because I have no idea what I'm doing, and I don't know what I've done wrong or what to do. The bot joins the voice channel I'm in, but it doesn't play anything, and this comes up in the terminal:
var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}Module["arguments"]=[];Module["thisProgram"]="./this.program";Module["quit"]=function(status,toThrow){throw toThrow};Module["preRun"]=[];Module["postRun"]=[];var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_HAS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_HAS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_NODE=ENVIRONMENT_HAS_NODE&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Mod
abort(TypeError [ERR_INVALID_ARG_TYPE]: The "file" argument must be of type string. Received type object). Build with -s ASSERTIONS=1 for more info.
const Discord = require('discord.js');
const bot = new Discord.Client();
const ytdl = require("ytdl-core");
const token = '';
const PREFIX = '!';
var servers = {};
bot.on('ready', () =>{
console.log('This bot is online!')
})
bot.on('message', message=>{
let args = message.content.substring(PREFIX.length).split(" ");
switch(args[0]){
case 'play':
function play(connection, message){
var server = servers[message.guild.id];
server.dispatcher = connection.playStream(ytdl(server.queue[0], {filter: "audioonly"}));
server.queue.shift();
server.dispatcher.on("end", function(){
if(server.queue[0]){
play(connection, message);
}else {
connection.disconnect();
}
});
}
if(!args[1]){
message.channel.send("You need to enter a link.");
return;
}
if(!message.member.voiceChannel){
message.channel.send("You have to be in a voice channel.");
return;
}
if(!servers[message.guild.id]) servers[message.guild.id] = {
queue: []
}
var server = servers[message.guild.id];
server.queue.push(args[1]);
if(!message.guild.voiceConnection) message.member.voiceChannel.join().then(function(connection){
play(connection, message);
})
break;
}
});
bot.login(token);
(I've removed the value for token)
https://github.com/discordjs/discord.js/issues/3375
If you are using ffmpeg-binaries, uninstall it and try ffmpeg-static or a regular FFmpeg installation instead.
Otherwise I suggest to open an issue at the prism-media repository.

Send notifications conditionally using Firebase cloud functions?

I am writing an android application where I need to send a notification based on some condition.
For example, when notiType = home then send other message in notification. If notiType = inBetween then send another message
I have written the cloud function for this but getting an error while deploying.
Here is the cloud function :
'use strict';
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
/* Listens for new messages added to /messages/:pushId and sends a notification to users */
exports.pushNotification = functions.database.ref('/Notifications/{user_id}/{notification_id}').onWrite(event => {
console.log('Push notification event triggered');
/* Grab the current value of what was written to the Realtime Database
*/
const userId = event.params.user_id;
const notificationId = event.params.notification_id;
const deviceToken = admin.database().ref(`Notifications/${userId}/${notificationId}/deviceToken`).once('value');
const childName = admin.database().ref(`Notifications/${userId}/${notificationId}/childName`).once('value');
const notificationType = admin.database().ref(`Notifications/${userId}/${notificationId}/type`).once('value');
return Promise.all([deviceToken, childName, notificationType]).then(result => {
const token = result[0].val();
const name = result[1].val();
const type = result[2].val();
/* Create a notification and data payload. They contain the notification information, and message to be sent respectively */
const payload;
switch (type) {
case "home":
payload = {
notification: {
title: 'App Name',
body: `${name} is reached at home`,
sound: "default"
}
};
break;
case "between":
payload = {
notification: {
title: 'App Name',
body: `${name} stuck on the way for some reason`,
sound: "default"
}
};
break;
case "school":
payload = {
notification: {
title: 'App Name',
body: `${name} reached at school`,
sound: "default"
}
};
break;
};
return admin.messaging().sendToDevice(token, payload).then(response => {
return null;
});
});
});
Getting this error :
Please correct me where I am going wrong. Using Firebase -tools version 5.0.1
JavaScript is telling you this line is invalid:
const payload;
You can't declare a const variable without also giving it a value immediately. Since you are conditionally giving it a value later, perhaps you should use let payload; instead.

Discord.js bot replies itself when awaiting messages

After the bot sends the message message.channel.send('Fortnite added!'); or another roles, the bot replies to itself with the default message until the 5 seconds ran out.
const awaiting = await message.channel.send('Awaiting your role(s)...');
const roles = await message.channel.awaitMessages(msg => {
console.log(msg.content);
switch(msg.content) {
case 'fortnite':
message.member.addRole('ROLEID');
message.channel.send('**Fortnite** added!')
break;
case 'pubg':
message.member.addRole('ROLEID');
message.channel.send('**PUBG** added!')
break;
case 'hots':
message.member.addRole('ROLEID');
message.channel.send('**HOTS** added!')
break;
default:
message.channel.send('This is not a valid role!');
return;
};
}, {time: 5000});
message.channel.send('Await completed!')
Node that I'm storing the command in a different file
What I tried so far:
if (message.author.bot) return;
in my bot.js and the js file where this code comes from:
switch(msg.content.toLowerCase()) {}
trying to make it only work in lowercase.

Categories

Resources