Detecting when Slack ephemeral message disappears - slack

I have a Slack command bot that posts ephemeral messages and lets the user decide whether they want to make the message visible to everyone else in the channel ('Send') or delete the message ('Cancel'). Since Slack API doesn't provide the original message when user interacts with an ephemeral message, I have to store original messages in Redis, retrieve them when user interacts with the posted message and delete the key from Redis afterwards. The one thing I'm worried about is clogging up Redis with keys that will never be deleted because user never interacts with the message (in other words, doesn't tap on any of the buttons, just leaves the message as is and walks away).
Does Slack API provide any way of knowing when ephemeral messages get deleted so I can clean up Redis? Or is there a better way to solve this problem in general?

No - Slack has no mechanism to inform your app when an ephemeral message vanished. In general they will live until the user refreshes the page on his browser (in the web version).
But I can offer an alternative solution to storing all messages on redis:
Since you created the initial ephemeral message you should be able to always recreate that same message later if you know the exact functional context (e.g. User ID).
All you need to do is to store an ID linking to its context in the buttons of your first message. If the user clicks on the buttons the Slack request will include those IDs, which allows you to identify its context, e.g. take the proper action or recreate the same message for sending to the whole channel.
You can use the name or value field of an action for storing IDs. (See also this answer.)
That ID can either represent the instance of an object (e.g. a customer), so you can fetch that object from your DB again or it can be the ID of your server session, which enables you to work with server session and keep all the context data in the server session. (see also this answer).

Related

Backend table structure and process to support individual notifications, item notifications, and topic notifications

I want my app to have 3 different kinds of notifications which the user has the option to opt into each but I need to support all of them on the backend I think. I wanted to see if others had an approach which worked well for them. The three notification types are different:
Individual Notifications - A specific user related notification. When a specific event happens in their account they (and their team members) get notified of it.
Item Notifications - An item specific notification. Any user of the system can get notified when a specific item available to all reaches a certain stage of the process.
Topic Notifications - General system event, to be sent to anybody who has opted into receiving notifications for a system event.
If I am going to support badges for each, I need to track them by user I suppose, in order to send down the badge number with the notification. The icon would be the aggregation of each. I am thinking I need three Toggle settings, one for each. When the user sets each one, I would send a registration for that type of notification to a webapi which would store the user id in a registration table along with the registration type.
When sending the registration to the user, the registration table gets queried, a record goes into the notification_view table for that user and notification type, and the badge count is taken from that and sent to apns.
When the user views a notification, I will send a message to the api and update (or remove) the notification_view record associated with he viewed notification.
I know there are ways to have filter a notification, and I expect this will be incorporated. I'm using Azure NotificationHubs and this would be included under tags. So if a device had a tag (sports_news or something like that) the server side could send a notification with a sports_news tag and it would go to everybody who subscribed to it. That might work for category #3 above, provided we do not care about badge counts.
Is anybody else doing something like this? Do you use the same type of backend tables to support the process? Does my process mirror what you are doing?

Slack API - persistent message visible only to a set of users in a public channel

I'm planning to write a slack app, and I need to render messages depending on who read them.
I'm thinking something like: the App should have some options, and user's clients should render the messages depending on the options chosen by the user.
Is there a way to post a persistent message (I mean not an ephemeral message) which is shown only to a user (or a set of users)?
Or
Is it possible to post a message shown differently depending on the user who read it?
I don't need to send private or sensitive data, so if the solution to my problem is a message containing all the content for all the users in the channel, it is perfectly fine. It's just matter of user experience.
I have two constraints:
The user experience for those who don't use the App should not be impacted
I need the messages from the App to be rendered in reply to messages sent by the users, so solutions like "open a new channel" or "send direct messages" are not suitable for my needs.
Thank you all (but the Slack team which, in case let us doing that, it makes that not clear in the documentation :D )
This is not possible unless you create your own client to show/display the messages.
Custom slack apps usually augment to the existing functionality. How do you expect to override the functionality of Native Slack 'Desktop, Mobile & Web' Client.
I am happy to discuss this further, if you have some approach in mind.

Unable to get timestamp of the message posted by Slack App

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.

Slack logon trigger

I want to create something in Slack that sends a message (starting by calling someone with '#') to a channel when specific users login. I've checked ifttt and zapier. I also checked the slack api to create something myself, but I couldn't really find anything usefull.
Anyone has any ideas?
Slack does not track user login or logoff in a traditional sense. Instead, users are always always "logged in" and available to receive messages once they have joined a team / channel.
There also is the concept of "presence", which is related, but not the same thing. User presence can change multiple times during a few minutes, e.g. if the user is on a mobile. I am guessing you would not want to send the user your message that often.
Still you can poll the presence information of a user with the API users.getPresence , which could be used to implement a script that polls this information on a regular basis and send your message. You also want to filter out presence changes below a certain duration threshold.
Keep in mind though that the rate limit for API methods is 1 per second. So depending on how many users you have in your workspace there will be a significant delay between the user becoming "present" and your script being able to send the message.
There is a workaround for that to have a google sheet as a database for the users and you can trigger by day once and timestamp it.
So the best trigger is a private message or public and you can use filter when mentioning or signin or signout it depends on the trigger word then you pass the filter since zapier won't count your zaps if you used fiter as a second step.

It's possible to list subscribers in autobahn.ws?

Currently I'm developing consoles in my webapp displaying user's running *nix application log (game servers) and I just want to make sure that one user can't access other user console by guessing topic name.
I'm using random generated string of 16 chars 0-9, A-Z, a-z, changing on every refresh of page, valid for 30min for each topic name.
Every user of webapp in crossbar config have access to subscribe any topic.
I wanted to set for each user to only subscribe to his/hers console topic but I think that dynamic config for crossbar is not yet implemented.
Is this implementation is enough for privacy of users or it's possible for subscriber to list other subscibers and my work with unique topic names is pointless?
It is indeed possible for subscribers to list other subscribers - via subscription meta-procedures.
Regarding your topic structure - you're doing something like
com.myapp.userlog.user34KUIK567878
com.myapp.userlog.userAHH78738J899
and want to prevent users from being able to subscribe to any channel but their own?
For this you can use a dynamic authorizer - see http://crossbar.io/docs/Authorization/
The dynamic authorizer is called on each subscription (& publish, call, register) request and can then accept or reject this request. It has access to the session data so that you can identify the user.

Resources