Conversations and approvals
Document version: 0.2 · Last updated: 2026-10-08 · Status: 🔴 UNDER REVIEW
Use a conversation when an outgoing notification needs a correlated response. Each conversation has an ID, participants, a handler route, context and a revision. Several conversations can be open for the same user at once.
Ask two people about the same request
The following recipe uses a registered TeamBot from writing a bot.
Run it in trusted application code after the bot application has started:
request = await telegram.create_conversation(
"engineering",
participants=[
{"user_id": mario_id, "chat_id": mario_id},
{"user_id": anna_id, "chat_id": anna_id},
],
route="review",
context={"pr": 45},
)
for user_id in (mario_id, anna_id):
await telegram.send_conversation_message(
"engineering", request["id"], user_id,
"Please review PR 45",
buttons={"Reviewed": "reviewed", "Need help": "help"},
)
Both users must be reachable by the Telegram bot. For WhatsApp, use string
participant IDs and observe the service-window/template rules. A participant
may have a distinct chat_id; provide it explicitly when the same user belongs
to more than one chat in a conversation.
The buttons invoke the conversation’s review handler with action="reviewed"
or action="help". Replies use the stored message and chat to select the request.
They are sent only to that participant, not broadcast to the other participants.
Your business handler decides whether a response satisfies the review.
Keep simultaneous conversations separate
A reply reference identifies its conversation. A button must also match a stored offered action and the expected participant. Plain text without a reply reference is dispatched only when exactly one open conversation matches. With two possible requests, the bot asks the user to reply to the relevant message.
The sender dictionary is provider-specific. Do not assume Telegram integer IDs
and WhatsApp string IDs refer to the same application identity.
Update and conclude a request
Read a fresh snapshot and supply its revision when replacing context:
current = await telegram.get_conversation("engineering", request["id"])
await telegram.update_conversation_context(
"engineering", request["id"],
{**current["context"], "review_status": "ready"},
revision=current["revision"],
)
await telegram.close_conversation("engineering", request["id"])
A stale revision raises rather than overwriting another update. Use
state="cancelled" to cancel. expires_at on creation is a Unix timestamp;
expiry is observed on the next read or interaction, not by a timer. A closed,
cancelled or expired request does not dispatch further replies.
If a handler sends a final message and closes the conversation, it should return
None. Send the message before closing so the participant is still eligible.
Schedule a reminder tied to the request
Before the conversation closes:
from datetime import datetime, timedelta, timezone
reminder_id = await telegram.schedule_reminder(
"engineering", mario_id, "PR 45 still needs a review",
when=datetime.now(timezone.utc) + timedelta(hours=2),
conversation_id=request["id"], user_id=mario_id,
)
The task manager must be running. If the conversation has concluded when the
reminder executes, it is skipped. Read get_reminder(reminder_id) for its state;
cancellation is possible only while pending. Delivery with an uncertain outcome
is not silently repeated.
Require admission before bot use
Admission is a separate, built-in conversation type. Enable it in a registration:
config = {
"settings": {"dataset": "engineering"},
"access": {
"approval_required": True,
"admins": [first_admin_id, second_admin_id],
"approval_policy": "first",
},
}
With first, the first valid processed decision concludes the request. With
all, all administrators must approve; one rejection concludes it. Each admin’s
vote is immutable. Rejected requests remain rejected when the user sends /start
again. Configured administrators are implicitly admitted.
On Telegram, each administrator must already have started a private chat with the bot. Settled request messages show who approved or rejected and lose their buttons. WhatsApp sends settlement messages and may need configured templates outside administrator service windows. The persisted decision is the authority even if one of those outgoing notifications fails; the application retries unresolved notices when restoring admissions.
Admission gives access to bot interactions. It does not create application users, tokens or router permissions. General conversation APIs cannot edit or close admission records. See Telegram admission and WhatsApp admission for provider-specific configuration.