Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,23 @@ than most of your human colleagues 😏
4. Copy the `Bot User OAuth Access Token` and add it to your environment as `SLACK_BOT_TOKEN`.
5. Create a new `App-Level Tokens` under `Basic Infomation` and add it to your environment as `SLACK_APP_TOKEN`.

### User Whitelisting (Optional)

Sam supports user whitelisting to restrict who can interact with the bot. This is useful for controlling access in larger Slack workspaces.

To enable whitelisting:
1. Add the `WHITELISTED_USERS` environment variable to your `.env` file
2. Set it to a comma-separated list of Slack user IDs
3. Example: `WHITELISTED_USERS=U1234567890,U0987654321,U1122334455`

**Finding Slack User IDs:**
- In Slack, click on a user's profile
- Click "More" → "Copy member ID"
- Or use the format from user mentions in Slack (the part after `@`)

If `WHITELISTED_USERS` is empty or not set, all users can interact with Sam (default behavior).

When a non-whitelisted user tries to interact with Sam, the bot will silently ignore their messages.

### How it works

Expand Down
4 changes: 4 additions & 0 deletions sam/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
SLACK_BOT_TOKEN: str = os.getenv("SLACK_BOT_TOKEN")
#: The Slack app token, prefixed with `xapp-`.
SLACK_APP_TOKEN: str = os.getenv("SLACK_APP_TOKEN")
#: Comma-separated list of Slack user IDs allowed to interact with the bot. If empty, all users are allowed.
WHITELISTED_USERS: list[str] = [
user.strip() for user in os.getenv("WHITELISTED_USERS", "").split(",") if user.strip()
]

# Sentry
#: The Sentry DSN for Sentry based error reporting.
Expand Down
14 changes: 13 additions & 1 deletion sam/slack.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@
if event.get("subtype") in ["message_changed", "message_deleted"]:
logger.debug("Ignoring `%s` event", event["subtype"])
return

Check failure on line 58 in sam/slack.py

View workflow job for this annotation

GitHub Actions / lint (ruff check --output-format=github .)

Ruff (W293)

sam/slack.py:58:1: W293 Blank line contains whitespace
# Check if user is whitelisted (if whitelist is configured)
user_id = event.get("user")
if config.WHITELISTED_USERS and user_id not in config.WHITELISTED_USERS:
logger.debug("Ignoring message from non-whitelisted user: %s", user_id)
return

Check failure on line 64 in sam/slack.py

View workflow job for this annotation

GitHub Actions / lint (ruff check --output-format=github .)

Ruff (W293)

sam/slack.py:64:1: W293 Blank line contains whitespace
bot_id = await get_bot_user_id()
channel_id = event["channel"]
channel_type = event["channel_type"]
Expand Down Expand Up @@ -103,9 +110,14 @@
voice_response: bool = False,
):
"""Send a response to a message event from Slack."""
# Check if user is whitelisted (if whitelist is configured)
user_id = event["user"]
if config.WHITELISTED_USERS and user_id not in config.WHITELISTED_USERS:
logger.debug("Ignoring response request from non-whitelisted user: %s", user_id)
return

Check failure on line 118 in sam/slack.py

View workflow job for this annotation

GitHub Actions / lint (ruff check --output-format=github .)

Ruff (W293)

sam/slack.py:118:1: W293 Blank line contains whitespace
logger.debug("process_run=%s", json.dumps(event))
channel_id = event["channel"]
user_id = event["user"]
try:
timestamp = event["ts"]
except KeyError:
Expand Down
1 change: 1 addition & 0 deletions template.env
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ SLACK_APP_TOKEN=
SLACK_BOT_TOKEN=
OPENAI_API_KEY=
REDIS_URL=redis://redis:6379/1
WHITELISTED_USERS=
Loading