---
title: Telegram as the Channel: Constraints as Features
description: Why the brief goes to the app you already open first thing in the morning, how the integration stays deliberately simple, and how a 4,096-character cap and a tiny HTML subset became the best editorial decisions in the system.
track: delivery
url: https://www.chiefofstaff.io/guides/telegram-as-the-channel
published: 2026-09-01
author: chiefofstaff.io editorial system
outcome: charter a channel coordinator that owns one private bot chat bidirectionally, author briefs against the channel's limits, and keep the bot token out of every agent's hands.
prerequisites: the-daily-brief, manager-not-operator
source: chiefofstaff.io
---

# Telegram as the Channel: Constraints as Features

Why the brief goes to the app you already open first thing in the morning, how the integration stays deliberately simple, and how a 4,096-character cap and a tiny HTML subset became the best editorial decisions in the system.

## Meet You Where You Already Live

The daily brief is worthless if it lands somewhere you don't look. The reference system uses Telegram for one reason: that's where the human already spends the day. The right channel for you is whichever app you actually open at 6 a.m. Everything below transfers to any of them; the specifics are Telegram's because that is where the scars are.

## The Shape of the Integration

Deliberately simple:

- **A bot**, created through the platform's standard flow, talking to a single private chat.
- **A coordinator agent** that owns the channel in both directions. The chief of staff never calls the messaging API; it hands the coordinator a payload with a *kind* (`daily-brief`, `ack`, `response`, `alert`) and the coordinator validates, formats, sends, and logs. Inbound, the coordinator polls for new messages, transcribes voice notes, and returns them as structured items for routing.
- **The secret outside the vault**, read by exactly one tiny wrapper script that the coordinator invokes — it never sees the token. See [Credentials and confidentiality](/guides/credentials-and-confidentiality).
- **An append-only conversation log**, so every inbound and outbound message has a durable record with a processed flag and the ID of the session that sent it.

## Constraints as Features

Telegram messages cap at 4,096 characters and support only a small HTML subset: bold, italic, code, links, block quotes. No headers, no tables, no lists, no `<br>`. This sounds limiting. It is the best editorial decision in the system.

The cap makes the sub-five-minute brief physically mandatory. The missing markup forces scannable formatting — a bold section marker, bullet lines, a decision per line — instead of walls of structure. If your channel has no such limit, **impose one on yourself.** The brief got better every time the cap was enforced and worse every time someone found a way around it (a second message, a file attachment).

## Authoring Conventions That Came from Pain

- **One source file, two renderers.** The archived brief is opened both in the channel (which treats a literal newline as a break and rejects `<br>`) and in a browser (which collapses newlines and needs `<br>`). Resolution: author every line break as `<br />`; the coordinator converts to newlines at send time. A brief authored without `<br />` renders as a run-on paragraph in every surface except the channel — which is the only surface anyone checks, so the bug is invisible until it isn't.
- **Measure what you send.** The coordinator independently measures the payload against the cap and refuses to send when its count disagrees with the author's. It halted three sends in eight days; all three were real bugs, one in a surface the channel never sees. Do not tune the check to tolerate small deltas.
- **Weekly content that exceeds the cap** goes as a short thread of messages, each standing alone — not as a file. A raw Markdown file opened on a phone is unstyled plain text; when a *report* must go as a file, it is HTML, standalone, with its own light styling and no JavaScript.

## Two-Way, Not Broadcast

The channel also carries your side of the control loop. **Every acknowledgement or response is a native threaded reply** to the message it answers, by rule — so you can see, in the thread, what happened to what you sent. And reactions carry state without adding chat noise: 👀 when a message is ingested, 🤔 while a session is working on it, 👍 when it is processed. Each transition is set by the code path that owns it, not by an agent deciding to be communicative.

For the full inbound contract — every message reaches an outcome and gets a receipt — see [Every message gets a receipt](/guides/every-message-gets-a-receipt).

## Outbound Audio, and the Wrapper's Whitelist

The coordinator's API whitelist is exhaustive: send message, get updates, send document, get file, set reaction. When the human wanted a voice reply and "send voice" was not on the list, the answer was not to widen the whitelist on the spot: the chief of staff synthesised audio on-device, encoded it as MP3, and sent it through the sanctioned *document* endpoint — which the platform renders as a tap-to-play bubble. The list widened later, by decision record, when a narrator operator was hired. Whitelists that only grow through records stay whitelists.

## Failure Modes to Design For

- **Token leaked** → revoke, rotate, and move it behind the wrapper if it wasn't already.
- **The human mutes the bot** → silent failure on their end; the weekly should note "no reply to any of the last seven briefs."
- **The send fires but the log write doesn't** (a harness kill mid-send) → the next session sees a gap in message IDs. Flag the gap; never rationalise it. One brief was sent three times because the gap was explained away.