How to get a thread reply's content from reaction_added event?
Asked Answered
K

2

6

I'm building a slack FAQ app that uses message reactions to gather the best answers to questions. My plan is to save any Slack messages with positive reactions by using the reaction_added event to get the TS attribute and then the conversations.history method to get the message's content.

This works well for parent-level or non-threaded messages, however it doesn't work for reply messages inside threads. For some reason the conversations.history method returns an unrelated message when using the TS of a thread reply.

I've checked the Slack API conversations.history method documentation to see if replies are handled in any special way. I reviewed conversations.replies method to see if it might be helpful, but since reaction_added event simply provides a TS id for the message and no thread_ts value that can be used with the conversations.replies method.

I'm using bolt framework. Here's a snippet of the code that tries to use the reaction_added event with conversations.history method to get the message content:

app.event('reaction_added', async ({ event, context, say }) => {
  try {
    const result = await app.client.conversations.history({
      token: process.env.SLACK_USER_TOKEN,
      channel: event.item.channel,
      latest: event.item.ts,
      limit: 1,
      inclusive: true
    });
    save(`${result.messages[0].text}`);
  }
  catch (error) {
    console.error(error);
  }
});

Expected result: Message contents of thread reply that a reaction is posted for

Actual result: Message contents of the latest message in the slack channel

Kajdan answered 19/10, 2019 at 14:9 Comment(5)
Possible duplicate of I want to find thread message and delete it with slack-apiWitham
The difference is this question is specifically asking for advice in finding a thread message when all you have a reaction_added event, which doesn't provide the required thread_ts attribute for finding a thread message.Kajdan
You are right. Just repeated your example and the reaction_added event does not include the thread_ts property, which you would need to identify the related message in a thread. Looks like a missing feature to me, so I would suggest opening as support request to Slack about this.Witham
Thanks, I did. I'll continue looking for workarounds too and post here if I find something.Kajdan
I also contact Slack support about this. I think it would be trivial for them to add it so I hope they can.Osteopathy
K
3

I'm not sure if it changed recently or I misread the documentation, but conversations.replies API endpoint does not require a thread_ts value containing the parent thread timestamp in order to retrieve a thread reply.

The event.item.ts value provided by the reaction_added event is sufficient to retrieve the message contents of the reply where a reaction was added.

So to get the message contents of a message where a reaction was added, you can update the code in my original question to:

app.event('reaction_added', async ({ event, context, say }) => {
  try {
    const result = await app.client.conversations.replies({
      token: process.env.SLACK_USER_TOKEN,
      channel: event.item.channel,
      ts: event.item.ts
    });
    save(`${result.messages[0].text}`);
  }
  catch (error) {
    console.error(error);
  }
});
Kajdan answered 2/12, 2019 at 19:37 Comment(0)
T
0

I was trying to get the content of the message (child message in a thread) the user reacted to and it kept returning the parent. in the end this was the solution that worked for me. https://github.com/slackapi/bolt-js/issues/1341#issuecomment-2163463635

Pasting the code here just in case:

import { WebClient } from '@slack/web-api'

async function getMessage(
  client: WebClient,
  channel: string,
  ts: string,
  thread_ts?: string
) {
  if (!thread_ts || thread_ts === ts) {
    return client.conversations.history({
      channel,
      oldest: ts,
      inclusive: true,
      limit: 1,
    })
  }
  return client.conversations.replies({
    channel: channel,
    oldest: ts,
    ts: ts,
    inclusive: true,
    limit: 1,
  })
}

app.event('reaction_added', async ({ event, client }) => {
  const { item, reaction } = event
  const permalinkMessage = await client.chat.getPermalink({
    channel: item.channel,
    message_ts: item.ts,
  })
  if (!permalinkMessage) {
    console.log('could not locate message (permalink)')
    return
  }
  const { permalink } = permalinkMessage
  const permalinkUrl = new URL(permalink)
  const thread_ts = permalinkUrl.searchParams.get('thread_ts')
  const response = await getMessage(client, item.channel, item.ts, thread_ts)
  const { messages } = response
  const message = messages.pop()
  console.log(message)
})
Tuttle answered 20/8, 2024 at 3:39 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.