Skip to content

Commit ec6cfb9

Browse files
1shoopermanclaude
andauthored
fix(slack-publish): gracefully handle missing SLACK_BOT_TOKEN with setup guidance (#23)
* fix(slack-publish): gracefully handle missing SLACK_BOT_TOKEN with setup guidance When the bot token is not configured, the publish skill now detects this early and shows step-by-step setup instructions instead of a bare error. Adds main() integration tests covering missing-token, missing-file, and dry-run paths. Closes #18 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(slack-publish): expand test coverage for main, resolve_channel_id, and load_slack_token edge cases Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * refactor(slack-publish): extract token check into agent-token-checker agent Move verify_slackbot_token.py to plugin root scripts/, create agent-token-checker agent, and update publish skill to invoke the agent instead of an inline bash snippet. Adds dedicated test file for verify_slackbot_token (10 tests). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(slack-publish): expand coverage to 75 tests across both test files Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(version): bump slack-publish version --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 9431ff1 commit ec6cfb9

6 files changed

Lines changed: 500 additions & 7 deletions

File tree

plugins/slack-publish/.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
"name": "1shooperman",
66
"email": "contact@aglflorida.com"
77
},
8-
"version": "1.0.0"
8+
"version": "1.0.1"
99
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
name: agent-token-checker
3+
description: Checks whether SLACK_BOT_TOKEN is available (env var or .env file). Returns exit code 0 if found, 1 if missing. Used by the publish skill before attempting to post to Slack.
4+
allowed-tools: [Bash]
5+
model: haiku
6+
---
7+
8+
## Instruction
9+
10+
Run the token checker script and report the result:
11+
12+
```bash
13+
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/verify_slackbot_token.py"
14+
```
15+
16+
- Exit code **0** → token is available. Report: "Token found."
17+
- Exit code **1** → token is missing. Report: "Token missing."
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#!/usr/bin/env python3
2+
"""Exit 0 if SLACK_BOT_TOKEN is available, 1 otherwise."""
3+
4+
from __future__ import annotations
5+
6+
import os
7+
import sys
8+
from pathlib import Path
9+
10+
11+
def find_token() -> str | None:
12+
token = os.environ.get("SLACK_BOT_TOKEN")
13+
if token:
14+
return token
15+
16+
cwd = Path.cwd()
17+
for candidate in [cwd / ".env", cwd / ".env.local"]:
18+
if not candidate.is_file():
19+
continue
20+
for raw in candidate.read_text(encoding="utf-8").splitlines():
21+
line = raw.strip()
22+
if line.startswith("SLACK_BOT_TOKEN="):
23+
value = line.split("=", 1)[1].strip()
24+
if len(value) >= 2 and value[0] == value[-1] and value[0] in {'"', "'"}:
25+
value = value[1:-1]
26+
if value:
27+
return value
28+
return None
29+
30+
31+
def main() -> int:
32+
return 0 if find_token() else 1
33+
34+
35+
if __name__ == "__main__":
36+
sys.exit(main())

plugins/slack-publish/skills/publish/SKILL.md

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,45 @@ Parse `<markdown-file>` and `<channel>` from `$ARGUMENTS`. Both are required —
1616

1717
## Workflow
1818

19-
1. Verify the markdown file exists at the given path.
19+
1. **Check for `SLACK_BOT_TOKEN`** before anything else — use the `slack-publish:agent-token-checker` agent. If it reports "Token missing", **stop here** and show the user this guidance:
20+
If this exits non-zero, **stop here** and show the user this guidance:
2021

21-
2. Run the publisher script, quoting each argument as a discrete shell word to prevent shell injection:
22+
> **`SLACK_BOT_TOKEN` is not set.** To publish to Slack you need a bot token. Here's how to get one:
23+
>
24+
> 1. Go to **https://api.slack.com/apps** and click **Create New App → From a manifest**
25+
> 2. Select your workspace and paste the contents of `slack-app-manifest.yaml` (in the plugin directory)
26+
> 3. Click **Install to Workspace** and copy the **Bot User OAuth Token** (starts with `xoxb-`)
27+
> 4. Invite the bot to your target channel: `/invite @Markdown Publisher`
28+
> 5. Set the token in one of these ways:
29+
> - **Shell environment**: `export SLACK_BOT_TOKEN='xoxb-...'`
30+
> - **`.env` file** in your working directory: `SLACK_BOT_TOKEN=xoxb-...`
31+
> - **Pass at runtime**: re-run with `--env-file /path/to/file.env`
32+
>
33+
> Once the token is set, try again.
34+
35+
2. Verify the markdown file exists at the given path.
36+
37+
3. Run the publisher script, quoting each argument as a discrete shell word to prevent shell injection:
2238
```bash
2339
python3 "${CLAUDE_PLUGIN_ROOT}/skills/publish/scripts/publish_markdown_to_slack.py" \
2440
-- "<markdown-file>" "<channel>"
2541
```
2642

27-
3. If `SLACK_BOT_TOKEN` is not set in the environment, the script will also check `.env` and `.env.local` in the current directory automatically. To use a different token file:
43+
4. To use a different token file:
2844
```bash
2945
python3 "${CLAUDE_PLUGIN_ROOT}/skills/publish/scripts/publish_markdown_to_slack.py" \
3046
-- "<markdown-file>" "<channel>" --env-file "<path>"
3147
```
3248

33-
4. To preview the converted Slack text without posting:
49+
5. To preview the converted Slack text without posting:
3450
```bash
3551
python3 "${CLAUDE_PLUGIN_ROOT}/skills/publish/scripts/publish_markdown_to_slack.py" \
3652
-- "<markdown-file>" "<channel>" --dry-run
3753
```
3854

39-
5. Report success including the resolved channel ID and message timestamp (`ts`).
55+
6. Report success including the resolved channel ID and message timestamp (`ts`).
4056

41-
6. If posting fails, report the exact Slack API error. Common causes:
57+
7. If posting fails, report the exact Slack API error. Common causes:
4258
- Missing token scopes (`chat:write`, `channels:read`, `groups:read`)
4359
- Bot not invited to the destination channel
4460

0 commit comments

Comments
 (0)