Install
$ agentstack add skill-initechsoftware-openclaw-whatsapp-skills-whatsapp-autoresponder ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
WhatsApp autoresponder
You receive an invocation from the webhook receiver with a payload like:
{
"chat_id": 12345678,
"text": "do you support Shopify?",
"sender_phone": "+15550200",
"sender_name": "Customer",
"message_uid": "c9054496-c8d2-4596-9786-aa872da4b743",
"allowed_sender_jid": "15550100@s.whatsapp.net"
}
Your job: compose a reply to the incoming text and send it back into the same chat. But before you send, check two guardrails.
Step 1 — Verify chat ownership (multi-number safety)
If your workspace has more than one WhatsApp number connected, the chat's whatsapp_account_id determines who the reply will come from. You must confirm that matches the sender JID this skill is allowed to speak as, or you will leak persona — replying to a sales chat from the support number is a hard mistake to explain.
CHAT_JID=$(curl -sS -H "Authorization: Bearer $TIMELINES_AI_API_KEY" \
"https://app.timelines.ai/integrations/api/chats/$CHAT_ID" \
| jq -r '.data.whatsapp_account_id')
if [ "$CHAT_JID" != "$ALLOWED_SENDER_JID" ]; then
echo "chat $CHAT_ID owned by $CHAT_JID, not $ALLOWED_SENDER_JID — skipping"
exit 0
fi
Single-number workspaces can skip this check — there's only one possible sender.
Step 2 — Check for stop-reply labels
If a human teammate has tagged the chat with needs-human, escalate, or pause-bot, the bot must exit silently without sending anything. This is how humans take over without confusing the customer with an overlapping agent reply.
LABELS=$(curl -sS -H "Authorization: Bearer $TIMELINES_AI_API_KEY" \
"https://app.timelines.ai/integrations/api/chats/$CHAT_ID/labels" \
| jq -r '.data.labels[]? // empty')
case "$LABELS" in
*needs-human*|*escalate*|*pause-bot*)
echo "stop-reply label present — exiting without reply"
exit 0
;;
esac
Step 3 — Reply
Compose your reply text (one short paragraph; if you need conversation history for context, fetch it with GET /chats/$CHAT_ID/messages?limit=20). Write the payload to a file with explicit UTF-8 encoding — never use inline -d "..." with anything that might contain em-dashes, smart quotes, or emoji, because shell encoding will mangle the bytes and the JSON parser will reject the whole request.
REPLY_TEXT="Your composed reply here."
python3 -c "import json,sys; json.dump({'text': sys.argv[1]}, open('/tmp/wa_reply.json','w'), ensure_ascii=False)" \
"$REPLY_TEXT"
curl -sS -X POST \
-H "Authorization: Bearer $TIMELINES_AI_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @/tmp/wa_reply.json \
"https://app.timelines.ai/integrations/api/chats/$CHAT_ID/messages"
A successful send returns:
{"status":"ok","data":{"message_uid":""}}
Capture that message_uid and return it in your skill output — downstream skills can use it to poll delivery status via GET /messages/{uid}/status_history.
Error responses to watch for
{"status":"error","message":"Bad JSON format: 'utf-8' codec can't decode byte 0x97..."}— your payload isn't valid UTF-8. Go back to step 3 and make sure you're writing the file withensure_ascii=Falseand reading it with--data-binary.{"status":"error","message":"Not authenticated"}— the token is wrong or missing. Check$TIMELINES_AI_API_KEY.{"status":"error","message":"Whatsapp chat_id ... not found"}— either the chat doesn't exist, or your token's workspace doesn't own it. Either way, don't retry.- An HTML 404 page instead of JSON — you probably have a trailing slash on the path. Remove it.
What this skill deliberately does NOT do
- It does not reply if the chat is owned by a different WhatsApp number in a multi-number workspace.
- It does not reply if any stop-reply label is present.
- It does not retry on failure — if the send 5xx's, let the caller decide.
- It does not send unsolicited first-touch messages to people who haven't messaged you — for outbound, use the
whatsapp-sendskill and read the compliance notes first.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: InitechSoftware
- Source: InitechSoftware/openclaw-whatsapp-skills
- License: MIT
- Homepage: https://timelines.ai/guides/openclaw-whatsapp-skills
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.