Instant messaging
Instant messaging pulls every chat app you use into one page: Slack and Telegram over their real APIs, WhatsApp, Messenger, and LinkedIn through the browser extension, since none of them offer a usable API for this. Every inbound message becomes an event, flows through triage like mail and calendar do, and can land a row in your task queue with a reply box right there.
The connector interface
Section titled “The connector interface”Every messaging app implements the same small seam: {fetch, send, capabilities}.
fetch(since?)drains everything new since a watermark and returns it as a normalized{conversationId, conversationTitle?, providerMessageId, ts, sender, body, meta?}list.send(conversationId, body, opts?)posts a reply;opts.claimKeylets a connector de-duplicate a retried or double-fired send so it never queues the same message twice.capabilitiesreports whether the connector can send at all and the latency you should expect, shown in the UI so you know what you’re waiting on.
Native (API) connectors
Section titled “Native (API) connectors”Slack and Telegram connect directly:
- Slack rides
@slack/web-apifor sends and Socket Mode for a live inbound feed (buffered inside the connector, drained on the same poll as everything else). - Telegram rides GramJS, a full MTProto client, so it behaves like your own Telegram session rather than a bot account.
Both are polled every 30 seconds by the IM sync engine, same cadence pattern as Mail.
Browser-automation connectors
Section titled “Browser-automation connectors”WhatsApp, Messenger, and LinkedIn have no usable API, so they ride the Chrome extension’s job queue instead, running in your own logged-in browser session:
- Fetching happens every two to five minutes: the server enqueues one fetch job per site (skipping a site that already has one queued or running) and the extension drains it, delivering whatever it found back through the same inbound pipeline as the API connectors.
- Sending enqueues a job the extension executes the next time it’s active; the UI shows it as queued, sends via browser rather than sent until that happens.
- A connector that finds itself logged out on the target site files a task-queue card asking you to log back in, background fetch can’t recover from that on its own.
The IM page
Section titled “The IM page”/p/im opens on a Unified tab (no filter, active by default) plus one tab per
configured connector. Each app tab shows an unread count as a red ·N badge, and
browser-automation apps carry a faint via browser annotation so you know their latency
differs from Slack or Telegram. Selecting an app tab (not Unified) marks it seen, clearing
its badge; the Unified tab never marks anything seen on its own.
Each message row shows an initials avatar, the sender, the conversation title and time, and the body. A row whose message already has an open task-queue entry carries a small also in task queue tag so you’re not tempted to act on it twice.
- Inline reply: every row has a reply affordance that reveals a text field, Enter sends, Escape cancels. API-connector sends show sent immediately; browser-connector sends show queued, sends via browser until the extension delivers it.
- → inbox: routes a message into the capture inbox as “
<sender>: <body>” for later triage as a task, independent of replying to it. - The page respects the same not-now gate as Mail: while locked it shows the shared not-now screen, and an active frequency restriction shows a small viewable every Nh chip in the header.
From message to task queue
Section titled “From message to task queue”Every inbound IM message becomes an ops.events row the same way inbound mail does, which
triage classifies and, depending on severity, surfaces as a
task queue row with the same inline reply affordance the IM page itself
offers.
The im.send agent tool
Section titled “The im.send agent tool”Agents reach IM through a gated tool, im.send {app, conversationId, body}, requiring
approval before it fires. It resolves to the matching connector and sends through the same
send() seam the UI uses, claim-guarded per call so a retried tool invocation can’t send
twice. It’s the tool the outreach sequence workflow uses for its IM
touches, alongside gated mail sends.