Skip to content

Commit 40bc711

Browse files
danishiclaude
andauthored
Add direct message support by refactoring message handling (#13)
* Add DM (direct message) support Extract shared message handling logic into _handle_message() and add a new "message" event handler that responds to DMs (channel_type "im"). Bot messages and message subtypes are ignored to prevent loops. https://claude.ai/code/session_01FkbkMoaxVNyJqsgAo2uTwm * Update README to document DM support https://claude.ai/code/session_01FkbkMoaxVNyJqsgAo2uTwm --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 401dd5c commit 40bc711

2 files changed

Lines changed: 24 additions & 9 deletions

File tree

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ If you want to use the [Google Gen AI SDK](https://googleapis.github.io/python-g
1111
If you want a simpler, lightweight Slack bot without the ADK framework, check out [Nano Banana](https://github.com/danishi/slack-nano-banana-bot-on-google-cloud)🍌
1212

1313
## Features
14-
- Responds to `@mention` messages in Slack channels.
14+
- Responds to `@mention` messages in Slack channels and direct messages (DMs).
1515
- Supports text, image, PDF, text file, video, and audio inputs from Slack messages. Files are fetched via authenticated URLs and sent to Gemini for multimodal understanding.
1616
- **Web search** via `web_search_agent` (Google Search) and `url_fetch_agent` (URL content retrieval) using `AgentTool`. Allows the bot to look up live web information and fetch page content on demand.
1717
- **Image generation** via `generate_image` tool using Gemini image generation models:
@@ -102,8 +102,8 @@ The Agent Development Kit includes a built-in web-based Development UI that you
102102
- `users:read`
103103
3. Install the app to your workspace to obtain `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET`.
104104
4. Enable **Event Subscriptions** and set the Request URL to `https://<your-cloud-run-service-url>/slack/events`.
105-
5. Subscribe to bot events: `app_mention`.
106-
6. Invite the bot to channels where you want to use it.
105+
5. Subscribe to bot events: `app_mention`, `message.im`.
106+
6. Invite the bot to channels where you want to use it. For DMs, simply open a direct message with the bot.
107107

108108
## Deploy to Cloud Run
109109
The repository includes a helper script to build the container and deploy to Cloud Run. Ensure your `.env` contains `SLACK_BOT_TOKEN` and `SLACK_SIGNING_SECRET` before running:

app/main.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,12 +218,8 @@ def _build_slack_blocks_from_text(text: str) -> List[dict]:
218218
] or [{"type": "section", "text": {"type": "mrkdwn", "text": ""}}]
219219

220220

221-
@bolt_app.event("app_mention")
222-
async def handle_mention(body, say, client, logger, ack):
223-
# Ack as soon as possible to avoid Slack retries that can cause duplicated responses
224-
await ack()
225-
226-
event = body["event"]
221+
async def _handle_message(event, say, client, logger):
222+
"""Shared handler for both app_mention and DM message events."""
227223
channel = event["channel"]
228224
message_ts = event["ts"]
229225
thread_ts = event.get("thread_ts") or message_ts
@@ -305,6 +301,25 @@ async def handle_mention(body, say, client, logger, ack):
305301
pass
306302

307303

304+
@bolt_app.event("app_mention")
305+
async def handle_mention(body, say, client, logger, ack):
306+
await ack()
307+
await _handle_message(body["event"], say, client, logger)
308+
309+
310+
@bolt_app.event("message")
311+
async def handle_direct_message(body, say, client, logger, ack):
312+
await ack()
313+
event = body["event"]
314+
# Only handle DMs (channel_type "im"), skip other message events
315+
if event.get("channel_type") != "im":
316+
return
317+
# Ignore bot's own messages and message subtypes (edits, joins, etc.)
318+
if event.get("bot_id") or event.get("subtype"):
319+
return
320+
await _handle_message(event, say, client, logger)
321+
322+
308323
@fastapi_app.post("/slack/events")
309324
async def slack_events(req: Request):
310325
retry_num = req.headers.get("x-slack-retry-num")

0 commit comments

Comments
 (0)