Direct Messaging custom slack bot built on node.js - 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

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.

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.

How do I get notifications when a bot sends a message in Teams?

I developed a bot for Microsoft Teams using the Microsoft Bot Framework v4 Nodejs SDK (botbuilder-sdk for nodejs). We have implemented the bot in such a way that, when we receive data using a REST API call from one of our CRMs, the data is posted to the channels on Microsoft Teams. However, when I do that, we do not receive a notification on the devices. Has anyone faced such an issue?
I am saving the context state initially. Everytime we receive data from a CRM, I am incrementing the activity id of the message (to send it as a new message and not a reply) and sending it to Microsoft Teams using context.sendActivity().
When we receive that adaptive card, we do not receive a notification in the activity feed or on any of the devices.
I have gone through all the steps as you described above. I've also gone through the troubleshooting steps. However, it still doesn't give me a notification for the card. However, when I initiate a conversation with the bot, I get a notification when the bot responds.
https://i.stack.imgur.com/Bi4fc.png
https://i.stack.imgur.com/ab6uP.png
In this image, I get a notification when I get the TMS Bot started! message. However, I don't get a notification for the next two messages.
Edit: OP and I have exchanged a few emails to get this answered. This answer, as a whole, is good information for accomplishing Teams Proactive messaging, in general, but the main answer is in the last section, Simplified Code.
This is a long answer that covers many areas, simply because I'm not 100% sure I know what kind of notification you aren't receiving.
Troubleshooting
Troubleshooting Guide
Pay special attention to the many areas where notifications need to be enabled
In particular, the user may need to "Follow" and/or "Favorite" the channel to receive notifications from it
If a user has the desktop app open, they will receive the notification there and will not receive one on their phone unless they have been inactive on the desktop app for 3+ minutes. Otherwise, it's likely a bug in Teams.
Chat Notifications
If you've followed the Troubleshooting Guide linked above, your users should receive chat notifications. If not, you can try updating your MS Teams desktop or mobile client. As #KyleDelaney mentioned, it may be helpful to # mention users and/or channels
Activity Feed Notifications
You can also create Activity Feed Notifications. The gist of it is that you need to:
Include text and summary in the message
Include channelData that sets notifications.alert to true
This code will accomplish that:
const msg = MessageFactory.text('my message');
msg.summary = 'my summary';
msg.channelData = {
notification: {
alert: true,
},
};
return await dc.context.sendActivity(msg);
Result:
Note: If your bot only creates notifications and doesn't have conversations, you may benefit from creating a notifications-only bot.
Full Implementation Code
import * as adaptiveCard from '../src/adaptiveCard.json';
...
const card = CardFactory.adaptiveCard(adaptiveCard);
const activity = {
attachments: [card],
text: 'Test Card',
summary: 'my summary',
channelData: {
notification: {
alert: true,
},
},
};
await turnContext.sendActivity(activity);
Result:
Using the Teams Extension
There's a Teams Extension for BobBuilder V4 that's currently in Beta, but seems to accomplish what you need. I believe the reason you weren't getting notifications while using the above is because your bot is creating a new reply chain in the channel and not replying directly to a user. I believe you can do all of this without the extension (by manually editing activity/context properties), but the extension should make it easier.
Here's the code I used to get working notifications within a channel:
In index.js (or app.js):
import * as teams from 'botbuilder-teams';
[...]
// Change existing to use "new teams.TeamsAdapter..."
const adapter = new teams.TeamsAdapter({
appId: endpointConfig.appId || process.env.microsoftAppID,
appPassword: endpointConfig.appPassword || process.env.microsoftAppPassword,
});
Wherever you're sending the message:
import * as teams from 'botbuilder-teams';
import * as adaptiveCard from '../src/adaptiveCard.json';
...
const card = CardFactory.adaptiveCard(adaptiveCard);
const activity = {
attachments: [card],
text: 'Test Card',
summary: 'my summary',
channelData: {
notification: {
alert: true,
},
},
};
const adapter = context.adapter as teams.TeamsAdapter;
await adapter.createReplyChain(context, [activity]);
Simplified Code
OP and I have emailed back and forth a bit and the key issue is that he needed to add the trustServiceUrl code from below. Normally, this manifests itself with a 500 error, but in this case, it appears to not create notifications.. After significant testing, here's all you really have to do to send different notifications to different channels. It basically amounts to setting a couple of properties of turncontext.activity and trusting the serviceUrl. No touching activity ID or using the Teams Extension at all. My code below is how I sent messages from Emulator that could then send cards to different Teams channels:
public onTurn = async (turnContext: TurnContext) => {
const dc = await this.dialogs.createContext(turnContext);
const dialogResult = await dc.continueDialog();
// Route message from Emulator to Teams Channel - I can send "1", "2", or "3" in emulator and bot will create message for Channel
let teamsChannel;
switch (turnContext.activity.text) {
// You can get teamsChannel IDs from turnContext.activity.channelData.channel.id
case '1':
teamsChannel = '19:8d60061c3d104exxxxxxxxxxxxxxxxxx#thread.skype';
break;
case '2':
teamsChannel = '19:0e477430ebad4exxxxxxxxxxxxxxxxxx#thread.skype';
break;
case '3':
teamsChannel = '19:55c1c5fb0d304exxxxxxxxxxxxxxxxx0#thread.skype';
break;
default:
break;
}
if (teamsChannel) {
const card = CardFactory.adaptiveCard(adaptiveCard);
const activity = {
attachments: [card],
summary: 'my summary',
text: 'Test Card',
};
const serviceUrl = 'https://smba.trafficmanager.net/amer/';
turnContext.activity.conversation.id = teamsChannel;
turnContext.activity.serviceUrl = serviceUrl;
// This ensures that your bot can send to Teams
MicrosoftAppCredentials.trustServiceUrl(serviceUrl);
await turnContext.sendActivity(activity);
} else {
[...Normal onTurn Code...]
await this.conversationState.saveChanges(turnContext);
}
Note: To receive notifications, you and your users must follow the channel.
I have gone through all the steps as you described above. I've also gone through the troubleshooting steps. However, it still doesn't give me a notification for the card. However, when I initiate a conversation with the bot, I get a notification when the bot responds.
https://i.stack.imgur.com/Bi4fc.png
https://i.stack.imgur.com/ab6uP.png
In this image, I get a notification when I get the TMS Bot started! message. However, I don't get a notification for the next two messages.

Microsoft Azure Bot Framework SDK 4: Send proactive message to specific users from bot using Node js

I am able to send message to specific users with older botbuilder SDK 3.13.1 by saving message.address field in database.
var connector = new builder.ChatConnector({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword,
openIdMetadata: process.env.BotOpenIdMetadata
});
var bot = new builder.UniversalBot(connector);
var builder = require('botbuilder');
var msg = new builder.Message().address(msgAddress);
msg.text('Hello, this is a notification');
bot.send(msg);
How can this be done with botbuilder SDK 4? I am aware of the Rest API but want to achieve this with the SDK itself because the SDK is the more preferred way of communication between the bot and user.
Thanks in advance.
Proactive Messages in the BotFramework v4 SDK enable you to continue conversations with individual users or send them notifications.
First, you need to import TurnContext from the botbuilder library so you can get the conversation reference.
const { TurnContext } = require('botbuilder');
Then, in the onTurn method, you can call the getConversationReference method from TurnContext and save the resulting reference in a database.
/**
* #param {TurnContext} turnContext A TurnContext object representing an incoming message to be handled by the bot.
*/
async onTurn(turnContext) {
...
const reference = TurnContext.getConversationReference(turnContext.activity);
//TODO: Save reference to your database
...
}
Finally, you can retrieve the reference from the database and call the continueConversation method from the adapter to send specific users a message or notification.
await this.adapter.continueConversation(reference, async (proactiveTurnContext) => {
await proactiveTurnContext.sendActivity('Hello, this is a notification')
});
For more information about proactive messages, take a look at the documentation or this example on GitHub. Hope this is helpful.

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