OpenClaw

View as Markdown

This guide shows how to integrate the AgentDuet SDK with OpenClaw so an after-hours phone agent can take a voicemail and notify Slack through OpenClaw’s message CLI.

Sample: after-hours voicemail → OpenClaw → Slack.

  • Business hours: pre-answer connect(), then close() — caller rings the human line; OpenClaw is idle
  • After hours: AI answers, takes a message, saves it locally, and notifies Slack through OpenClaw

The sample runs openclaw message send after Gemini calls leave_voicemail.

What this integration provides

  • AgentDuet answers (or pass-through connects) inbound calls
  • Gemini Live runs the after-hours voicemail dialogue
  • OpenClaw delivers Slack with the same CLI you already use in chat (message send)

How the pieces fit

LayerOwns
AgentDuetConnector, inbound calls, PCM, connect / answer / disconnect
Gemini LiveSpeech-to-speech dialogue + tool calls
OpenClawSlack channel delivery (message send)
Your appBusiness hours, prompts, voicemail store, CLI invoke

Prerequisites

  • Python 3.12+
  • AgentDuet API key and connector UUID from agentduet.com
  • Gemini API key
  • OpenClaw running locally, with Slack connected (see below)

Set up OpenClaw

Install and onboard OpenClaw from their docs:

When that is done:

  1. openclaw on PATH on the machine that runs this sample
  2. Gateway running (openclaw gateway status)
  3. Slack connected, bot invited to the notify channel
  4. A working send (same shell as python main.py):
$openclaw message send --channel slack \
> --target channel:C0123456789 \
> --message "AgentDuet OpenClaw smoke test"

channel:C0123456789 is OpenClaw’s Slack target format: the prefix channel: plus the Slack channel ID (IDs start with C). In Slack, open the channel → View channel details → copy the ID at the bottom, or copy the channel link and take the C… segment. #channel-name also works if OpenClaw can resolve the name. See message CLI.

If this command fails, fix OpenClaw before starting AgentDuet.

Step 1: Clone the sample

$git clone https://github.com/AgentDuet/agentduet-samples.git
$cd agentduet-samples/integrations/openclaw/after-hours-voicemail

Layout:

after-hours-voicemail/
├── main.py # SessionManager + Gemini + OpenClaw notify
├── requirements.txt
└── .env.example

Step 2: Install dependencies

$python3.12 -m venv .venv
$source .venv/bin/activate
$pip install -r requirements.txt

The sample pins agentduet==1.0.0.

Step 3: Configure .env

$cp .env.example .env
$AGENTDUET_API_KEY=your-connector-api-key
$AGENTDUET_CONNECTOR_UUID=your-connector-uuid
$GEMINI_API_KEY=your-gemini-api-key
$OPENCLAW_SLACK_TARGET=channel:C0123456789
$FORCE_AFTER_HOURS=1

FORCE_AFTER_HOURS=1 makes every inbound call use the after-hours path (Riley + Slack), even if the wall clock is inside weekday 09:00–17:00 UTC. Omit it when you want real business-hours pass-through to the human line.

Optional:

$# OPENCLAW_BIN=/usr/local/bin/openclaw
$# OPENCLAW_DRY_RUN=1
$# BUSINESS_TZ=UTC
$# BUSINESS_HOURS_START=9
$# BUSINESS_HOURS_END=17
$# BUSINESS_DAYS=0,1,2,3,4

Step 4: Run

$python main.py

Call your AgentDuet number. Leave a short message. Confirm Slack receives an After-hours voicemail post delivered by OpenClaw.

Ask / doExpect
Call after hours (or with FORCE_AFTER_HOURS=1)Riley greets; office closed
Leave name + reasonleave_voicemail → JSONL + OpenClaw Slack post
Say goodbyeend_call → disconnect
Call during business hours (no force flag)connect → human line; agent closes

How AgentDuet and OpenClaw connect

  1. Gemini Live calls the local leave_voicemail tool from main.py.

  2. The handler appends voicemails/messages.jsonl, then runs:

    $openclaw message send --channel slack --target "$OPENCLAW_SLACK_TARGET" --message "..."
  3. Slack delivery uses OpenClaw’s configured Slack bot.