Slack Bot Replying to his own message in Node js - node.js

I am trying to make a slack bot in nodejs that replys the user based on their input. But As far now the bot keeps replying to his own messages
this is the code for my bot
let Bot = require('slackbots');
// create a bot
let settings = {
token: 'xoxb-10584202949',
name: 'BotHelp'};
let bot = new Bot(settings);
bot.on('start', function() {
bot.postMessageToChannel('general', 'At your service');
});
bot.on('message',function (data) {
console.log(data);
if (data.username != "BotHelp" && data.subtype != 'bot_message'){
bot.postMessageToChannel('general', 'Yoooo');
}
});
The Console log for data Prints
{ type: 'hello' }
{ text: 'At your service',
username: 'BotHelp',
bot_id: 'B336WGVSM',
type: 'message',
subtype: 'bot_message',
team: 'T2ZAW44P3',
user_team: 'T2ZAW44P3',
channel: 'C303W2D4M',
ts: '1479877794.000266' }
{ type: 'presence_change',
presence: 'active',
user: 'U33QS0VEF' }
So why my validation is failing to check that the message has been sent from bot itself or not?
Thank you for your time

I had the same issue. The message event in slackbots fires for every event ie, user_typing, message_marked, desktop_notification. All events can be found here.
Now what i did to ensure my bot didn't send a message after receiving its own was:
bot.on('message',function (data) {
if (data.user != "Uxxxxxx" && data.message === 'message'){
bot.postMessageToChannel('general', 'Yoooo');
}
the data.user gives a unique id, you can get this by console.log(data) and find your user id.
Also, if you want to specify which message you want to listen to, say direct message. channel id inside data will start with a D. For private channels, the channel id starts with G
Hope this helps. I know there is much more to do here but this is the basic. And you can grow on this. I know I will be trying to :D

I know that the question is already answered but I will like to add my answer, because the slack api has made some changes.
if (data.type !== "message" || data.subtype === 'bot_message' ){
return;
}
else{
bot.postMessageToChannel('general', 'Yoooo');
}

If I were you I'd check if the parameters are really user_name and subtype . If it's right, I would try to check the type of the objects that are coming(Maybe there is a cast in objects coming from the Slack api). I've done a small project very similar to yours, using the same library slackbots and also a library I built myself,nodejslack(https://github.com/marcogbarcellos/nodejslack) but didn't get this issue.

Related

I just made a welcome and goodbye message for my discord.js bot but it doesn't send the messages to the required channels

Here's my code,
Welcome message:
client.on('guildMemberAdd', async member => {
if(member.guild.id !== "737222740305641472")return;
const channel = guild.channels.cache.get("750952211659620413")
if (!channel) return;
let data = await canva.welcome(member, { link: "https://imgur.com/a/BPTpkDT", blur: false })
const attachment = new Discord.MessageAttachment(
data,
"welcome-image.png"
);
channel.send(
"Welcome message here",
attachment
);
});
And my goodbye message's code:
client.on('guildMemberRemove',(member) => {
if(member.guild.id !== "737222740305641472")return;
guild.channels.cache.get('781737515421138984').send(`Goodbye message here`);
});
I'd like to make it clear that I dont get any error's in my console and that I've given the bot all the perms it needs to send messages.
Also, I've already declared my guild before, so that isn't supposed to be the problem.
Can anyone tell what I'm doin wrong?
As directed by this comment, it is appearent that you have not enabled privilliged intents for your application. For your application to listen to events such as guildMemberAdd and guildMemberRemove you would have to enable to Members Intent from the Discord Developer Portal. Here is what you would be looking for:
This can be found under
Your Application > Bot > ( Scroll down ) Privilleged Gateway Intents > Server Members Intent ( toggleable ).
This was a change introduced in the Discord API version v8 for the intents to be mandatorily enabled for such API requests.

discord.js how to send message when bot joins to a new server without system message channel?

I'm trying to send message with bot upon joining with statement.
//Will post message when bot joined new server because system channel exists.
if(guild.systemChannelId != null) return guild.systemChannel.send("Thank you for invite!"), console.log('Bot Joined new server!')
//Send post join message when there is no system channel on the server to possible channel (not working)
client.guilds.cache.forEach((channel) => {
if(channel.type == "text") {
if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
channel.send("Thanks for inviting me")
console.log('Bot Joined new server!')
}
}
})
guild.systemChannel.send("Thank you for invite!")
This one works and will send message to the "default system channel". Problem is if server has no system channel, this will appear as error. So i had to create statement above and use this request only when system channel exists.
Error: Unhandled rejection TypeError: Cannot read property 'send' of null -> error will appear when using only guild.systemChannel.send("Thank you for invite!") in the code without statement.
How to send message to the first channel possible if system channel does not exist on the server?
You simply need to access the first cached text channel you can achieve this by accessing the cache and filtering for text channels bot has permissions to send messages to like so:
client.on('guildCreate', (g) => {
const channel = g.channels.cache.find(channel => channel.type === 'GUILD_TEXT' && channel.permissionsFor(g.me).has('SEND_MESSAGES'))
channel.send("Thank you for inviting me!")
})
The easiest way is to forEach through each channel in the cache, and stop once you find one:
bot.on('guildCreate', guild => {
let found = false;
guild.channels.cache.forEach((channel) => {
if(found) return;
if(channel.type === "text" && channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
channel.send("Thank you for inviting me!");
found = true;
}
})
});

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.

Messaging a user a bot does not know

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
});
}
});

Resources