Tock message opt-out doesn't seem to work correctly
mgwalker opened this issue · comments
Howdy! How does one discontinue the Charlie bot tock reminders for themselves, anyone here know? I've tried clicking on the three dots and selecting "don't show again" but they persist.
https://gsa-tts.slack.com/archives/C041X137T/p1645560627032939
So this is the button:
And searching for that button text only takes me to optOut.test.js. I'm finding it odd it's in the test but not anywhere in the actual source? Update: Hmm, it's in optOut.js too. not sure why that didn't pull up in search. Update: Never mind, apparently my local copy was out of date and doesn't seem to be in optOut.js anymore? 🤔
But the general idea is when the message is posted, we add in a button to the block response, then there's a way to have the Charlie API respond to that. The documentation of the process is on Slack's API for app interactivity. I've played with this some at the last job. I can look into it a bit more here soon.
We should check whether Eleni was getting messages from Optimistic Tock or Angry Tock. One possible sequence of events that would produce an apparent bug as described:
- get a message from Optimistic Tock
- click the "Don't show me this anymore" button
- get a message from Angry Tock
The two Tock reminders are completely separate and opting out of Optimistic Tock doesn't do anything to Angry Tock. Angry Tock currently can't be opted-out, which is by design. Though it might be worth checking whether that's still the right behavior. Tocking on time used to be very important, and maybe it's not as critical anymore.
As far as how opting out works, optOut.js
is a utility for creating the little button, handling the click event for that button, and allowing scripts to query whether a user is opted out. The utility exposes one function:
optOut(key: string) => object
The key
is a unique identifier for the script that is using the opt-out utility. It's used as a key in Charlie's brain (a SQL database) to track which users have clicked the opt-out button for that particular script.
The utility returns an object that looks roughly like this:
{
button: { ... }
isOptedOut(userId) => boolean
}
The button
property contains a Slack block that creates the 3-button context menu and the "Don't show me this anymore" button. The block is preconfigured so it will be handled by the opt-out.js
script (more below), so the calling script doesn't have to handle block interaction.
The isOptedOut()
property is a function that will tell you whether a given user ID has opted-out of the script, based on the key
passed in when calling the utility function above.
The optOut.js
utility itself doesn't handle any interactivity. It just creates the Slack block and provides the helper for identifying opted-out users. The block is created with an action_id
that identifies the type of button (in case other Slack scripts also have buttons, you can tell them apart), and a value
that identifies the script associated with this opt-out.
Interactivity is handled by the opt-out.js
script, which registers a Slack action handler. When the button is clicked, Slack sends Charlie an action
event. The event includes the action_id
and value
that were set when the block was created along with the user_id
of the user that clicked it. The Bolt SDK uses the action_id
to decide which of Charlie's action
event handlers to call. Once the opt-out.js
handler is called, it further uses the value
to identify which script is being opted out of and the user_id
to know which user.
There's some technical documentation that probably ought to live somewhere... 😬
It was optimistic tock