From f8fcdb779b4869c26edd60e6a8a0f375e166aa54 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 14 Jul 2026 16:47:29 -0700 Subject: [PATCH 1/3] feat(methods): add chat.postMessage example (typecheck-only) Add a methods/ chat.postMessage example verified by ruff + mypy, with no runtime test. slack_sdk's chat_postMessage has typed keyword arguments, so mypy catches wrong types, missing required args, and misspelled arguments (e.g. chnnel -> "Missing named argument channel") without a mock server. This is an alternative to the mock-server runtime-test approach for side-by-side comparison. Co-Authored-By: Claude --- README.md | 1 + methods/.gitignore | 5 +++++ methods/README.md | 20 ++++++++++++++++++++ methods/requirements.txt | 3 +++ methods/src/__init__.py | 0 methods/src/chat/__init__.py | 0 methods/src/chat/chat_post_message.py | 27 +++++++++++++++++++++++++++ 7 files changed, 56 insertions(+) create mode 100644 methods/.gitignore create mode 100644 methods/README.md create mode 100644 methods/requirements.txt create mode 100644 methods/src/__init__.py create mode 100644 methods/src/chat/__init__.py create mode 100644 methods/src/chat/chat_post_message.py diff --git a/README.md b/README.md index 5a58c76..8fe0a2e 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,4 @@ This collections of examples highlights features of a Slack app in the language - **[AI in Slack](./ai)**: Agent experiences and MCP features in an interactive conversation interface. - **[Block Kit](./block-kit)**: The framework of visual components arranged to create app layouts. +- **[Methods](./methods)**: Individual Slack Web API method calls with the `slack_sdk` `WebClient`. diff --git a/methods/.gitignore b/methods/.gitignore new file mode 100644 index 0000000..4a797c4 --- /dev/null +++ b/methods/.gitignore @@ -0,0 +1,5 @@ +__pycache__ +.mypy_cache +.pytest_cache +.ruff_cache +.venv diff --git a/methods/README.md b/methods/README.md new file mode 100644 index 0000000..77dfd18 --- /dev/null +++ b/methods/README.md @@ -0,0 +1,20 @@ +# Methods + +Individual Slack Web API method calls with the `slack_sdk` `WebClient`. + +Read the [docs](https://docs.slack.dev/reference/methods) to explore every method, or explore implementations of specific families. + +## What's on display + +### chat + +- **[chat.postMessage](https://docs.slack.dev/reference/methods/chat.postmessage)**: Sends a message to a channel. [Implementation](./src/chat/chat_post_message.py). Scopes: `chat:write`. + +## Running an example + +Set a bot token and run an example module directly: + +```sh +export SLACK_TOKEN="xoxb-your-token" +python -m src.chat.chat_post_message +``` diff --git a/methods/requirements.txt b/methods/requirements.txt new file mode 100644 index 0000000..1768855 --- /dev/null +++ b/methods/requirements.txt @@ -0,0 +1,3 @@ +mypy==2.3.0 +ruff==0.15.21 +slack_sdk==3.43.0 diff --git a/methods/src/__init__.py b/methods/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/methods/src/chat/__init__.py b/methods/src/chat/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/methods/src/chat/chat_post_message.py b/methods/src/chat/chat_post_message.py new file mode 100644 index 0000000..ffaaabb --- /dev/null +++ b/methods/src/chat/chat_post_message.py @@ -0,0 +1,27 @@ +import os + +from slack_sdk import WebClient +from slack_sdk.web import SlackResponse + + +def example01(client: WebClient) -> SlackResponse: + """ + Sends a message to a channel. + https://docs.slack.dev/reference/methods/chat.postmessage + """ + # Call the chat.postMessage method using the WebClient + response = client.chat_postMessage( + channel="C123ABC456", + text="Here's a message for you", + ) + return response + + +if __name__ == "__main__": + # Read a token from the environment variables + token = os.environ.get("SLACK_TOKEN") + + # Initialize a WebClient with the given token + client = WebClient(token=token) + + print(example01(client)) From 524db5d32403308cd82f1993bcc61121f9c69fa6 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Tue, 14 Jul 2026 16:57:02 -0700 Subject: [PATCH 2/3] ci: run methods showcase; tolerate no-test showcases Add methods to the CI matrix and treat pytest exit code 5 ("no tests collected") as success, so the type-check-only methods example (which has no tests) passes CI while still running ruff and mypy. Real test failures (exit 1) still fail the build. Co-Authored-By: Claude --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 434ef3a..6141479 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,7 @@ jobs: - "ai/slackbot-mcp-client/rich-responses/mcp-apps" - "ai/slackbot-mcp-client/slack-identity" - "block-kit" + - "methods" steps: - name: Checkout code uses: actions/checkout@v7 @@ -30,4 +31,5 @@ jobs: ruff check ruff format --diff --check mypy ./**/*.py - pytest -v + # Exit code 5 = "no tests collected" (e.g. type-check-only showcases); treat as success. + pytest -v || [ $? -eq 5 ] From 5a7ac6cf0350c2b8ade91ed9279432d46164735a Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 15 Jul 2026 00:21:17 -0700 Subject: [PATCH 3/3] feat(methods): add per-family manifest; align README copy Match the runtime branch: add a chat manifest.json requesting only chat:write, move the scope out of the README into the manifest, and use the method's exact docs description. Co-Authored-By: Claude --- methods/README.md | 4 ++-- methods/src/chat/manifest.json | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 methods/src/chat/manifest.json diff --git a/methods/README.md b/methods/README.md index 77dfd18..07f419a 100644 --- a/methods/README.md +++ b/methods/README.md @@ -8,11 +8,11 @@ Read the [docs](https://docs.slack.dev/reference/methods) to explore every metho ### chat -- **[chat.postMessage](https://docs.slack.dev/reference/methods/chat.postmessage)**: Sends a message to a channel. [Implementation](./src/chat/chat_post_message.py). Scopes: `chat:write`. +- **[chat.postMessage](https://docs.slack.dev/reference/methods/chat.postmessage)**: Sends a message to a channel. [Implementation](./src/chat/chat_post_message.py). ## Running an example -Set a bot token and run an example module directly: +Each family ships a [`manifest.json`](./src/chat/manifest.json) requesting only the scopes it needs (`chat` → `chat:write`). Create an app from it, then set a bot token and run an example module directly: ```sh export SLACK_TOKEN="xoxb-your-token" diff --git a/methods/src/chat/manifest.json b/methods/src/chat/manifest.json new file mode 100644 index 0000000..ad13ee2 --- /dev/null +++ b/methods/src/chat/manifest.json @@ -0,0 +1,22 @@ +{ + "display_information": { + "name": "Slack API Methods", + "description": "Example implementations to call \"chat\" methods" + }, + "features": { + "bot_user": { + "display_name": "Slack API Methods", + "always_online": true + } + }, + "oauth_config": { + "scopes": { + "bot": ["chat:write"] + } + }, + "settings": { + "org_deploy_enabled": true, + "socket_mode_enabled": false, + "token_rotation_enabled": false + } +}