Slack API : How to manage sessions in different channels? - session

I am developing a Slack Bot that gets data from a user and executes queries on it. But if there are 2 channels within the same workspace, and one channel provides the data, the other is then able to query on that data.
I want to prevent this behaviour by having different sessions for different channels. What is the best way to implement this?

As Colm mentioned in the comment, it would be helpful to know more about your application.
A generic answer to your question would be to scope your data by channel. For example, if your application receives slash commands, you will get all the necessary details in the payload. Therefore, when storing received data, use team_id and channel_id to scope the data to the relevant context.

Related

Slack Bot send DM message to the User

I want to send message as DM to the users, so I've come with some questions;
1- There are two ways to send DM to the user;
the first one open a conversation with user by using conversation.open, and send message. Then if I want to send the message to the same user, I use conversation.list and find the conversationId by userId, then send message to the same channel again.
Second one is just basically using userId as channelId parameter in chatPostMessageRequest.
I've tried both ways, and both of them are sending message as DM. So, what is the purpose of using conversation.open? I'm asking this because nearly all the answers say you should do this etc.
2- Seems like there is no way to get multiple users by emails except users.list?
3- Also seems like there is no way to send messages to the multiple user at the same time (the content of the messages are different, those are depends on user data).
Sending a direct message by user ID works with chat.postMessage as a convenience, a shortcut. But it's the only method/API that allows you to use a user ID as a channel ID, so Slack warns developers away from relying on it in totality -- if you use conversations.open and the resultant conversation ID, it'll work for other methods like chat.update should you need to edit the message after sending it.
Slack doesn't offer many "lookup" APIs -- most things you'll want to look up require fetching an entire data set (like a list of users with all pages of users.list) and then filtering the results yourself. There are no APIs to look up multiple users at once via email address.
There is also no way to send the same direct message content to multiple users with a single request. In most cases, when an app is sending the same message to multiple users the best practice would be to use a channel to broadcast the message a single time, with the intended recipients as members of the channel.

slack chat.postMessage vs. incoming webhook?

I am trying to send messages from several outer sources to a specific channel, which is private and belongs to myself only. The username should be the name of source, not my ID.
I found there are two ways to do such a similar function: Incoming Webhooks and chat.postMessage
I have already practiced these two, which seems no difference between them.
However, in Incoming Webhooks, a statement says:
You can't use Incoming Webhooks with Workspace Apps right now; those
apps can request single channel write access and then use
chat.postMessage in the Web API to post messages, providing very
similar functionality to Incoming Webhooks.
What does it mean?
To my work, which one is better?
with chat.postMessage() you send a message to a specific channel, often you do that in response to a users action. You will need the token to verify the postMessage Request which you receive when the user installs your app.
Incoming webhooks are often used to post general information, e.g. patch notes or general announcements.
As far as I know, you don't need the token since there is a verification behind that Url.
so the webhook url is bound to a specific channel, which is specified through the user. With chat.postMessage you can post messages anywhere (depending on your permissions, maybe not in private channels or direct messages)
Adding to what Ben said:
Incoming webhooks are limited in their functionality. They are great if you need an easy way to send a message that does not require a token, but in general the API method (chat.postMessage) is the better choice. It is more flexible (e.g. not fixed to one channel) and provides the full functionality (e.g. you get the ID for a message and can later update it).
Workspace apps / tokens where a new functionality that allowed apps to be installed in one channel only (among other things). It never left its beta stage and can be safely ignore for further development.

What is a proper way to handle AdaptiveCard action using DirectLine?

What is a proper way to handle AdaptiveCard action on the client side using DirectLine? Should I build "value" for activity by hand?
If so, I realized that multi-select's value is handled in different way for different channels (BotFrameworkEmulator sends the values separated with commas while WebChat uses semicolons). Which format should I pick? Isn't this inconsistency a bug?
The Emulator is in a sense a form of WebChat. I don't think the inconsistency is a bug, but if you see WebChat in different places then it's likely to be different versions and may therefore have different behavior.
Fortunately your bot code is free to interpret the received values however you want it to. If your bot is likely to run on multiple channels then you may want to make your bot smart enough to account for multiple possible choice-separators. Otherwise you can just make sure your bot is looking for the right separator for the channel you want to run it on.
As far as I can tell commas are the more standard up-to-date separators, so it's probably best to go with those. But if you're making your own Direct Line client then it's ultimately up to you how you format the activities that your client sends to the bot.
I would say that the inconsistency is not a bug, it is just the way the data is sent back by different channels. Please remember, Adaptive cards are a fairly new concept of exchanging data between the user and the bot code. It is still going to take time how the values are rendered and posted by each channel to come to a common format. That being said, I would not over think this problem much.
The design pattern for the bot should always be made after fixing the channels that the bot will be published on. Once the channels are fixed then it would just be matter of coding to handle the various ways in which the post back data is sent back to the bot

Need suggestions in getting the conversation details

I am creating a bot using MS Bot framework - NodeJs. The below information needs to be captured for logging (Using the bot.use method i.e. IMiddleware).
Receive:
a. UserId
b. UserInput (text)
c. ConversationId
Send:
1. Name of Intent or dialog name that handled this (that handled the user input text)
2. Bot output text
3. ConversationId
4. UserId
I am unable to get the required detail for the 'send'. Can anyone provide me some suggestions on this.
Thanks.
I believe your main struggle is to log the name of intent or dialog. You won't know it in your send middleware if you haven't captured it during the routing phase. Once the Bot Framework figured out where to send the incoming message, it just invokes that function.
These two articles may help you get what you want. Just recently I played with capturing the conversation's breadcrumbs and also logging a full transcript:
http://www.pveller.com/smarter-conversations-part-3-breadcrumbs/
http://www.pveller.com/smarter-conversations-part-4-transcript/
If you need to build a reliable capture engine, I would suggest that you didn't use the session.privateConversationData like I did and instead built your own storage/log infrastructure to push the events to. Just stream them out with a timestamp and conversationId and reconcile on the other end later. The asynchronous nature of everything the bot framework does internally will be haunting you along the way so that's why. Plus, once you scale out beyond testing on a few users and your bot spans multiple processes, you will be out of the single-threaded event loop.

How do I correlate user between channels?

From what I see, Bot Framework is providing an abstraction over users in different channels by providing a ChannelAccount class that has ChannelId/Address pair to identify user via its account and Id property, which is... okay, here's the question.
I suppose that the idea behind Id is to provide a unique and persistent identifier that can be used to cross-correlate users between account (i.e., I can say that Slack user #alpha is also email user alpha#company.con). This idea is supported by the fact that ChannelAccount for my bot always has same Id regardless of the channel (and Address is different between channels, obviously).
If this is right, and I hope it is, is there any way to provide BotConnector with the correlation information? I.e., I want BotConnector to give me ChannelId/Address, and I'd give back user Id which I'd the get back in incoming message.
The purpose of this is quite simple: I want the code inside my bot to use the Id as already correlated identifier so that I can log it, build logic from it and so on.
BotFramework does not yet support linking of accounts. In the interim, take a look at this post for one way you might implement a solution:
Why isn't BotUserData persisting and retrievable in my Bot Framework bot?

Resources