Skip to main content
Channels connect a project to a messaging provider. The channel definition is code-owned; provider credentials and conversation IDs are configured in the dashboard for each environment. A channel is a conversation keyed by an external participant. What differs between providers is transport, addressing, and authentication; what does not differ is that an inbound message continues the conversation it belongs to. Agents see the second part and never the first — one useInput().source === "channel" branch handles every provider. Providers are named for the vendor rather than the medium, because the vendor is what actually differs: Twilio signs the request URL and its sorted parameters, Slack signs a timestamp and the raw body. A different SMS vendor is a different adapter, not a variant of this one. Twilio WhatsApp needs no separate provider — same API, same webhook, same signature, with a whatsapp: prefix on addresses.

Define a Twilio or email channel

Providers other than Slack address one participant, so they need no scopes and have a single inbound event:
opencomputer/channels/shop-sms.ts
opencomputer/channels/support-email.ts
Note what is not in the definition: the phone number and the inbox address. Those are per-environment operational configuration, bound to a connection in the dashboard, exactly as Slack workspace and conversation IDs are. Development and production do not share a number. Register them the same way as Slack, with the trigger the provider supports:
opencomputer/agents/receptionist/channels/shop-sms.ts
Registering a Slack trigger on a Twilio channel is a build error, and the reverse is too.

Idle and cost

Agent runtime is billed by wall-clock time, and a conversation spends most of its life waiting for a person. idle.suspendAfterSeconds says how long to hold the runtime after the last message; an inbound message resumes it. It defaults to 300 seconds, and the default matters most where replies are slowest — a text conversation that waits hours for an answer should not bill for those hours.

Slack

Define a Slack channel

Create a project-level channel under opencomputer/channels/:
opencomputer/channels/team-slack.ts
The filename must match the channel id. A channel owns:
  • the Slack bot scopes requested by its generated app manifest;
  • the Slack events the app subscribes to;
  • stable destination names used by outboxes; and
  • the routing policy used when several agents can receive the same event.
Slack workspace IDs, conversation IDs, bot tokens, and signing secrets do not belong in source.

Register an agent for inbound messages

A channel does not name an agent. An agent opts into inbound events with a registration under its own directory:
opencomputer/agents/reviewer/channels/team-slack.ts
mention requires the channel to declare the app_mention event and the app_mentions:read scope. direct-message requires message.im and im:history. Several agents may register the same channel. An existing Slack thread stays with its selected agent. If a new thread has several eligible agents, OpenComputer asks the user which agent should handle it instead of guessing.

Connect Slack

After the deployment is synchronized:
  1. Open the project in the dashboard.
  2. Select Development or Production.
  3. Open Channels and choose Connect Slack.
  4. Create or update the Slack app from the generated manifest.
  5. Install the app to the intended Slack workspace.
  6. Enter the installed app credentials when prompted.
  7. Invite the app to each Slack conversation it will use.
  8. Bind each code-defined destination to that conversation’s Slack ID and verify it.
For a public destination, include channels:read and chat:write. For a private destination, include groups:read and chat:write. The app must be a member of the selected conversation. OpenComputer does not request chat:write.public automatically. Adding a scope in code changes the generated manifest. Update and reinstall the Slack app so its granted scopes satisfy the current deployment. Inspect delivery health without opening the dashboard:
The result reports the last accepted provider event, the latest outbound delivery status, and the latest redacted error category. It never includes message content, provider responses, tokens, or signing secrets.

Environment isolation

Development and Production never share Slack credentials, destination bindings, thread routing, or delivery history. Connecting a Slack app in one environment does not connect it in the other. The same stable destination name can therefore map independently:
Slack delivery uses the stored conversation ID. Renaming the conversation does not change the route, although its display label may refresh later.

Current limits

  • Slack is the only channel provider.
  • Destination binding currently uses a Slack conversation ID.
  • Direct Slack user mapping and outbound DMs are not available.
  • A registration can receive mentions or direct messages only when the corresponding event and scope are declared.
Use an outbox when an agent needs to publish a proactive message to a configured Slack destination.