Twitch bot with node.js - node.js

Im new to node and tried to make a simple twitch chat bot with node.js following a youtube tutorial but
everything works untill i try to use "!" command... I use the command and the bot simply doesnt respond to the command.
Here is what i have so far:
const tmi = require('tmi.js'),
{channel , username , password } = require('./settings.json');
const options = {
options: {debug: true},
connection: {
reconnct: true,
secure: true
},
identity : {
username,
password
},
channel: [channel]
};
const client = new tmi.Client(options);
client.connect().catch(console.error);
client.on('connected', () => {
client.say(channel, `${username} joined the chat`)
})
client.on('message', (channel, user, message ,self) => {
if(self) return;
if(message == '!ping') {
client.say(channel, `#${user.username}, pong`);
}
});
I cant figure it out i just want it to respond

I only played a bit with twitch bots a while ago, but the problem might be the part where you return on self:
if(self) return;
This means that if a message comes from the bot itself, it will be ignored and the function will return (and therefore stop). Meaning that if you linked the bot to the same account from which you are sending messages, those messages are ignored.
Also:
you mispelled reconnect with reconnct in the connection options
in JS I would recommend to use === instead of == because the latter attempts to convert and compare operands that are of different types (you can learn more here)
Edit: what also helps in general is to use console.log() to debug and find out where the problem is

Related

How can I send a message from bot framework sdk after a period of inactivity? In nodejs

I am using the nodejs SDK for Bot Framework to develop a chatbot. I want to send a message to the user if they do not write in 5 minutes.
I do not find an example in bot-framework documentation and, in stackoverflow there are not solutions for a started bot (I do not need it to start the conversation). Where do I need to create the code? I have an index.js and a dialog file. How can I set the timer and restart it when the user send a message?
I'm using directline.
Thanks
There are two different ways you can approach this, one for directline only using events and one for all channels using setTimeout. The directline solution requires some code on your webchat client, but the latter requires you to save the conversation reference and start a new bot adapter. Both approaches could work.
Directline Only
You need to set up your webchat client to set up the timer and send an event to your bot if no activities are sent before the timer expires. You need to create a custom store to do this. Here is an example I used in the past:
const store = window.WebChat.createStore({}, function(dispatch) { return function(next) { return function(action) {
if (action.type === 'WEB_CHAT/SEND_MESSAGE') {
// Message sent by the user
clearTimeout(interval);
} else if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY' && action.payload.activity.name !== "inactive") {
// Message sent by the bot
clearInterval(interval);
interval = setTimeout(function() {
// Notify bot the user has been inactive
dispatch.dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'inactive',
value: ''
}
});
}, 300000)
}
return next(action);
}}});
This will send an event to your bot with the name 'inactive'. Now you need to set up your bot to handle it. So in your this.onEvent handler you need to do something like this:
if (context.activity.name && context.activity.name === 'inactive') {
await context.sendActivity({
text: 'Are you still there? Is there anything else I can help you with?',
name: 'inactive'
});
}
All channels
As I'm typing this up, I'm realizing you should be able to emit the event from your bot itself and forego starting a new bot adapter instance. But I haven't tried that before, so I'm providing my existing solution. But you may wish to experiment with emitting an inactive event if the timeout is reached instead of the actions below.
That said, here is a solution you can use within your this.onMessage handler.
// Inactivity messages
// Reset the inactivity timer
clearTimeout(this.inactivityTimer);
this.inactivityTimer = setTimeout(async function(conversationReference) {
console.log('User is inactive');
try {
const adapter = new BotFrameworkAdapter({
appId: process.env.microsoftAppID,
appPassword: process.env.microsoftAppPassword
});
await adapter.continueConversation(conversationReference, async turnContext => {
await turnContext.sendActivity('Are you still there?');
});
} catch (error) {
//console.log('Bad Request. Please ensure your message contains the conversation reference and message text.');
console.log(error);
}
}, 300000, conversationData.conversationReference);
Note that you have to get and save the conversationReference if you go this route, so that you can call continueConversation if the timer expires. I typically do this in my this.onMessage handler as well just to make sure I always have a valid conversation reference. You can get it with the below code (I'm assuming you already have your conversation state and state accessor defined).
const conversationData = await this.dialogState.get(context, {});
conversationData.conversationReference = TurnContext.getConversationReference(context.activity);
Now as I mentioned in the first solution, I believe you should be able to send an inactivity event in your try block instead of initiating the bot adapter. If you try that and it works, please let me know so I can update this solution!

Telegram Bot API. How to collect images only between start and end messages?

I'm writing Telegram bot (nodejs) which will collect all images sent to it between "start" and "end" messages. I learned how to start bot.onText(/\/start/, but how to react on "end" message from user to start reacting after that?
You need to maintain state for every user who is going to send you the /start and /end command. You can persist the state in a Key/Value store (e.g. { userid: xxx, end: false }. You can then check against the database store every time a picture is sent. An example of how your code would look like is:
bot.onText(/\/start/, msg => {
//saveToDb({chat_id: msg.chat.id, completed: false});
});
bot.onText(/\/end/, msg => {
//saveToDb({chat_id: msg.chat.id, completed: true});
});
bot.on("message", msg => {
// most of this code is just for logical purposes to explain the concept
if (typeof msg.image === "object") {
//const completed = checkDb(msg.chat.id);
if (completed !== true) {
// work with the image
}
}
});
Alternatively you can look into mau its aim is to solve this issue. It works well with node-telegram-bot-api, check the examples folder to get started on how it works.

builder.Prompts.text not working after being hosted remotely

I have a simple bot that fetches news articles based on a user prompt. The entire flow works fine locally using emulator but after being deployed to a server the bot fails when it hits a builder.Prompts.text block. Below is my code and you will see a "Asking article count" prompt which is where it stops in flow.
Bot shows accepted when testing on the BOT Framework page
Bot is receiving messages via WebChat and Slack
Bot also shows 0 issues for each channel after interacting
var bot = new builder.UniversalBot(connector);
var intents = new builder.IntentDialog();
bot.dialog('/', intents);
var HHCC = require('./hhcc.js');
intents.matches(/^news/i, [
function(session) {
console.log("Intent Given!");
session.beginDialog('/news');
},
function(session, results) {
session.send('Enjoy reading!');
}
]);
bot.dialog('/news', [
function(session) {
console.log("Asking article count");
builder.Prompts.text(session, 'How many articles would you like to see?');
},
function(session, results) {
session.sendTyping();
session.conversationData.count = results.response;
HHCC.getNews(session.conversationData.count, session, function(newsArticles) {
newsArticles.forEach(function(newsCard) {
session.send(newsCard);
});
session.conversationData.news = newsArticles;
console.log(newsArticles);
session.endDialog();
});
}
]);
server.post('/api/messages', connector.listen());
Ive checked all logs and can't seem to find any clues as its failing pretty silently.
Have you attempted using builder.Prompts.number() instead of .text()? It only accepts numbers and (I'm guessing you're doing this) you won't have to parse the results.response into a number. Without provided error messages or logs it's difficult to help.
One thing you might have to look out for (if using builder.Prompts.number) is if a user provides a decimal, as the prompt will accept this input, requiring the bot to round to the nearest integer.
Also, if you've saved the results.response into your session object, you will not need to pass in session.conversationData.count as another parameter to HHCC.getNews(). You can instead access it from session in your function.

Chaining with Telegram Bot API (like TriviaBot)

I am creating a TriviaBot style bot for telegram and am using Node.js to do so. At the moment I am having trouble capturing the users response to my quiz to determine whether the user got the question right or wrong. Below is some code:
bot.onText(/\/quiz/, function (msg) {
var chatId = msg.chat.id;
var text = quizdata.one.msgtxt;
var opts = {
reply_to_message_id: msg.message_id,
reply_markup: JSON.stringify({
keyboard: quizdata.one.keyboard,
one_time_keyboard: true
})
};
bot.sendMessage(chatId, text, opts);
//NEED TO CAPTURE THE USER RESPONSE AND REPLY TO THEIR MESSAGE ACCORDINGLY
});
NOTE : Telegram would cut of any asynchronous function, you should make separated module for listening any incoming interaction with button. You could use global Array for to store small data to be able getting returned for other module you need.
Putting all of your command in the index js not good idea tho.
if you want to listen the from keyboard callback_data. Just create a new line to listen any incoming clicked button.
bot.on("callback_query", (msg) => {
if (msg.data === "your_keyboard_callback_data") {
// do whatever you want
}
})
For more clearance node telegram api
Sorry if my answer is too late for this but hope mine can help other people 🙂

Connecting to Conference over node-xmpp on Node.js

How to connect to a Jabber conference? Send and receive messages. Get a list of online users.
Did some testing from localhost using prosody.im. I had two clients:
alfred1: Just normally XMPP client
alfred2: My bot
I created MUC alfred#conference.localhost.
When I first connect to channel from XMPP client(alfred1) and next run the bot, I receive test message from bot(alfred2). And I will also receive chat message from alfred1 in console when I sent message from XMPP-client.
var xmpp = require('node-xmpp'),
sys = require('sys'),
jid = 'alfred2#localhost',
password = '1234',
room_jid = 'alfred#conference.localhost',
room_nick = 'alfred2',
conn = new xmpp.Client({
jid : jid,
password : password,
});
conn.on('online', function () {
console.log('online');
//var elm2 = new xmpp.Element('presence', { from: jid, to: 'alfred#conference.localhost'}).c('x', {'xmlns': 'http://jabber.org/protocol/muc' }).up();
conn.send(new xmpp.Element('presence', { to: room_jid +'/' + room_nick }).
c('x', { xmlns: 'http://jabber.org/protocol/muc' })
);
conn.send(new xmpp.Element('message', { to: room_jid, type: 'groupchat' }).
c('body').t('test')
);
});
conn.on('stanza', function(stanza) {
sys.puts(stanza);
});
conn.on('error', function(e) {
sys.puts(e);
});
Maybe later I try to improve code a bit, but I guess this gets you going...
From jabber.org:
but as always feel free to join the
jabber#conference.jabber.org chatroom
via XMPP or HTTP if you have questions
or comments.
You mean connecting to jabber#conference.jabber.org?
I believe that should look up MUC specifications for that. I think it is possible using only node-xmpp, but node-xmpp is pretty low-level library. I used npmjs.org's search to look for modules supporting MUC, but could not get any of them working yet.. I think MetaJack's source-code about MUC could help you out. This could be a fun project to implement over the weekend I guess.
When you like to get started immediately you should probably(maybe somebody has MUC in node-xmpp?) have a look at Smack(Java) for example which does support MUC.

Resources