Messaging a user a bot does not know - node.js

I am using the Slack RTM node client and having a bit of an issue with DM's. Say a user joins the channel who has never DM'ed the bot before, the user types a command in the channel that the bot usually will respond to and by default the bot responds in a private message to the user. However, the bot cannot do this because the dataStore does not contain any DM data for this user. Code sample below...
rtm.on(RTM_EVENTS.MESSAGE, function (message) {
user = rtm.getUserById(message.user);
console.log(user); // It gets the user object fine
dm = rtm.getDMByName(user.name);
console.log(dm); // This is always undefined unless the user has DM'ed the bot previously
});
Is there a way around this? I can't seem to find anything in the docs or code to suggest there might be.

You can use the im.open method of the web API. Here's roughly how you'd do it with #slack/client (untested, apologies in advance!):
var webClient = new WebClient(token);
...
rtm.on(RTM_EVENTS.MESSAGE, function (message) {
var dm = rtm.getDMById(message.user);
if (dm) {
console.log(`Already open IM: ${dm}`);
// send a message or whatever you want to do here
} else {
webClient.im.open(message.user, function (err, result) {
var dm = result.channel.id;
console.log(`Newly opened IM: ${dm}`);
// send a message or whatever you want to do here
});
}
});

Related

Direct Messaging custom slack bot built on node.js

I have built a slack bot using the slack/bots apis in node.js: https://slack.dev/bolt-js/tutorial/getting-started
Currently, it is working fine when I type <bot> help in a channel I have set up for using webhooks. I am trying to run those same commands in a DM with the bot using the app.event('app_mention',...) method but it is not working. its like the message doesn't register in a DM with the bot for some reason but it works in a public channel. code snippet below:
app.event('app_mention', async ({ event, client}) => {
console.log(event);
const text = event.text;
const parentMessageId = event.ts;
const eventChannel = event.channel;
if (text.includes("help")) {
console.log(event);
try {
await client.chat.postMessage({
channel: eventChannel,
text: helpMessage,
thread_ts: parentMessageId
});
} catch (err) {
console.error(err);
}
I should have permissions set up correctly as well. I basically have all the permissions that I can add for the bot
The documentation of the app_mention api specifically mentions that this event does not work with DMs.
Messages sent to your app in direct message conversations are not
dispatched via app_mention, whether the app is explicitly mentioned or
otherwise. Subscribe to message.im events to receive messages directed
to your bot user in direct message conversations.
Check here : https://api.slack.com/events/app_mention

How to forward message from channel to the groups on telegram bot?

im trying to implement my bot a function. Function that if the channel write any message it will be forwarded to the groups where the bot already is.
Trying to use scope method that worked like a charm on welcome message when new user joined the group.
//index.js
const Telegram = require('telegram-node-bot'),
tg = new Telegram.Telegram('MYAPI', {
workers: 1
});
const ForwardController = require('./controllers/forward')
tg.router.when(new Telegram.TextCommand('/info', 'infoCommand'), new InfoController())
.otherwise(new ForwardController());
//forward.js
const Telegram = require('telegram-node-bot');
class ForwardController extends Telegram.TelegramBaseController {
handle(scope) {
if ('channel' == scope.message.chat._type) {
scope.api.forwardMessage(scope.message._chat._id, _forwardFromChat._text);
}
}
}
module.exports = ForwardController;
I tried many combinations but the message is never forwarded... The bot is already administrator on the channel and is also putted in the groups. (Have also private message opened with bot so i think it should forward also there)
Take a look at the API reference for the library, the documentation page appears to be down so Github is your friend.
The forwardMessage call you are making has incorrect arguments and is accessing the private class variables. It is also returning a promise so you should await the promise or chain a .then to it. You can use the class methods on the Scope instance itself.
It should be more like:
// using async/await - note the containing function must be async for this approach
const result = await forwardMessage(<id of chat here>, scope.message().id());
// or to chain a .then
forwardMessage(<id of chat here>, scope.message().id())
.then(result => /* do something with result */)
.catch(err => /* handle the error */);
This will use the Scopes instance method and handle sending the id of the current chat for you, all you need is the id of the chat you want to send the message to and then replace the <id of chat here> with that id.

Authorization error Skype Bot a day later

The bot works on such a case: the user subscribes to the event, and then the event (event generated in TeamCity) should receive a notification.
The bot works fine within one day. But at night in most cases new events are not sent to the user.
error 401 "Authorization has been denied for this request" is written in the logs when the message is sent to the user (await context.sendActivity(message))
When a user subscribes to an event, I save the link to the conversation.
const reference = TurnContext.getConversationReference(context.activity);
reference => saving to base as string (used JSON.stringify)
When I receive an event, I read the link to the conversation from the database and try to send a message.
const reference = JSON.parse(reference from base)
await adapter.continueConversation(reference, async (context) => {
try {
const reply = await context.sendActivity(message);
const reference = TurnContext
.getReplyConversationReference(context.activity, reply);
} catch (e) {
console.log(e);
}
})
3.The link to the dialogue, after sending the message, is again stored in the database
What could go wrong? Why does the code work fine during the day, and after a long time, stop?
If you send any message to the bot from any user, the messages begin to be sent again.

Private messaging a user

I am currently using the discord.js library and node.js to make a discord bot with one function - private messaging people.
I would like it so that when a user says something like "/talkto #bob#2301" in a channel, the bot PMs #bob#2301 with a message.
So what I would like to know is... how do I make the bot message a specific user (all I know currently is how to message the author of '/talkto'), and how do I make it so that the bot can find the user it needs to message within the command. (So that /talkto #ryan messages ryan, and /talkto #daniel messages daniel, etc.)
My current (incorrect code) is this:
client.on('message', (message) => {
if(message.content == '/talkto') {
if(messagementions.users) { //It needs to find a user mention in the message
message.author.send('Hello!'); //It needs to send this message to the mentioned user
}
}
I've read the documentation but I find it hard to understand, I would appreciate any help!
The send method can be found in a User object.. hence why you can use message.author.send... message.author refers to the user object of the person sending the message. All you need to do is instead, send to the specified user. Also, using if(message.content == "/talkto") means that its only going to run IF the whole message is /talkto. Meaning, you can't have /talkto #me. Use message.content.startsWith().
client.on('message', (message) => {
if(message.content.startsWith("/talkto")) {
let messageToSend = message.content.split(" ").slice(2).join(" ");
let userToSend = message.mentions.users.first();
//sending the message
userToSend.send(messagToSend);
}
}
Example use:
/talkto #wright Hello there this is a dm!

How can I post a welcome message to a newly joined user via a Slack bot?

I am trying to leverage Slack's Real-time messaging (RTM) API to post a welcome message to newly joined users of my team from a "Greeter Bot".
The event I'm listening for is team_join.
I have confirmed that the event is firing, and that messages can be sent to previously joined users out upon receiving that event. However, when trying to notify the newly joined user, nothing comes through.
I've played around with adding a delay (up to 45secs) after receiving the event before notifying the user, but still no dice.
Here my index.js file:
var SlackBot = require('slackbots');
var bot = new SlackBot({
token: process.env.SLACK_TOKEN || '',
name: process.env.BOT_NAME || 'greeterbot'
});
bot.on('message', function(data) {
var self = this;
if ('team_join' === data.type) {
setTimeout(function() {
var message = 'hello.';
// this works. 'some crusty old user' gets a DM message from my greeterbot.
self.postMessageToUser('some crusty old user', message, { as_user: true });
// FAIL. what am i doing wrong?!
self.postMessageToUser(data.user.name, message, { as_user: true });
}, 45000);
console.log("'" + data.user.name + "' has joined the team."); // works. the user name is present in the log.
}
});
I figured it out. There is a caching issue with the underlying bot library that I'm using.
For reference, here is a link to a PR that aims to address this issue.
https://github.com/mishk0/slack-bot-api/pull/25
Switching libs now.
Our Slack team, SKGTech.io uses Janitr that we wrote. Janitr is a Slack bot that welcomes new users based on your preferences.

Resources