So I'm building a slack app in Node that responds to some user commands. It usually responds with an interactive message that has some attachments and buttons.
For certain buttons, I return different types of texts or other attachments, but I also want to have a "Cancel" button that would basically cancel the current command - delete it from the user's chat.
The thing is that I want to do it without having to request the chat:write:user scope or without having to create a bot.
By asking for the chat:write:user scope I can basically remove any message the user created, but it asks for that scope when installing the app and gives my app permission to post on behalf of the user, which most find uncomfortable.
By creating a bot I could achieve this, but again it asks for permission to add a bot to the channel and I don't want this.
What I've tried
Use chat.delete method, but I get { ok: false, error: 'missing_scope', needed: 'chat:write:user', provided: 'identify,commands' } from Slack, even when I try with as_user set to false.
Respond with an empty message to the command, like res.send(), or res.send({ text: null }), or res.send({ attachments: null }), etc.
When you reply to a user command on Slack it overrides by default the previous content. I just want to override with nothing, basically removing the original response. When I try this however, it doesn't do anything, unless I provide some content.
I'm pretty sure #2 is the way to go and I feel I'm close and it's something pretty simple but out of my sight.
Working example of what I want
I know it can be done because the GIF Keyboard app for slack does this. When searching for Gifs, they have a "cancel" button at the bottom that just removes the current command/message. Furthermore, they only ask for the Commands scope.
You are on the right track. Option #2 works, so no need to request scopes to delete a message.
Just send the following response back to Slack and the last (ephemeral) message from your app will be deleted:
{
"response_type": "ephemeral",
"replace_original": true,
"delete_original": true,
"text": ""
}
Related
I'm unable to successfully upload a file even using Slacks file.upload tester mechanism here: https://api.slack.com/methods/files.upload
I've applied a Slack app token, channel name, and chosen a file, but get the following result:
{
"ok": false,
"error": "missing_scope",
"needed": "files:write:user",
"provided": "identify,incoming-webhook"
}
I then created a new app, and ensured that files: write was in scope (it wasn't in the previous app). Now, I get a different error:
{
"ok": false,
"error": "not_in_channel"
}
As a test to confirm that the channel name was ok, I subsequently tried a nonexistent channel name, and the error indicated 'channel_not_found', so the channel name I used should be valid.
I had the same issue and fixed it by adding the Slack app to the channel
I guess there are many ways to add it;
I just opened the corresponding channel I was trying to "files.upload" to, and clicked the "Add an app" link at the really top of the channel history:
Before posting a message, reacting to any message or uploading files you need to open a conversation with the channel. You can also do it programmatically and achieve this with the help of API (https://api.slack.com/methods/conversations.open)
You just need to invite the app that you created into the slack channel. Example:
#AppBot
I have observed that, in my message extension bot when I open one-to-one chat with bot, at the top of my chat bar it asks "What can i do?". But when I try to click nothing happens.
Is there any way I can hide that text as its miss leading.
I have tried to update the manifest but it seems its related to some settings.
"What can i do" lists out a set of bot commands to get started with using your bot. You could remove it by removing the commands in the "bots" section from your app manifest.
Do you want the user to be able to interact with the bot at all? If so, do you have any commands in the "commandLists" in your manifest? I actually think this is one of the best features of bots in Teams, if you're creating a normal chat bot, because it gives the user some immediate options, saves them typing, and makes it easier than using LUIS even to check for input.
However, if you don't want any interaction with your bot, then you shouldn't have a "bot" section in your manifest at all. For an app with a message extension only, you need only the "composeExtensions", and don't actually need the "bot" section at all. In this case, the user won't have any chance to 1-1, but that's fine.
To see this, have a look at a sample manifest file:
{
"$schema": "https://developer.microsoft.com/...",
...
"bots": [], <- leave this empty, it is only if you want you user to CHAT with the bot
...
"composeExtensions": [
"botId": Here is where your BotId goes, JUST to handle message extension commands
]
}
Whenever my app posts ephemeral message to Slack channel (in response to a query by a user), I am unable to get the timestamp of my Slack app response. As I want to delete it once the user has made a selection using one of the buttons. Although I have subscribed to 'message.channels' event, I don't get a notification to my app whenever my app posts in the channel (in response to the user input), therefore, I am unable to get the timestamp of the message which I'll use to delete it. All I want is the timestamp of the message posted by my app so that I can delete it but I am unable to receive the timestamp. Please help!
For e.g. in Giphy app for Slack. Let's say the user invokes the app by calling '/giphy [dog]' where 'dog' is just an example of a search term. The app responds by sending a gif and user can either send it, shuffle to the next one or cancel it. I want a similar capability of cancelling the app response but I need the timestamp of the message in order to do so therefore I am asking for help.
Thanks.
Your approach can not work, because Slack is handling ephemeral messages differently from "normal" messages. They are only visible by one user and can not be modified by API methods (e.g. deletion).
But of course its possible to replace ephemeral messages. Here is how:
Your app can just reply to the interactive message request from Slack with a new message. That new message will by default override the original message including ephemeral messages.
You can reply in two ways:
Directly reply to the request from Slack with a message within 3 seconds
Send a message to the response_url from the Slack request within 30 minutes.
See here for the official documentation on how to respond to interactive messages.
This approach works both with interactive messages and slash commands.
See also this answer for a similar situation.
I want my bot to post a message to a user which has a "delete" link to a particular message posted by that user. For e.g.
"Hi #someuser , you have posted an inappropriate message. Click >>here<< to delete it."
When the user clicks on "here" it will open up the slack delete message UI?
I have the message ts and channel ID.
I know i can do this via chat.delete api call (have the link point to my backend and then issue the chat.delete api call).
But i was wondering if there is a way to point user to the "delete message" window via a direct link in the message itself.
You can not add to or change the existing message of another user. Only delete a message (with admin rights).
What you can do though is send the guy a direct message from your app including the link (or button) to delete the message. Just send a message to the user ID of the user via chat.postMessage.
Or you can send the guy an ephemeral message into the channel, that only he will be able to see with chat.postEphermal.
To create a user experience similar to Slack's delete pop-up for messages I would suggest the following:
Include a "Delete" button in your message to the user with the
danger style, so it is shown in red color.
Include a confirmation pop-up with a copy of the message text.
My cross-platform Xamarin Forms app (iOS and Android) needs to send an email (upon request from the user). Right now, when the user presses the appropriate button I'm calling
Page.Navigation.PushAsync(new SendEmailPage)
And then in the SendEmailPage constructor I'm using the DependencyService to send an email:
IMail mail = DependencyService.Get<IMail> ();
mail.SendMessage ("Contents");
I've implemented IMail in both Android and iOS, but looking just at the Android version:
void IMail.SendMessage (string contents)
{
Intent emailIntent = new Intent(Intent.ActionSend);
emailIntent.SetType ("message/rfc822");
emailIntent.PutExtra (Intent.ExtraEmail, new string [] { "me#notreal.com" });
emailIntent.PutExtra (Intent.ExtraSubject, "Subject");
emailIntent.PutExtra (Intent.ExtraText, contents);
Forms.Context.StartActivity (Intent.CreateChooser (emailIntent, "Send email"));
}
When I run this code, and click the appropriate button, it pops up an email "Compose" window with all the appropriate information filled in, and I can click the "send" button to send the mail. Cool!
Side Question: Am I correct in assuming there's no way to send an email "quietly" (without requiring additional user intervention)? This would not be something done maliciously, our app would only do this when the user asked to, and would certainly request the appropriate privileges if this is possible.
Main Question #1: When the "Compose" window comes up, if I click the back button in the title bar, it takes me back to my email Inbox, not back to my application. How do I invoke the email intent/activity in such a way that its back button brings the user back to my app?
Main Question #2: Instead, when the "Compose" window comes up, if I click the back button in the bottom of the screen, it does come back to my app, but tells me "Message saved as draft" which isn't what I want. I would rather have the message deleted, and then re-create it if the user hits the appropriate button again.
For Main Question #1, I believe that starting the activity with
Forms.Context.StartActivityForResult (Intent.CreateChooser (emailIntent, "Send email"));
instead of:
Forms.Context.StartActivity (Intent.CreateChooser (emailIntent, "Send email"));
should work to get you back to your Forms activity. At least in a non-forms app that should work, and I suspect it should in a Form app as well, but not 100% certain.
I can not answer your side question, though I suspect that this is intentional. I am sure you are not intending to do anything malicious and that the user requests the email, but if the OS allowed sending the email without user interaction, developers who are not as ethical as you might abuse the feature. But don't quote me, there may very well be a way to do it, I just don't know how if so.
As for Main Question #2, without changing the behavior of the email client app, I don't see how you could do as you wish as it is the mail client itself that is saving the email as a draft.