Cannot delete a chat message via Slack API - slack-api

I have a Slack team with a public channel.
My goal is to use the channel only for announcements posted by bot-A.
I understand that it is not possible to configure Slack channel to be writable for only one person and read-only for the rest, I created a bot-B (Python thing running on an external machine) that monitors the channel via RTM and if there is any message not coming from bot-A, bot-B's task is to delete the message by calling chat.delete (https://api.slack.com/methods/chat.delete). Bot-B is also in the channel.
Unfortunately bot-B is getting "cant_delete_message" which, according to the chat.delete doc, means that he has no permissions.
However, according to https://api.slack.com/bot-users, chat.delete is allowed for Custom Bots.
So is my bot-B not a "Custom Bot"? If so, what does a Custom Bot actually is and how can I create one?
Or what am I doing wrong?

I believe that a Slack user (bot or otherwise) is only allowed to delete its own messages. There's no way to delete messages posted by someone else.
EDIT: I stand corrected. Admins can delete other people's messages. From https://get.slack.help/hc/en-us/articles/202395258-Editing-or-deleting-messages:
Owners and Admins can delete messages from any sender as long as the messages are in public or private channels that the Owner or Admin has joined.

Related

How to get the Slack DM channel ID of the Slack App

I have created a simple Slack App app where the only purpose is to send a message to a channel. I understand that there is the conversations.list API to list all public channels to get the correct ID.
However, as a first step, I just want to send the message to the app channel itself. If I use the D... ID it works as expected. No invite by the channel is needed. But how do I get this ID? conversations.list only returns publich channels, but no the app channel itself.
In Slack, there is no such thing as an app's channel. There is a DM channel between every user and your app/bot. In these terms, to send a DM message from your app/bot to the user, you need to know ID of this user and specify it as a channel argument of the postMessage API request.
The ability to pass a Slack user ID as channel is somewhat unique to chat.postMessage. If you try this with other API methods which expect a channel ID only (conversations.info), you'll get "error": "channel_not_found". The docs state:
Begin a conversation in a user's App Home
Start a conversation with users in your App Home.
With the chat:write scope enabled, call chat.postMessage and pass a user's ID (U0G9QF9C6) as the value of channel to post to that user's App Home channel. You can use their direct message channel ID (as found with im.open, for instance) instead.
Source: https://api.slack.com/methods/chat.postMessage#app_home
Note: The above behavior assumes you're using the bot token. If you provide the user token instead, you'll make the user DM themselves.
Now, if you *do* need to get a user's App Home channel ID for use outside of chat.postMessage, keep reading... Here are three ways to do it, each with their own shortcomings:
1. chat.postMessage
Well, it's worth mentioning that if you are going to use chat.postMessage, it returns the resolved channel ID in its response: "channel": "D01234ABCDE". You can save this for later use.
2. conversations.open
The API method im.open referenced in the docs above has been renamed to conversations.open, which can be used to obtain the user's App Home channel ID:
Use the user token, and set users to the app bot ID, or
Use the bot token, and set users to the user ID.
Though, I've observed some weirdness with conversations.open, which may or may not be a dealbreaker for you:
It requires stronger OAuth permission scopes than ones required to initiate a private DM with a user than chat.postMessage (a bot token with chat:write is insufficient), and
It behaves strangely with respect to the "open state" of a conversation. For example...
I tested this method with a user token.
The user for that token already had a DM channel with the app! (Doesn't that mean the conversation is already open?)
Strangely, the first response had is_opened: false (and subsequent responses had is_opened: true).
3. app_home_opened
The event app_home_opened fires when the user opens your App Home. If you handle this event, you can save the channel in the event payload on your server and use it later, obviating the need to later call conversations.open.
Since the event only occurs if and when the user opens your app's App Home, this approach is more of an optimization than a standalone solution.
4. A better way...?
Due to the drawbacks outlines above, if anyone knows a better way of getting the App Home channel ID for a Slack user, please, comment on this answer!
You can get the channel ID of the app channel through the GUI if you:
navigate to a message in the channel
go to the more actions men
select copy link
The channel ID will be the string following archives/ eg:
{myorg}.slack.com/archives/{channel_ID}
Using this approach would work for any channel in the slack app, though it's unlikely to be the best approach since it's manual vs something more programmatic.

Slack api conversations.history returns error: not_in_channel

I'm starting out with the Slack API and trying to just get a list of messages.
Here are my steps:
Created a Slack app and gave it channels:read and channels:history scope (also re-installed it)
Queried the list of channels with conversations.list (this worked fine)
From the output of conversations.list, I found a channel that I use and copied the id
Used the conversations.history api with the channelid from step 3
Result:
{ "ok": false, "error": "not_in_channel" }
I'm not at all sure what is happening here. I definitely have messages in the channel, and the documentation page for that api does not say anything about this "not_in_channel" error code.
What am I doing wrong?
After a long time of investigations (~2 hours), I found an easy approach. For Caleb's answer, I didn't understand how to invite a Bot to the channel. Hence, I am posting this answer.
Go to your Slack Channel and type the following as a message.
/invite #BOT_NAME
Eg: If your Bot name is SRE Incident Manager the command would be as follows.
/invite #sre_incident_manager
As soon as you start typing #, Slack will automatically suggest. So it becomes easy. For this, the Bot needs to be added to your Slack Workspace.
PS: Original answer.
The error not_in_channel has the exact meaning, your custom Slack app should be added to the channel.
Exact solution 1
To resolve the error, in the Web Slack interface:
Open channel settings
Click on the Integrations tab
Click Add apps and find your custom app.
Slack app might have different interface, see Iryna Vernik's answer.
Alternative solution 2
Give access to the bot to all channels by adding workspace wide scope, for example, chat:write.public. Depends on your needs and security requirements.
Alternative solution 3
To access the channel chat from API specify Incoming webhook. Slack will generate a unique URL with the token per each channel. Only convenient for a few channels.
This error arises when you are using the bot oauth token and the bot is not invited to the channel. To solve this you need to
Invite the bot(slack app) to join the channel.
Use the OAuth Access Token instead
To add Bot to your channel you need to write /invite #Bot_name in the slack channel
I also didn't understand how to invite a Bot to the channel. Way that was proposed by Caleb and Keet was not clear for me or not working. From my side, 'invite' work after
open channel
in Details tab, choose a 'More'clause
in dropdown menu, chouse an 'add app'
in pop-up look for you app (bot)
Also i was use Bot User OAuth Access Token, because i need this functionality in private channel (additionaly, you should add for bot groups:history scope)
FOr me, instead of invite a user/bot, I invite the app.
I'm getting started with the Slack API as well, and I've come to realize that not_in_channel simply means that the user/bot you are using the token for hasn't joined that particular channel you're trying to perform an action on.
Think of it this way: if you're using Slack on the web-browser or web-app, you wouldn't be able to post a message on a channel you haven't either joined or was invited to.
☝️ You'll also never run into this issue through the Slack UI/UX because you're not even able to access the channels UNTIL you are invited or join it.
Click to see png example of a slack message stating my bot being added to a channel
However, because we're using the API we can essentially skip some steps, and in this case we skipped the step where a user/bot has joined the channel before doing the action we're trying to perform (writing a message, grabbing information, etc).
💪 How to address this
There's probably plenty of ways to do it that I'm not versed in, but if you're just concerned about a specific channel or two without the concern of scaling to x channels I'll list the way that worked for me.
📇 /invite Slash Command
As others have mentioned, putting /invite in the message box lets you use Slack's slash command shortcut to add users. What's important is this way also allows us to invite bots to the channel.
Putting "#" triggers Slack to start auto-suggesting, which is why it then becomes easy to find your bot name in the list.
Click here to see screenshot example of the /invite command with #bot_name_here
Hope this helps answer people's question on why it's happening, and thank you to the original posts that got me out of my initial mess. 🙏
As all others said, you need to join each channel.
The bot can join channel programmatically by using API below:
https://api.slack.com/methods/conversations.join
Don't forget to add permission of conversations.join

Using the Slack web API when deep linking to direct message/IM, I get "#deleted-channel"

When responding to a slash command with a string that includes a channel ID like <#C3989289>, the response in Slack shows a deep link to that channel "#general.
When I do the same for a direct message or IM, the response in Slack shows "#deleted-channel" and it's not a link.
I don't see anything in the docs about why this: https://api.slack.com/docs/message-formatting#linking_to_channels_and_users
Slack has confirmed that their system is designed in this way to protect private channels/direct messages from being made aware to users, even if the recipient of the message containing the deep link does belong to that particular channel/DM.

Trying to create multiple conversations to the same person/participant

I'm wondering is there someway to create more than 1 conversation to the same person? We receive inbound messages through an SMS service and then forward the text message on to the user via a Lync conversation. When we create the conversation we pass in some contextual information so that if the user responds in the lync conversation we can send the reply back to the sender via SMS.
My problem is that if more than one text message comes in from different people for the same internal user then the lync sdk is sending both message into the same conversation (which is the default behaviour for Lync) which means I lose the contextual info for the first message that initially created the conversation, also if the user writes a reply in the lync conversation I have no way of knowing to whom that message should go to. Hopefully I haven't lost you....
I can't see a setting or property in the sdk when creating conversations to create a new instance of a conversation even if one already exists for the intended sip address.
Any suggestions?
troy
I came across the same problem recently, it looks like the Lync (specificly the 2013 client, we had no problems before) automaticly merges conversations from the same user address.
If we set up a second conversation to a user from the same sip uri (our application endpoint), the first conversation will be terminated, and the second conversation becomes active. This is all seamlessly merged in the Lync 2013 client, you dont even notice.
The (crude but working) fix was to call Conversation.Impersonate() with a different uri for each new conversation. Mind you this only works when creating conversations on a Trusted Application Endpoint.

MOTD for channels

Is there a way to display a file/string of text to a user's channel output when a user joins a channel? Would this have to happen serverside in the irc config or could a bot do the same?
A bot could do it. Many servers, such as Freenode, support sending notices via the server's services to users upon joining a channel.
Either way you let a bot react on a join event and send a message (/msg) or a notice (/notice) to the user.
Or you let the server send an entry message if the server supports this service. Most common you do this with "/chanserv set entrymsg my_message".

Resources