关于 whatsapp
whatsapp 是通过 Green API 发送和检索 WhatsApp 消息的自动化技能,面向通知、媒体分享及消息跟进等任务。它提供统一命令行脚本,支持多种消息和附件,并包含回复监控流程。
主要功能
- 01发送文本、图片、视频、语音和文件
- 02向联系人或群组发送消息
- 03按条件检索消息与媒体信息
- 04监控新回复并去重
- 05发送前预览消息
适用场景
- 01发送通知、提醒和工作坊跟进
- 02向联系人分享图片或文档
- 03检索并转录收到的语音消息
- 04等待客户审批或反馈后继续处理
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ aviz85/ claude-skills-library --skill whatsapp安装后在 Claude Code 中输入/whatsapp确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
SETUP.mdscripts/.env.exampleget-group-members.tsget-messages.tspackage.jsonsend-image.tssend-message.tssend-voice.tstsconfig.jsonwatch-replies.sh详细介绍
WhatsApp 自动化
通过统一脚本发送消息,使用 Green API(主要方式)和 WAHA(已配置时作为备用方式)。
快速开始 — 统一脚本
cd ~/.claude/skills/whatsapp/scripts
# Text message
npx ts-node send-message.ts "Hello!" --to 972501234567
# Multiline text from shell: use $'...'
npx ts-node send-message.ts $'Line 1\n\nLine 2\n- Bullet A\n- Bullet B' --to 972501234567
# Image with caption
npx ts-node send-message.ts --to 972501234567 --image /path/to/image.jpg --caption "Check this out!"
# Video with caption
npx ts-node send-message.ts --to 972501234567 --video /path/to/video.mp4 --caption "Watch this!"
# Any media file (auto-detect)
npx ts-node send-message.ts --to 972501234567 --media /path/to/any-file --caption "Here!"
# Voice message
npx ts-node send-message.ts --to 972501234567 --voice /path/to/audio.ogg
# File/document
npx ts-node send-message.ts --to 972501234567 --file /path/to/doc.pdf --caption "Here's the doc"
# Send to group
npx ts-node send-message.ts "Group message" --group [email protected]
# Reply to a specific message (quoted reply)
npx ts-node send-message.ts "Reply!" --group [email protected] --quote BAE5367237E13A1B
# Voice as quoted reply
npx ts-node send-message.ts --group [email protected] --voice /tmp/voice.mp3 --quote BAE5367237E13A1B
# Dry run (preview)
npx ts-node send-message.ts "Test" --to 972501234567 --dry-run
默认号码
| 别名 | 号码 | 用途 |
|---|---|---|
| myself / me / test | $MY_PHONE(来自 config.sh) | 默认收件人 |
发送视频和音频 — 编码为 AAC
如果视频的音轨是 MP3 并封装在 MP4 中,WhatsApp(以及 Facebook)会静音播放视频——文件本身有效,在桌面播放器中也有声音,但移动应用会丢弃音轨。视频音频务必使用 AAC:
# Re-encode ONLY the audio to AAC, leave the video untouched; +faststart for streaming
ffmpeg -y -i in.mp4 -c:v copy -c:a aac -b:a 192k -movflags +faststart out.mp4
# Verify it isn't silent before sending
ffmpeg -i out.mp4 -af volumedetect -f null /dev/null 2>&1 | grep mean_volume
语音消息:请先将源文件转换为 OGG/Opus——在应用中,容器内的原始 MP3 不可靠。
脚本选项
| 选项 | 说明 |
|---|---|
"message" | 文本消息(第一个位置参数) |
--to, --phone <NUMBER> | 电话号码(接受以色列格式) |
--group <ID> | 群组 ID(格式:[email protected]) |
--image <PATH> | 附加图片文件 |
--video <PATH> | 附加视频文件(MP4 等) |
--media <PATH> | 附加任意媒体文件(自动检测) |
--voice <PATH> | 发送语音消息(OGG/MP3) |
--file <PATH> | 附加文档/文件 |
--caption <TEXT> | 媒体文件的说明文字 |
--quote <MSG_ID> | 回复特定消息(quotedMessageId) |
--dry-run | 预览但不发送 |
多行格式
从 shell 发送带换行符的 WhatsApp 消息时,如果希望最终消息中出现实际换行,不要在普通引号字符串中传入字面量 \n。
请改用 shell 的 ANSI-C 引号:
npx ts-node send-message.ts $'Hi\n\nLine 2\n- Item 1\n- Item 2' --group [email protected]
原因:
"text with \n"会发送字符\+n,但脚本会自动将其转换为实际换行$'text with \n'会直接发送实际换行
两种形式都可用——脚本会在发送前将字面量 \n 规范化为实际换行。
$'...' 中的撇号: 直接使用 \'——不要使用 '\'' 这种写法。'\'' 模式会跳出 ANSI-C 引号,之后的所有内容都会变成普通单引号引起来的内容(其中 \n 是字面量)。
# CORRECT — apostrophe inside $'...'
$'I\'ve added a check.\n\nNext line.'
# WRONG — breaks ANSI-C quoting, \n becomes literal after the apostrophe
$'I'\''ve added a check.\n\nNext line.'
编写结构化的 WhatsApp 消息时,建议使用:
- 简短的开场白
- 空行
- 简短的项目符号列表
- 空行
- 简短的结束语
格式规则 — 与语言一致
英文消息: 使用常规项目符号/短横线。英文文本中绝不要使用希伯来字母(א. ב. ג.)。
- First item
- Second item
- Third item
希伯来语消息: 每一行都必须以希伯来字符开头,以确保 RTL 渲染正确。列表项请使用希伯来字母。
א. פריט ראשון
ב. פריט שני
ג. פריט שלישי
不要混用: 英文消息中不要使用希伯来字母,希伯来语消息中不要使用短横线/数字。
不要这样做:
- פריט ראשון
1. פריט שני
* פריט שלישי
以非希伯来字符(短横线、数字、星号、英文)开头的行会破坏 WhatsApp 中的 RTL 对齐。务必确保第一个可见字符是希伯来字符。
服务提供方逻辑
| 内容类型 | 主要方式 | 备用方式 |
|---|---|---|
| 文本 | Green API | WAHA(已配置时) |
| 图片 | Green API | - |
| 视频 | Green API | - |
| 语音 | Green API | - |
| 文件 | Green API | - |
注意: 目前尚未安装 WAHA。所有消息类型均由 Green API 处理。
配置
凭据位于 scripts/.env:
# Green API (primary provider)
GREEN_API_URL=https://7103.api.greenapi.com
GREEN_API_INSTANCE=your_instance
GREEN_API_TOKEN=your_token
# WAHA (optional fallback — uncomment if installed)
# WAHA_URL=http://localhost:3001
# WAHA_API_KEY=your_key
# WAHA_SESSION=default
电话号码格式
| 输入 | 规范化结果 |
|---|---|
972501234567 | [email protected] |
0501234567 | [email protected] |
501234567 | [email protected] |
直接 API(WAHA)
仅适用于文本消息:
source ~/.claude/skills/whatsapp/config.sh
curl -s -X POST "$WAHA_URL/api/sendText" \
-H "X-Api-Key: $WAHA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"session": "default",
"chatId": "[email protected]",
"text": "Hello!"
}'
检查会话状态
source ~/.claude/skills/whatsapp/config.sh
curl -s -H "X-Api-Key: $WAHA_API_KEY" "$WAHA_URL/api/sessions/default"
按姓名查找联系人
用户未提供电话号码而说“给 [name] 发 WhatsApp”时:
- 使用
get-contact技能搜索 CRM - 如果未找到 → 向用户询问电话号码
- 如果找到多个 → 请用户选择
- 如果找到一个 → 发送前进行确认
发送前务必确认联系人。
按名称或项目查找群组
当用户说“发送到 [project] 群组”时,直接搜索 Green API(WAHA 可能不可用):
TOKEN=$(grep "GREEN_API_TOKEN" ~/.claude/skills/whatsapp/scripts/.env | cut -d'=' -f2)
INSTANCE=$(grep "GREEN_API_INSTANCE" ~/.claude/skills/whatsapp/scripts/.env | cut -d'=' -f2)
curl -s "https://7103.api.greenapi.com/waInstance$INSTANCE/getChats/$TOKEN" | python3 -c "
import json,sys
data=json.load(sys.stdin)
for c in (data if isinstance(data,list) else []):
if '@g.us' in c.get('id',''):
print(c.get('id'), '|', c.get('name',''))
"
然后使用 send-message.ts --group <ID> 发送。
发送前绝不要检查 WAHA 会话——脚本会自动处理回退。
提供商说明
Green API 是主要提供商。WAHA 未安装,仅在明确配置时用作回退。
直接运行 send-message.ts 即可——它会直接使用 Green API。
获取消息 (get-messages.ts)
从任意联系人获取收到的消息、语音录音和媒体:
# Get recent messages from a contact
npx ts-node get-messages.ts --chat 972526062921 --count 5
# Get messages from last 2 hours
npx ts-node get-messages.ts --chat 972526062921 --minutes 120
# Get all messages from a time range
npx ts-node get-messages.ts --start "2h ago" --end "now"
# Output as JSON (includes download URLs for media)
npx ts-node get-messages.ts --chat 972526062921 --json
你会获取到:
- 包含完整内容的文本消息
- 带有下载 URL 的语音消息(OGA/OGG 格式)——可以单独转录
- 带有下载 URL 和元数据的图片
- 时间戳、发送者信息、文件名
- 所有消息类型(扩展文本、回应、媒体)
引用/回复消息会内联显示——get-messages.ts 现在会自动显示引用上下文,并加上 ↳ Reply to 前缀。extendedTextMessage 和 quotedMessage 类型均已处理。
消息类型:textMessage、extendedTextMessage(带有 .text)、quotedMessage(回复,带有 .quotedMessage.textMessage)、reactionMessage、imageMessage
语音消息工作流:
- 使用
get-messages.ts --json获取消息 - 从
audioMessage类型中提取downloadUrl - 下载 OGA 文件
- 转换为 WAV:
ffmpeg -i file.oga -ar 16000 file.wav - 转录:
/transcribe --language he /path/to/file.wav
等待回复 — Monitor 集成
有时发送消息后,你需要先收到联系人的回复才能继续——例如批准、决定、反馈,或“我欠你多少钱”。这时,不必停下来让用户盯着聊天窗口;把等待交给 Monitor 工具,同时继续工作;每条新回复都会作为通知送达。
使用 scripts/watch-replies.sh——它会轮询真正新收到的消息(按 ID 去重,并处理文本/回应/媒体),每条回复输出一行,供 Monitor 接收。只有被终止时才会退出(Monitor 超时 / TaskStop)。
# usage
scripts/watch-replies.sh --chat <number|groupId> [--since <epoch>] [--interval 30] [--label REPLY]
通过 Monitor 工具启动它(而不是 Bash),这样你可以继续工作,同时接收回复通知:
command:~/.claude/skills/whatsapp/scripts/watch-replies.sh --chat 972501234567 --since "$(date +%s)" --label CLIENTtimeout_ms:等待时长(例如,等待一小时可设为3600000)。- 始终将
--since设为你发送消息的时刻($(date +%s)),否则旧消息会再次触发,仿佛是新消息。
⚠️ 不要在 Monitor 的
command中临时编写内联轮询器。 在 shell 中直接传入群组 ID 或 JSON 正文会在 zsh 下出错——@g.us会触发bad math expression: illegal character: @,导致 monitor 以状态码 1 退出。watch-replies.sh将聊天作为参数接收(--chat <id>),因此群组 ID 是安全的。始终使用此脚本;不要在 Monitor 命令中内联群组 ID 和 curl/python。
根据具体情况决定是否使用
当回复会影响你的下一步操作时,使用它:
- 你发送的内容需要先获批准才能进行下一步(草稿、预览、报价);
- 你提出了一个问题,并会根据答案采取行动;
- 你正在进行迭代循环(发送修复 → 对方审核 → 发送下一项);
- 你开始了耗时的工作,并希望不被阻塞地等待回复。
对于发完即忘的消息(确认、告知信息、“已完成”),则无需使用——预计不会有回复,因此也无需等待。
保持对话连贯
很多时候,正确的做法是持续跟进:收到回复后,先回复对方,然后重新启动一个新的监听器(使用新的 --since),等待下一轮消息。这才是真正的来回沟通——发送示例 → 对方批准 → 发送修复 → 再次等待——直到对话自然结束(最终批准、致谢、款项结清,或用户表示收尾)。每一轮:发送 → 监听 → 回复 → 再次监听。 自行判断交流是否真正结束,以及何时停止监听。
使用规范
- 每个监听器都有自己的去重文件,因此,同一聊天中的两个监听器会触发两次——启用新的监听器前,请先对旧的监听器执行
TaskStop。 - 表情反应会显示为
(reaction 👍),媒体会显示为[imageMessage];需要图片 URL、说明文字或语音文件时,请使用get-messages.ts --json获取完整记录。
使用场景
- 发送通知或提醒
- 分享图片或海报
- 发送语音消息
- 分享文档
- 自动提醒
- 跟进研讨会
- 检索并转录客户发送的语音消息
- 检查联系人的媒体附件