Prerequisites
- A Zenzap API key and secret (see Setup Steps)
- Python 3.10+
- An OpenAI API key
Project Setup
Create a new directory for your agent and install the required dependencies:.env file with your credentials:
| Variable | Description |
|---|---|
BOT_API_KEY | Your Zenzap API key (from the console) |
BOT_SECRET | Your Zenzap API secret (used for request signing) |
CONTROL_CHANNEL_ID | The topic ID where the bot will post status messages (e.g. “connected”, “disconnecting”) |
OPENAI_API_KEY | Your OpenAI API key |
OPENAI_MODEL | The OpenAI model to use (defaults to gpt-4o) |
API_BASE_URL | The Zenzap API base URL (defaults to https://api.zenzap.co) |
Step 1 — Build the Zenzap API Client
Createzenzap_client.py. This module handles all communication with the Zenzap API, including HMAC request signing (see Authentication for details).
Start with the response wrapper and client constructor:
GET requests sign the URI path, while POST/PATCH/DELETE requests sign the JSON body:
The client uses additional methods like
create_topic, list_topics, create_task, etc.
See the full API Reference endpoints for everything you can do.Step 2 — Handle Incoming Messages
Createbot.py. Start by defining a system prompt and a state object to track the bot’s runtime data:
bot_member_id— the bot’s own user ID, so it can skip its own messages.next_offset— the cursor for long polling.topic_name_cache— avoids repeated API calls to resolve topic names.conversation_histories— per-topic message history sent to OpenAI for context.
Step 3 — Process Updates From the Poll Loop
Add a function that filters incoming updates and routes relevant ones to the chat handler. The bot should ignore its own messages and empty texts:- Only
message.createdevents are processed — see Webhook Events for all event types. - The bot skips its own messages by comparing
senderIdtobot_member_id. - Each incoming message is marked as read and given an 👀 reaction as visual feedback.
Step 4 — Wire Up the Main Loop
Finally, add themain() function that initializes the clients and starts the long-polling loop:
409 error occurs (offset expired), it resets and starts fresh.
Step 5 — Run the Agent
Start the bot:Next Steps
- Custom tools — Extend
handle_chatto support function calling so your agent can create tasks, manage topics, or call external APIs. - Conversation management — Use a database instead of in-memory
conversation_historiesfor persistence across restarts.