This repository provides a Slack bot backend implemented in Python that uses Slack Bolt and Google Cloud's Gemini Enterprise Agent Platform (formerly Vertex AI) Gemini model via the Agent Development Kit. The bot responds to text, images, PDFs, plain text files, videos, and audio messages, while maintaining conversation context within Slack threads. It is designed to run on Cloud Run.
If you want to use the Google Gen AI SDK, please refer to this repository๐ก
If you want a simpler, lightweight Slack bot without the ADK framework, check out Nano Banana๐
- Powered by Gemini Enterprise Agent Platform (formerly Vertex AI) Gemini via the ADK. Verified working with
gemini-3.5-flash(the defaultMODEL_NAME); any other Gemini model can be used by settingMODEL_NAME. - Responds to
@mentionmessages in Slack channels and direct messages (DMs). - 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.
- Web search via
web_search_agent(Google Search) andurl_fetch_agent(URL content retrieval) usingAgentTool. Allows the bot to look up live web information and fetch page content on demand. - Image generation via
generate_imagetool using Gemini image generation models:gemini-3-pro-image(Nanobanana Pro) โ higher qualitygemini-3.1-flash-image(Nanobanana 2) โ faster generation- Generated images are automatically uploaded to the Slack thread.
- Maintains conversation context by retrieving prior messages in a thread and sending them as conversation history to Gemini.
- MCP integration sample via
mock_service_agent, which reaches an external service over the Model Context Protocol. The bundledmcp_servers/mock_service_server.pywraps the public JSONPlaceholder mock API as a read-only user directory โ swap the base URL and tools for your own backend to build a real integration. - Access control via Slack workspace, user, and bot allowlists (
ALLOWED_SLACK_WORKSPACE,ALLOWED_SLACK_USERS,ALLOWED_SLACK_BOTS). Empty user/bot lists mean "allow everyone / no bots". - Invocable by other bots (e.g. Slackbot) when allowlisted, which enables scheduled/periodic runs triggered by Slack reminders.
- Formats responses using Slack-compatible Markdown for rich text output.
- FastAPI-based web server suitable for Cloud Run.
- Deployment script for building and deploying to Cloud Run.
@mentionthe bot in a channel or DM it to ask questions, hand it images/PDFs/audio for multimodal understanding, summarize a thread (the bot attributes statements by speaker), search the web, fetch a URL, or generate images.- Ask it to look up people ("list the users", "what's user 2's email?") and it delegates to the MCP-backed
mock_service_agent.
Because the bot can be invoked by an allowlisted bot, you can drive it on a schedule with a plain Slack reminder โ no extra cron infrastructure required. When a reminder fires, Slackbot posts the reminder text into the channel; if that text @mentions the bot, an app_mention event reaches your service and the agent runs.
Setup:
- Add Slackbot's user ID,
USLACKBOT, toALLOWED_SLACK_BOTS(it is in.env.exampleby default). Without this the bot ignores messages posted by Slackbot. - Make sure the bot is a member of the target channel.
- Create a recurring reminder whose text mentions the bot, for example:
/remind #ops "@YourBot Summarize the open incidents and post the highlights" every weekday at 9:00 - At each scheduled time Slackbot posts the reminder, the bot is mentioned, and the agent generates and posts its reply in the thread.
This pattern works for any recurring agent task โ daily standup prompts, morning digests, periodic data lookups through the MCP service, and so on. Slack scheduled messages and Workflow Builder can be used the same way as long as the posted message @mentions the bot and the posting identity is allowlisted.
app/
main.py # FastAPI app, Slack Bolt handlers, access control, agent wiring
agents/
comedian.py # ex: Comedian agent implementation
web_search_agent.py # ex: Web search & URL fetch agents (AgentTool)
mock_service_agent.py # ex: MCP-backed user directory sub-agent
tools/
generate_image.py # ex: Image generation tool (Nanobanana Pro / Nanobanana 2)
get_current_datetime.py # ex: Date/time utility tool
skills/
greeting-skill/ # ex: Greeting skill (file-based ADK Skill)
SKILL.md
references/
greeting_templates.md
datetime-skill/ # ex: Datetime skill (file-based ADK Skill)
SKILL.md
references/
default_timezones.md
mcp_servers/
mock_service_server.py # ex: MCP server wrapping the JSONPlaceholder mock API
scripts/
deploy.sh # Helper script to deploy to Cloud Run
Dockerfile # Container definition for Cloud Run
requirements.txt # Python dependencies
llms.txt # ADK documentation for LLM reference
llms-full.txt # Extended ADK documentation for LLM context
- Python 3.14
- Google Cloud SDK with
gcloudauthenticated - Slack workspace admin privileges
- Install dependencies
python -m venv venv source venv/bin/activate pip install -r requirements.txt - Configure environment variables
cp .env.example .env # edit .env and set your Slack and Google Cloud credentials # ALLOWED_SLACK_WORKSPACE is the Slack team ID to allow requests from # ALLOWED_SLACK_USERS / ALLOWED_SLACK_BOTS gate who can invoke the bot (see Access Control)
- Run the server
uvicorn app.main:fastapi_app --host 0.0.0.0 --port 8080 --reload
- Use a tunneling tool like
ngrokto exposehttp://localhost:8080/slack/eventsto Slack during development.
The Agent Development Kit includes a built-in web-based Development UI that you can run locally. It's a powerful tool for testing, debugging, and interacting with your agent during development. It provides a chat interface to send messages to your agent and inspect the results.
-
Start the ADK web server:
gcloud auth application-default login adk web
-
Interact with your agent: Open the local URL (usually
http://127.0.0.1:8000) in your browser to use the Development UI.
- Create a new Slack app at https://api.slack.com/apps.
- Under OAuth & Permissions, add the following Bot Token scopes:
app_mentions:readchat:writechannels:historygroups:historyim:historympim:historyfiles:readfiles:writereactions:writeusers:read
- Install the app to your workspace to obtain
SLACK_BOT_TOKENandSLACK_SIGNING_SECRET. - Enable Event Subscriptions and set the Request URL to
https://<your-cloud-run-service-url>/slack/events. - Subscribe to bot events:
app_mention,message.im. - Invite the bot to channels where you want to use it. For DMs, simply open a direct message with the bot.
Three independent, optional allowlists gate who can reach the bot:
| Variable | Empty / unset behavior | When set |
|---|---|---|
ALLOWED_SLACK_WORKSPACE |
Allow all workspaces | Only accept events from the given Slack team ID (others get HTTP 403) |
ALLOWED_SLACK_USERS |
Allow all human users | Comma-separated user IDs; only listed humans may invoke the bot |
ALLOWED_SLACK_BOTS |
No bots allowed (bot messages ignored) | Comma-separated bot user IDs (e.g. USLACKBOT) that may invoke the bot |
Notes:
- A disallowed human user gets a permission-denied reply (in-thread) so they know why the bot is not responding. Customize it with
ACCESS_DENIED_MESSAGE(empty = built-in default). - Disallowed bots (anything carrying a
bot_id, including Slackbot and the bot's own replies) are ignored silently to avoid reply loops and channel noise. - The bot's own messages carry a
bot_idand are never allowlisted, so reply loops are prevented automatically. ALLOWED_SLACK_BOTSis what makes scheduled execution via Slack reminders possible โUSLACKBOTposts reminder messages, so it must be listed.- To find a user ID, open the member's profile โ โฎ โ Copy member ID, or call the Slack API:
curl -s -H "Authorization: Bearer $SLACK_BOT_TOKEN" \ "https://slack.com/api/users.list" | jq '.members[] | {id, name, real_name: .profile.real_name}'
mock_service_agent demonstrates how to connect the bot to an external service through the Model Context Protocol:
mcp_servers/mock_service_server.pyis a FastMCP server, started by ADK'sMcpToolsetas a stdio subprocess (python -m mcp_servers.mock_service_server).- It exposes two read-only tools โ
list_usersandget_user(user_id)โ backed by the public JSONPlaceholder mock API (/usersand/users/{id}). - The backend URL is hardcoded as the
MOCK_API_BASE_URLliteral at the top ofmock_service_server.py.
To turn this into a real integration, change that MOCK_API_BASE_URL literal to your own service and replace the tool implementations in mock_service_server.py (add auth, write operations, etc.).
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:
Enable the Cloud Build API for your project:
gcloud services enable cloudbuild.googleapis.comThen deploy:
./scripts/deploy.shThe script will:
- Build the container image using Cloud Build.
- Deploy the image to Cloud Run.
- Set the required environment variables on the service.
After deployment, configure the Slack app's event subscription URL to the Cloud Run service URL.