Skip to content

app_mention event not triggered when bot posts @mention in a thread via chat_postMessage #1350

@PrajwalNaik07

Description

@PrajwalNaik07

When the bot posts a message containing an @mention of itself in a thread using chat_postMessage, the app_mention event is not triggered.

Reproduction Steps:

The bot listens for the followup button action.
In the action handler, the bot posts a message with an @mention of itself in the same thread, e.g.:

await client.chat_postMessage(
    channel=channel_id,
    text=f"<@{bot_id}> {follow_up_question}",
    thread_ts=ts
)

Expect the app_mention event handler to trigger for this new message.
However, the app_mention event is never triggered.

Expected Behavior:

Posting a new message mentioning the bot (even inside a thread) should trigger the bot’s app_mention event handler.

Actual Behavior:

No app_mention event is received by the bot when the message is posted in a thread.

Environment:

  • slack_bolt==1.23.0
  • slack_sdk==3.36.0
  • Bolt for Python (async)
  • Slack App with necessary permissions and subscriptions
  • Slack workspace where the bot is installed

Notes & Checks performed:

  1. Verified that the bot is subscribed to app_mention events in Slack App's event subscriptions.
  2. Confirmed the bot has app_mentions:read and chat:write scopes.
  3. Tested posting the mention as a top-level message (without thread_ts) — the app_mention event does not trigger
  4. Concluded that Slack does not trigger app_mention events for mentions inside and outside thread replies.

Sample Code

import asyncio
import json

from slack_bolt.async_app import AsyncApp
from slack_bolt.adapter.socket_mode.async_handler import AsyncSocketModeHandler
from slack_sdk import WebClient


Slack_app_token = "xapp..."
Slack_bot_token = "xoxb..."

client = WebClient(token=Slack_bot_token)
app = AsyncApp(token=Slack_bot_token)

@app.event("app_mention")
async def bot_mention(event, body, say, client, logger, ack):
	await ack()
	print("@app_mention done")
	print(body)
	# user_id = event["user"]
	message_channel = event["channel"]
	thread = body['event']['event_ts']
    await client.chat_postMessage(
	channel=message_channel,
	text="Followup block",
	thread_ts=thread,
	blocks=[
		{
			"type": "section",
			"text": {
				"type": "mrkdwn",
				"text": "*Need clarification? Try one of these questions:*\n1. What are some examples of general-purpose EC2 instance types?\n2. How does Compute Optimizer determine right-sizing recommendations?\n3. What happens to my data if I don’t delete the EBS volume before terminating an EC2 instance\n\n*Choose a question below to get started:*"
			}
		},
		{
			"type": "actions",
			"elements": [
				{
					"type": "button",
					"text": {
						"type": "plain_text",
						"text": "Question 1"
					},
					"value": "What are some examples of general-purpose EC2 instance types?",
					"action_id": "followup"
				}
			]
		},
		{
			"type": "actions",
			"elements": [
				{
					"type": "button",
					"text": {
						"type": "plain_text",
						"text": "Question 2"
					},
					"value": "How does Compute Optimizer determine right-sizing recommendations?",
					"action_id": "followup"
				}
			]
		},
		{
			"type": "actions",
			"elements": [
				{
					"type": "button",
					"text": {
						"type": "plain_text",
						"text": "Question 3"
					},
					"value": "What happens to my data if I don't delete the EBS volume before terminating an EC2 instance?",
					"action_id": "followup"
				}
			]
		}
	]
	)

@app.action("followup")
async def followup(event, body, say, client, logger, ack):
	await ack()
	print(f"followup body = {body}")
	bot_id = body['message']['user']
	follow_up_question = body['actions'][0]['value']
	ts = body['message']['ts']
	channel_id=body['channel']['id']

	follow_up_query = f"<@{bot_id}> {follow_up_question}"
	await client.chat_postMessage(
		channel=channel_id,
		text=follow_up_query,
		thread_ts=ts
	)


async def main():
	handler = AsyncSocketModeHandler(app, Slack_app_token)
	await handler.start_async()

if __name__ == "__main__":
	try:
		asyncio.run(main())
	except KeyboardInterrupt:
		print("Keyboard Interruption")

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions