I'm using the 'slack-node' npm package to build a simple Slack App for my team. The initialization of the bot works great so far. I got it to post a message to a channel after using a custom slash command. This message contains an interactive button, which after the user pressed on it, the message should update.
From my log:
// User uses /event slash command
18:48:50 UTC - - Received [POST] to path [/event]
// API response after posting the message
{ ok: true, message_ts: '1506538130.000343' }
// Incoming request after user pressed the button
18:49:32 UTC - - Received [POST] to path [/button_reply]
// Extracted channel id and message ts
C3PEQESP5 1506538130.000343
// respond after using chat.update
{ ok: false, error: 'message_not_found' }
I made sure I am passing the correct channel ID and message ts, i am 100% sure these parameters are correct since you only have to compare the response (objects).
This is the package I am using: https://www.npmjs.com/package/slack-node
Here is the code snippet I am using:
module.exports = {
postEphemeral : function(text, body, callback) {
slack.api('chat.postEphemeral', {
attachments:JSON.stringify(text.attachments) ,
channel:body.channel_id,
user:body.user_id
}, function(err, response){
console.log(response);
return callback(null);
});
},
updateMessage : function(text, body, callback) {
console.log(body.channel.id, body.message_ts)
slack.api('chat.update', {
attachments:JSON.stringify(text.attachments) ,
channel:body.channel.id,
ts:body.message_ts
}, function(err, response){
console.log(response);
return callback(null);
});
}
}
I think the slack-node package uses the web-api from slack but not sure. According to Slack 'message_not_found' means No message exists with the requested timestamp, which is not true, the message is right there.
Does anyone had the same/similar problem before ?
Thanks for any advice.
I can confirm the chat.postEphemeral
generates messages that cannot be updated :
curl -X POST 'https://slack.com/api/chat.postEphemeral?token=xoxp-mytoken&channel=C143CVGRE&text=blabla&user=U334D3FFF&pretty=1'
{
"ok": true,
"message_ts": "1506544109.000059"
}
Then :
curl -X POST 'https://slack.com/api/chat.update?token=xoxp-mytoken&channel=C143CVGRE&text=updated&ts=1506544109.000059&pretty=1'
{
"ok": false,
"error": "channel_not_found"
}
Whereas, messages sent with chat.postMessage
can be :
curl -X POST 'https://slack.com/api/chat.postMessage?token=mytoken&channel=C143CVGRE&text=blabla&pretty=1'
{
"ok": true,
"channel": "C143CVGRE",
"ts": "1506544023.000474",
"message": {
"text": "blabla",
"username": "Slack API Tester",
"bot_id": "B4X35D333",
"type": "message",
"subtype": "bot_message",
"ts": "1506544023.000474"
}
}
Then :
curl -X POST 'https://slack.com/api/chat.update?token=mytoken&channel=C143CVGRE&text=updated&ts=1506544023.000474&pretty=1'
{
"ok": true,
"channel": "C143CVGRE",
"ts": "1506544023.000474",
"text": "updated",
"message": {
"text": "updated",
"username": "Slack API Tester",
"bot_id": "B4X35D333",
"type": "message",
"subtype": "bot_message"
}
}
I think it's just because of the very nature of ephemeral messages, that are directed to an end user in a channel and are not persistent. Quoted from https://api.slack.com/methods/chat.postEphemeral :
Ephemeral message delivery is not guaranteed — the user must be
currently active in Slack and a member of the specified channel. By
nature, ephemeral messages do not persist across reloads, desktop and
mobile apps, or sessions.
Hope this helps!
Another way to update bot messages after user pressed a button (interactive messages). You can use the response_url
that's also included in the payload coming from the button-push. Just make another POST
request to this response_url
just like you would post a simple message.
This works with ephemeral
messages as well !
var response_url = body.response_url;
var options = {
url: response_url,
method: 'POST',
body: JSON.stringify(text)
}
request(options,function(err, response, body) {
// Continue doing stuff
});
Reading this (https://api.slack.com/interactive-messages) there might also be an additional parameter you could use (although I don't know when and how) : "replace_original": true
, but haven't tried that yet.