A Jev-powered bot for Bluesky and Slack.
talky-jev docs slack.md
4.9 kB · 93 lines
Markdown
at main

Slack #

The shared flow in talky_jev/core.py acknowledges a mention, loads its context, generates with Jev, and delivers a reply at END or the platform length boundary. Bluesky and Slack implement those interactions independently. Both use the same word tournament, stopping rules, images, message types, and 300-character reply limit.

Message permalinks and forwarded message links resolve into attributed source text and images within the configured channel allowlist. See referenced messages for the shared context format and limits.

The Slack adapter follows the mention attribution, chronological thread context, file recovery, and SQLite deduplication patterns in prefecthq/marvin/examples/slackbot. It does not depend on Marvin's agent runtime. Slack's Socket Mode connects outward from heavypad, so it needs no public webhook or inbound port.

current setup #

The dedicated talky jev app already exists in Prefect (TAN3D79AL). Installation was approved on 2026-10-21 and Jev is a member of #ai-tools. Nate authorized explicit mentions in any channel the bot joins. It uses the same shared decoder as Bluesky.

setup #

  1. After approval, install the existing dedicated app in Prefect. Its requested permissions are recorded in the manifest.
  2. Generate an app-level token with connections:write for Socket Mode.
  3. Invite the bot to channels where it should respond.
  4. Put the dedicated app's credentials in the canonical SOPS store under slack.talky_jev:
bot_token: <bot OAuth token>
app_token: <Socket Mode app-level token>
team_id: <workspace ID>
bot_user_id: <Jev bot user ID>
app_id: <Jev app ID>
channels:
  - "*"

The same keys can be provided with TALKY_JEV_SLACK_ environment names; TALKY_JEV_SLACK_CHANNELS is a comma-separated list of IDs, or * for any channel the bot joins. Referenced messages in wildcard mode require verified channel membership. With explicit IDs, the app must be a member of each channel. The runner refuses an empty allowlist and verifies the workspace, bot user, and app before processing events. Use a dedicated Jev app; Marvin's identity is not accepted as a substitute.

just slack-check
just deploy-slack

slack-check reads Slack identity and channel membership without posting. Socket Mode authentication is exercised when the runner connects. deploy-slack sends credentials through SSH stdin to ~/.config/talky-jev/slack.env with mode 600, and enables talky-jev-slack.service. just deploy also restarts Slack once that service is enabled. The Slack queue is separate from Bluesky's outbox. For rotation, update the dedicated entry, run just slack-check, then just deploy-slack and verify a real mention in #ai-tools.

interactions #

Every turn must explicitly mention Jev. Messages from bots, edits, other apps, other workspaces, and channels outside the allowlist are ignored. Anyone in a joined channel can mention it; Bluesky's PDS approval grants remain specific to Bluesky.

Events are committed to SQLite before acknowledging their Socket Mode envelope. The worker adds an eyes reaction, then reads the thread, recovering attachments that Slack omits from app_mention events. PNG/JPEG downloads require files:read, accept only Slack file hosts, and are bounded in size. Context ends at the triggering message and retains at most eleven conversation messages. Up to four images from those messages are kept at their original message indices, prioritizing recent uploads, so follow-up questions retain the picture. The decoder retains human messages from that window and omits earlier bot replies. The tagging person's name and job title are supplied as profile context. Slack does not add the bot's own bio or avatar.

Replies are posted in the original Slack thread. The queue stores the exact reply before sending, with stable client IDs and metadata used for recovery. If interrupted during a send, it looks for the matching bot reply. If delivery remains ambiguous, it stops that request for operator review instead of blindly posting again. Generation uses the same categorical append/END decoder as Bluesky, without a second draft or a word/step deadline. Withheld replies replace the eyes reaction with a warning. Model/transport exceptions follow the existing queue retry and failure handling; no ordinary-language error text is posted as Jev.

At most fifty replies are prepared per UTC day. Processing retries are bounded, and rate limits defer work without blocking receipt of new events. The queue and single-process lock live in ~/.local/state/talky-jev/slack.sqlite3.