Slack API - chat.update : “message_not_found”

2019-05-03 09:39发布

问题:

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.

回答1:

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!



回答2:

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 POSTrequest 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.