Mainstream messaging
Status: آماده برای تولید از طریق WhatsApp Web (Baileys). Gateway مالک نشست(های) لینکشده است.
نصب (در صورت نیاز)
- راهاندازی اولیه (
openclaw onboard) وopenclaw channels add --channel whatsappهنگام اولین انتخاب WhatsApp plugin، نصب آن را پیشنهاد میکنند. openclaw channels login --channel whatsappنیز وقتی plugin هنوز موجود نیست، جریان نصب را ارائه میدهد.- کانال Dev + checkout گیت: بهصورت پیشفرض از مسیر plugin محلی استفاده میکند.
- Stable/Beta: از بسته npm یعنی
@openclaw/whatsappروی تگ انتشار رسمی فعلی استفاده میکند.
نصب دستی همچنان در دسترس است:
openclaw plugins install @openclaw/whatsapp
برای دنبال کردن تگ انتشار رسمی فعلی، از بسته بدون نسخه استفاده کنید. نسخه دقیق را فقط زمانی pin کنید که به نصب بازتولیدپذیر نیاز دارید.
در Windows، WhatsApp plugin هنگام نصب npm به Git روی PATH نیاز دارد، چون
یکی از وابستگیهای Baileys/libsignal آن از یک URL گیت دریافت میشود. Git
for Windows را نصب کنید، سپس shell را دوباره راهاندازی کنید و نصب را دوباره اجرا کنید:
winget install --id Git.Git -e
Portable Git نیز در صورتی کار میکند که دایرکتوری bin آن روی PATH باشد.
سیاست پیشفرض DM برای فرستندههای ناشناس pairing است.
عیبیابی میانکانالی و راهنماهای تعمیر.
الگوها و نمونههای کامل پیکربندی کانال.
راهاندازی سریع
Configure WhatsApp access policy
{
channels: {
whatsapp: {
dmPolicy: "pairing",
allowFrom: ["+15551234567"],
groupPolicy: "allowlist",
groupAllowFrom: ["+15551234567"],
},
},
}
Link WhatsApp (QR)
openclaw channels login --channel whatsapp
برای یک حساب مشخص:
openclaw channels login --channel whatsapp --account work
برای اتصال یک دایرکتوری احراز هویت موجود/سفارشی WhatsApp Web پیش از ورود:
openclaw channels add --channel whatsapp --account work --auth-dir /path/to/wa-auth
openclaw channels login --channel whatsapp --account work
Start the gateway
openclaw gateway
Approve first pairing request (if using pairing mode)
openclaw pairing list whatsapp
openclaw pairing approve whatsapp <CODE>
درخواستهای Pairing پس از ۱ ساعت منقضی میشوند. درخواستهای در انتظار برای هر کانال به ۳ مورد محدود میشوند.
الگوهای استقرار
Dedicated number (recommended)
این تمیزترین حالت عملیاتی است:
- هویت WhatsApp جداگانه برای OpenClaw
- allowlistهای DM و مرزهای مسیریابی شفافتر
- احتمال کمتر سردرگمی در چت با خود
الگوی حداقلی سیاست:
{
channels: {
whatsapp: {
dmPolicy: "allowlist",
allowFrom: ["+15551234567"],
},
},
}
Personal-number fallback
راهاندازی اولیه از حالت شماره شخصی پشتیبانی میکند و یک baseline سازگار با چت با خود مینویسد:
dmPolicy: "allowlist"allowFromشامل شماره شخصی شما استselfChatMode: true
در زمان اجرا، محافظتهای چت با خود بر اساس شماره خود لینکشده و allowFrom عمل میکنند.
WhatsApp Web-only channel scope
کانال پلتفرم پیامرسان در معماری کانال فعلی OpenClaw مبتنی بر WhatsApp Web (Baileys) است.
در رجیستری داخلی کانالهای چت، کانال پیامرسانی جداگانه Twilio WhatsApp وجود ندارد.
مدل زمان اجرا
- Gateway مالک سوکت WhatsApp و حلقه اتصال مجدد است.
- watchdog اتصال مجدد از فعالیت انتقال WhatsApp Web استفاده میکند، نه فقط حجم پیامهای ورودی برنامه؛ بنابراین یک نشست دستگاه لینکشده کمصدا صرفا به این دلیل که اخیرا کسی پیامی نفرستاده است دوباره راهاندازی نمیشود. یک سقف طولانیتر سکوت برنامه همچنان اگر فریمهای انتقال همچنان برسند ولی هیچ پیام برنامهای در بازه watchdog پردازش نشود، اتصال مجدد را اجبار میکند؛ پس از یک اتصال مجدد گذرا برای نشستی که اخیرا فعال بوده، این بررسی سکوت برنامه برای نخستین پنجره بازیابی از timeout عادی پیام استفاده میکند.
- زمانبندیهای سوکت Baileys بهصورت صریح زیر
web.whatsapp.*هستند:keepAliveIntervalMspingهای برنامه WhatsApp Web را کنترل میکند،connectTimeoutMstimeout handshake آغازین را کنترل میکند، وdefaultQueryTimeoutMstimeoutهای query در Baileys را کنترل میکند. - ارسالهای خروجی به یک شنونده فعال WhatsApp برای حساب مقصد نیاز دارند.
- ارسالهای گروهی برای tokenهای
@+<digits>و@<digits>در متن و captionهای رسانه، وقتی token با فراداده شرکتکننده فعلی WhatsApp مطابقت داشته باشد، از جمله گروههای پشتیبانیشده با LID، فراداده mention بومی را ضمیمه میکنند. - چتهای وضعیت و broadcast نادیده گرفته میشوند (
@status،@broadcast). - watchdog اتصال مجدد فعالیت انتقال WhatsApp Web را دنبال میکند، نه فقط حجم پیامهای ورودی برنامه: نشستهای دستگاه لینکشده کمصدا تا زمانی که فریمهای انتقال ادامه دارند برقرار میمانند، اما توقف انتقال خیلی زودتر از مسیر قطع اتصال راه دور بعدی، اتصال مجدد را اجبار میکند.
- چتهای مستقیم از قوانین نشست DM استفاده میکنند (
session.dmScope؛ مقدار پیشفرضmain، DMها را به نشست اصلی agent ادغام میکند). - نشستهای گروهی ایزوله هستند (
agent:<agentId>:whatsapp:group:<jid>). - WhatsApp Channels/Newsletters میتوانند با JID بومی
@newsletterخود، مقصدهای خروجی صریح باشند. ارسالهای خروجی newsletter بهجای معنای نشست DM، از فراداده نشست کانال استفاده میکنند (agent:<agentId>:whatsapp:channel:<jid>). - انتقال WhatsApp Web متغیرهای محیطی استاندارد proxy را روی میزبان Gateway رعایت میکند (
HTTPS_PROXY,HTTP_PROXY,NO_PROXY/ گونههای lowercase). پیکربندی proxy در سطح میزبان را به تنظیمات proxy اختصاصی WhatsApp برای کانال ترجیح دهید. - وقتی
messages.removeAckAfterReplyفعال باشد، OpenClaw پس از تحویل یک پاسخ قابل مشاهده، واکنش ack در WhatsApp را پاک میکند.
hookهای Plugin و حریم خصوصی
پیامهای ورودی WhatsApp میتوانند شامل محتوای پیام شخصی، شماره تلفنها،
شناسههای گروه، نام فرستندهها، و فیلدهای همبستگی نشست باشند. به همین دلیل،
WhatsApp payloadهای hook ورودی message_received را برای plugins broadcast نمیکند
مگر اینکه صریحا opt in کنید:
{
channels: {
whatsapp: {
pluginHooks: {
messageReceived: true,
},
},
},
}
میتوانید opt-in را به یک حساب محدود کنید:
{
channels: {
whatsapp: {
accounts: {
work: {
pluginHooks: {
messageReceived: true,
},
},
},
},
},
}
این را فقط برای pluginsی فعال کنید که به آنها برای دریافت محتوای پیام ورودی WhatsApp و شناسهها اعتماد دارید.
کنترل دسترسی و فعالسازی
DM policy
channels.whatsapp.dmPolicy دسترسی چت مستقیم را کنترل میکند:
pairing(پیشفرض)allowlistopen(نیاز داردallowFromشامل"*"باشد)disabled
allowFrom شمارههای به سبک E.164 را میپذیرد (داخلی normalized میشوند).
allowFrom یک فهرست کنترل دسترسی فرستنده DM است. ارسالهای خروجی صریح به JIDهای گروه WhatsApp یا JIDهای کانال @newsletter را gate نمیکند.
override چندحسابی: channels.whatsapp.accounts.<id>.dmPolicy (و allowFrom) برای آن حساب بر پیشفرضهای سطح کانال اولویت دارند.
جزئیات رفتار زمان اجرا:
- pairingها در allow-store کانال پایدار میشوند و با
allowFromپیکربندیشده ادغام میشوند - automation زمانبندیشده و fallback گیرنده Heartbeat از مقصدهای تحویل صریح یا
allowFromپیکربندیشده استفاده میکنند؛ تاییدهای pairing در DM، گیرندههای ضمنی cron یا heartbeat نیستند - اگر هیچ allowlistی پیکربندی نشده باشد، شماره خود لینکشده بهصورت پیشفرض مجاز است
- OpenClaw هرگز DMهای خروجی
fromMeرا بهصورت خودکار pair نمیکند (پیامهایی که از دستگاه لینکشده به خودتان میفرستید)
Group policy + allowlists
دسترسی گروه دو لایه دارد:
-
allowlist عضویت گروه (
channels.whatsapp.groups)- اگر
groupsحذف شده باشد، همه گروهها واجد شرایط هستند - اگر
groupsوجود داشته باشد، بهعنوان allowlist گروه عمل میکند ("*"مجاز است)
- اگر
-
سیاست فرستنده گروه (
channels.whatsapp.groupPolicy+groupAllowFrom)open: allowlist فرستنده bypass میشودallowlist: فرستنده باید باgroupAllowFrom(یا*) مطابقت داشته باشدdisabled: همه ورودیهای گروه را مسدود میکند
fallback برای allowlist فرستنده:
- اگر
groupAllowFromتنظیم نشده باشد، زمان اجرا در صورت وجود بهallowFromfallback میکند - allowlistهای فرستنده پیش از فعالسازی mention/reply ارزیابی میشوند
نکته: اگر اصلا هیچ بلوک channels.whatsapp وجود نداشته باشد، fallback سیاست گروه در زمان اجرا allowlist است (با log هشدار)، حتی اگر channels.defaults.groupPolicy تنظیم شده باشد.
Mentions + /activation
پاسخهای گروهی بهصورت پیشفرض به mention نیاز دارند.
تشخیص mention شامل این موارد است:
- mentionهای صریح WhatsApp از هویت bot
- الگوهای regex mention پیکربندیشده (
agents.list[].groupChat.mentionPatterns، fallback بهmessages.groupChat.mentionPatterns) - transcriptهای voice-note ورودی برای پیامهای گروهی مجاز
- تشخیص ضمنی reply-to-bot (فرستنده reply با هویت bot مطابقت دارد)
نکته امنیتی:
- quote/reply فقط gate مربوط به mention را برآورده میکند؛ به فرستنده مجوز نمیدهد
- با
groupPolicy: "allowlist"، فرستندههایی که در allowlist نیستند حتی اگر به پیام کاربری در allowlist پاسخ دهند همچنان مسدود میشوند
فرمان فعالسازی در سطح نشست:
/activation mention/activation always
activation وضعیت نشست را بهروزرسانی میکند (نه config سراسری). این کار با مالک gate میشود.
رفتار شماره شخصی و چت با خود
وقتی شماره خود لینکشده نیز در allowFrom وجود داشته باشد، محافظتهای چت با خود WhatsApp فعال میشوند:
- رد کردن read receiptها برای نوبتهای چت با خود
- نادیده گرفتن رفتار auto-trigger مربوط به mention-JID که در غیر این صورت خودتان را ping میکند
- اگر
messages.responsePrefixتنظیم نشده باشد، پاسخهای چت با خود بهصورت پیشفرض[{identity.name}]یا[openclaw]هستند
نرمالسازی پیام و زمینه
Inbound envelope + reply context
پیامهای ورودی WhatsApp در envelope ورودی مشترک wrap میشوند.
اگر پاسخ نقلقولشده وجود داشته باشد، context به این شکل اضافه میشود:
[Replying to <sender> id:<stanzaId>]
<quoted body or media placeholder>
[/Replying]
فیلدهای فراداده reply نیز در صورت موجود بودن پر میشوند (ReplyToId, ReplyToBody, ReplyToSender, sender JID/E.164).
وقتی مقصد reply نقلقولشده رسانه قابل دانلود باشد، OpenClaw آن را از طریق
media store ورودی عادی ذخیره میکند و بهصورت MediaPath/MediaType ارائه میدهد تا
agent بتواند تصویر ارجاعشده را بررسی کند، نه اینکه فقط
<media:image> را ببیند.
Media placeholders and location/contact extraction
پیامهای ورودی فقط رسانهای با placeholderهایی مانند موارد زیر normalized میشوند:
<media:image><media:video><media:audio><media:document><media:sticker>
voice noteهای گروهی مجاز پیش از gate مربوط به mention، وقتی
body فقط <media:audio> باشد، transcript میشوند؛ بنابراین گفتن mention مربوط به bot در voice note میتواند
پاسخ را trigger کند. اگر transcript همچنان bot را mention نکند،
transcript بهجای placeholder خام در تاریخچه گروه در انتظار نگه داشته میشود.
بدنههای location از متن مختصر مختصات استفاده میکنند. labelها/commentهای location و جزئیات contact/vCard بهصورت فراداده نامطمئن fenced render میشوند، نه متن prompt inline.
Pending group history injection
برای گروهها، پیامهای پردازشنشده میتوانند buffer شوند و وقتی bot در نهایت trigger میشود، بهعنوان context تزریق شوند.
- حد پیشفرض:
50 - پیکربندی:
channels.whatsapp.historyLimit - جایگزین:
messages.groupChat.historyLimit 0غیرفعال میکند
نشانگرهای تزریق:
[پیامهای چت از آخرین پاسخ شما - برای زمینه][پیام فعلی - به این پاسخ دهید]
تأییدیههای خواندن
تأییدیههای خواندن برای پیامهای ورودی پذیرفتهشدهی WhatsApp بهصورت پیشفرض فعال هستند.
غیرفعالسازی سراسری:
{
channels: {
whatsapp: {
sendReadReceipts: false,
},
},
}
بازنویسی برای هر حساب:
{
channels: {
whatsapp: {
accounts: {
work: {
sendReadReceipts: false,
},
},
},
},
}
نوبتهای چت با خود، حتی وقتی بهصورت سراسری فعال باشد، تأییدیههای خواندن را رد میکنند.
تحویل، قطعهبندی، و رسانه
قطعهبندی متن
- حد پیشفرض قطعه:
channels.whatsapp.textChunkLimit = 4000 channels.whatsapp.chunkMode = "length" | "newline"- حالت
newlineمرزهای پاراگراف را ترجیح میدهد (خطوط خالی)، سپس به قطعهبندی امن از نظر طول برمیگردد
رفتار رسانهی خروجی
- از محمولههای تصویر، ویدئو، صدا (یادداشت صوتی PTT)، و سند پشتیبانی میکند
- رسانهی صوتی از طریق محمولهی
audioدر Baileys باptt: trueارسال میشود، بنابراین کلاینتهای WhatsApp آن را بهصورت یادداشت صوتی push-to-talk نمایش میدهند - محمولههای پاسخ
audioAsVoiceرا حفظ میکنند؛ خروجی یادداشت صوتی TTS برای WhatsApp حتی وقتی ارائهدهنده MP3 یا WebM برمیگرداند، روی همین مسیر PTT میماند - صدای بومی Ogg/Opus برای سازگاری یادداشت صوتی بهصورت
audio/ogg; codecs=opusارسال میشود - صدای غیر Ogg، شامل خروجی MP3/WebM از Microsoft Edge TTS، پیش از تحویل PTT با
ffmpegبه Ogg/Opus تککانالهی 48 kHz تبدیل میشود /tts latestآخرین پاسخ دستیار را بهصورت یک یادداشت صوتی ارسال میکند و ارسالهای تکراری برای همان پاسخ را سرکوب میکند؛/tts chat on|off|defaultTTS خودکار را برای چت فعلی WhatsApp کنترل میکند- پخش GIF متحرک از طریق
gifPlayback: trueدر ارسالهای ویدئویی پشتیبانی میشود - هنگام ارسال محمولههای پاسخ چندرسانهای، زیرنویسها روی نخستین مورد رسانه اعمال میشوند، بهجز یادداشتهای صوتی PTT که صدا را ابتدا و متن قابل مشاهده را جداگانه ارسال میکنند، چون کلاینتهای WhatsApp زیرنویسهای یادداشت صوتی را بهطور پایدار نمایش نمیدهند
- منبع رسانه میتواند HTTP(S)،
file://، یا مسیرهای محلی باشد
محدودیتهای اندازهی رسانه و رفتار جایگزین
- سقف ذخیرهی رسانهی ورودی:
channels.whatsapp.mediaMaxMb(پیشفرض50) - سقف ارسال رسانهی خروجی:
channels.whatsapp.mediaMaxMb(پیشفرض50) - بازنویسیهای هر حساب از
channels.whatsapp.accounts.<accountId>.mediaMaxMbاستفاده میکنند - تصاویر برای جا شدن در محدودیتها بهصورت خودکار بهینه میشوند (تغییر اندازه/پویش کیفیت)
- در صورت شکست ارسال رسانه، جایگزینِ مورد اول بهجای حذف بیصدای پاسخ، هشدار متنی ارسال میکند
نقلقول کردن پاسخ
WhatsApp از نقلقول بومی پاسخ پشتیبانی میکند، که در آن پاسخهای خروجی بهصورت قابل مشاهده پیام ورودی را نقلقول میکنند. آن را با channels.whatsapp.replyToMode کنترل کنید.
| مقدار | رفتار |
|---|---|
"off" |
هرگز نقلقول نکن؛ بهصورت پیام ساده ارسال کن |
"first" |
فقط نخستین قطعهی پاسخ خروجی را نقلقول کن |
"all" |
هر قطعهی پاسخ خروجی را نقلقول کن |
"batched" |
پاسخهای دستهای صفشده را نقلقول کن، درحالیکه پاسخهای فوری بدون نقلقول میمانند |
پیشفرض "off" است. بازنویسیهای هر حساب از channels.whatsapp.accounts.<id>.replyToMode استفاده میکنند.
{
channels: {
whatsapp: {
replyToMode: "first",
},
},
}
سطح واکنش
channels.whatsapp.reactionLevel کنترل میکند که عامل تا چه اندازه از واکنشهای ایموجی در WhatsApp استفاده کند:
| سطح | واکنشهای تأیید | واکنشهای آغازشده توسط عامل | توضیح |
|---|---|---|---|
"off" |
خیر | خیر | هیچ واکنشی وجود ندارد |
"ack" |
بله | خیر | فقط واکنشهای تأیید (رسید پیش از پاسخ) |
"minimal" |
بله | بله (محافظهکارانه) | تأیید + واکنشهای عامل با راهنمایی محافظهکارانه |
"extensive" |
بله | بله (تشویقشده) | تأیید + واکنشهای عامل با راهنمایی تشویقی |
پیشفرض: "minimal".
بازنویسیهای هر حساب از channels.whatsapp.accounts.<id>.reactionLevel استفاده میکنند.
{
channels: {
whatsapp: {
reactionLevel: "ack",
},
},
}
واکنشهای تأیید
WhatsApp از واکنشهای تأیید فوری هنگام رسید دریافت ورودی از طریق channels.whatsapp.ackReaction پشتیبانی میکند.
واکنشهای تأیید توسط reactionLevel کنترل میشوند — وقتی reactionLevel برابر "off" باشد، سرکوب میشوند.
{
channels: {
whatsapp: {
ackReaction: {
emoji: "👀",
direct: true,
group: "mentions", // always | mentions | never
},
},
},
}
یادداشتهای رفتاری:
- بلافاصله پس از پذیرش ورودی ارسال میشود (پیش از پاسخ)
- شکستها ثبت میشوند اما تحویل عادی پاسخ را مسدود نمیکنند
- حالت گروهی
mentionsدر نوبتهای فعالشده با اشاره واکنش نشان میدهد؛ فعالسازی گروهیalwaysبرای این بررسی بهعنوان دورزننده عمل میکند - WhatsApp از
channels.whatsapp.ackReactionاستفاده میکند (messages.ackReactionقدیمی اینجا استفاده نمیشود)
چندحسابی و اعتبارنامهها
انتخاب حساب و پیشفرضها
- شناسههای حساب از
channels.whatsapp.accountsمیآیند - انتخاب حساب پیشفرض: اگر
defaultوجود داشته باشد همان، وگرنه نخستین شناسهی حساب پیکربندیشده (مرتبشده) - شناسههای حساب برای جستوجو بهصورت داخلی نرمالسازی میشوند
مسیرهای اعتبارنامه و سازگاری قدیمی
- مسیر احراز هویت فعلی:
~/.openclaw/credentials/whatsapp/<accountId>/creds.json - فایل پشتیبان:
creds.json.bak - احراز هویت پیشفرض قدیمی در
~/.openclaw/credentials/همچنان برای جریانهای حساب پیشفرض شناسایی/مهاجرت داده میشود
رفتار خروج
openclaw channels logout --channel whatsapp [--account <id>] وضعیت احراز هویت WhatsApp را برای آن حساب پاک میکند.
وقتی یک Gateway قابل دسترسی است، logout ابتدا شنونده زنده WhatsApp را برای حساب انتخابشده متوقف میکند تا نشست لینکشده تا راهاندازی مجدد بعدی همچنان پیام دریافت نکند. openclaw channels remove --channel whatsapp نیز قبل از غیرفعالسازی یا حذف پیکربندی حساب، شنونده زنده را متوقف میکند.
در دایرکتوریهای احراز هویت قدیمی، oauth.json حفظ میشود در حالی که فایلهای احراز هویت Baileys حذف میشوند.
ابزارها، کنشها، و نوشتن پیکربندی
- پشتیبانی ابزار عامل شامل کنش واکنش WhatsApp (
react) است. - دروازههای کنش:
channels.whatsapp.actions.reactionschannels.whatsapp.actions.polls
- نوشتن پیکربندی آغازشده توسط کانال بهطور پیشفرض فعال است (با
channels.whatsapp.configWrites=falseغیرفعال کنید).
عیبیابی
Not linked (QR required)
نشانه: وضعیت کانال گزارش میدهد که لینک نشده است.
رفع:
openclaw channels login --channel whatsapp
openclaw channels status
Linked but disconnected / reconnect loop
نشانه: حساب لینکشده با قطع اتصالهای تکراری یا تلاشهای اتصال مجدد.
حسابهای کمفعالیت میتوانند پس از پایان مهلت معمول پیام همچنان متصل بمانند؛ نگهبان زمانی راهاندازی مجدد میشود که فعالیت انتقال WhatsApp Web متوقف شود، سوکت بسته شود، یا فعالیت سطح برنامه فراتر از پنجره ایمنی طولانیتر خاموش بماند.
اگر گزارشها status=408 Request Time-out Connection was lost تکراری نشان میدهند، زمانبندیهای سوکت Baileys را زیر web.whatsapp تنظیم کنید. ابتدا keepAliveIntervalMs را کمتر از مهلت بیکاری شبکه خود کوتاه کنید و connectTimeoutMs را در پیوندهای کند یا پراتلاف افزایش دهید:
{
web: {
whatsapp: {
keepAliveIntervalMs: 15000,
connectTimeoutMs: 60000,
defaultQueryTimeoutMs: 60000,
},
},
}
رفع:
openclaw doctor
openclaw logs --follow
اگر ~/.openclaw/logs/whatsapp-health.log میگوید Gateway inactive اما openclaw gateway status و openclaw channels status --probe نشان میدهند که Gateway و WhatsApp سالم هستند، openclaw doctor را اجرا کنید. در Linux، doctor درباره ورودیهای crontab قدیمی که هنوز ~/.openclaw/bin/ensure-whatsapp.sh را فراخوانی میکنند هشدار میدهد؛ آن ورودیهای مانده را با crontab -e حذف کنید، زیرا cron ممکن است محیط user-bus مربوط به systemd را نداشته باشد و باعث شود آن اسکریپت قدیمی سلامت Gateway را نادرست گزارش کند.
در صورت نیاز، با channels login دوباره لینک کنید.
QR login times out behind a proxy
نشانه: openclaw channels login --channel whatsapp پیش از نمایش یک کد QR قابل استفاده، با status=408 Request Time-out یا قطع اتصال سوکت TLS شکست میخورد.
ورود WhatsApp Web از محیط پروکسی استاندارد میزبان Gateway استفاده میکند (HTTPS_PROXY، HTTP_PROXY، گونههای حروف کوچک، و NO_PROXY). بررسی کنید که فرایند Gateway محیط پروکسی را به ارث میبرد و NO_PROXY با mmg.whatsapp.net مطابقت ندارد.
No active listener when sending
وقتی هیچ شنونده Gateway فعالی برای حساب هدف وجود نداشته باشد، ارسالهای خروجی سریع شکست میخورند.
مطمئن شوید Gateway در حال اجرا است و حساب لینک شده است.
Reply appears in transcript but not in WhatsApp
ردیفهای رونوشت چیزی را ثبت میکنند که عامل تولید کرده است. تحویل WhatsApp جداگانه بررسی میشود: OpenClaw فقط پس از آنکه Baileys برای دستکم یک ارسال متن یا رسانه قابل مشاهده، شناسه پیام خروجی برگرداند، یک پاسخ خودکار را ارسالشده تلقی میکند.
واکنشهای تایید، رسیدهای مستقل پیش از پاسخ هستند. واکنش موفق ثابت نمیکند که پاسخ متنی یا رسانهای بعدی توسط WhatsApp پذیرفته شده است.
گزارشهای Gateway را برای auto-reply delivery failed یا auto-reply was not accepted by WhatsApp provider بررسی کنید.
Group messages unexpectedly ignored
به این ترتیب بررسی کنید:
groupPolicygroupAllowFrom/allowFrom- ورودیهای فهرست مجاز
groups - دروازهگذاری اشاره (
requireMention+ الگوهای اشاره) - کلیدهای تکراری در
openclaw.json(JSON5): ورودیهای بعدی ورودیهای قبلی را بازنویسی میکنند، بنابراین در هر محدوده فقط یکgroupPolicyنگه دارید
Bun runtime warning
زماناجرای Gateway مربوط به WhatsApp باید از Node استفاده کند. Bun برای عملیات پایدار Gateway مربوط به WhatsApp/Telegram ناسازگار علامتگذاری شده است.
اعلانهای سیستم
WhatsApp از اعلانهای سیستم به سبک Telegram برای گروهها و گفتوگوهای مستقیم از طریق نگاشتهای groups و direct پشتیبانی میکند.
سلسلهمراتب تفکیک برای پیامهای گروه:
نگاشت مؤثر groups ابتدا تعیین میشود: اگر حساب groups خودش را تعریف کند، بهطور کامل جایگزین نگاشت ریشه groups میشود (بدون ادغام عمیق). سپس جستوجوی اعلان روی همان نگاشت واحد حاصل اجرا میشود:
- اعلان سیستم ویژه گروه (
groups["<groupId>"].systemPrompt): زمانی استفاده میشود که ورودی گروه مشخص در نگاشت وجود داشته باشد و کلیدsystemPromptآن تعریف شده باشد. اگرsystemPromptیک رشته خالی ("") باشد، wildcard سرکوب میشود و هیچ اعلان سیستمی اعمال نمیشود. - اعلان سیستم wildcard گروه (
groups["*"].systemPrompt): زمانی استفاده میشود که ورودی گروه مشخص بهطور کامل در نگاشت غایب باشد، یا وقتی وجود دارد اما هیچ کلیدsystemPromptتعریف نمیکند.
سلسلهمراتب تفکیک برای پیامهای مستقیم:
نگاشت مؤثر direct ابتدا تعیین میشود: اگر حساب direct خودش را تعریف کند، بهطور کامل جایگزین نگاشت ریشه direct میشود (بدون ادغام عمیق). سپس جستوجوی اعلان روی همان نگاشت واحد حاصل اجرا میشود:
- پرامپت سیستمی مخصوص گفتوگوی مستقیم (
direct["<peerId>"].systemPrompt): زمانی استفاده میشود که ورودی همتای مشخص در نقشه وجود داشته باشد و کلیدsystemPromptآن تعریف شده باشد. اگرsystemPromptیک رشتهٔ خالی ("") باشد، wildcard نادیده گرفته میشود و هیچ پرامپت سیستمی اعمال نمیشود. - پرامپت سیستمی wildcard برای گفتوگوی مستقیم (
direct["*"].systemPrompt): زمانی استفاده میشود که ورودی همتای مشخص بهطور کامل در نقشه وجود نداشته باشد، یا وجود داشته باشد اما هیچ کلیدsystemPromptتعریف نکند.
تفاوت با رفتار چندحسابی Telegram: در Telegram، groups ریشه عمداً برای همهٔ حسابها در یک راهاندازی چندحسابی نادیده گرفته میشود - حتی حسابهایی که هیچ groups مخصوص خودشان تعریف نکردهاند - تا از دریافت پیامهای گروههایی که bot عضو آنها نیست جلوگیری شود. WhatsApp این محافظ را اعمال نمیکند: groups ریشه و direct ریشه همیشه توسط حسابهایی که override در سطح حساب تعریف نکردهاند به ارث برده میشوند، فارغ از اینکه چند حساب پیکربندی شده باشد. در یک راهاندازی چندحسابی WhatsApp، اگر پرامپتهای گروه یا گفتوگوی مستقیم مخصوص هر حساب میخواهید، بهجای تکیه بر پیشفرضهای سطح ریشه، نقشهٔ کامل را صریحاً زیر هر حساب تعریف کنید.
رفتار مهم:
channels.whatsapp.groupsهم نقشهٔ پیکربندی برای هر گروه است و هم allowlist گروه در سطح chat. در محدودهٔ ریشه یا حساب،groups["*"]یعنی «همهٔ گروهها برای این محدوده پذیرفته میشوند».- فقط زمانی wildcard گروه
systemPromptاضافه کنید که از قبل میخواهید آن محدوده همهٔ گروهها را بپذیرد. اگر همچنان میخواهید فقط مجموعهٔ ثابتی از شناسههای گروه واجد شرایط باشند، ازgroups["*"]برای پیشفرض پرامپت استفاده نکنید. بهجای آن، پرامپت را روی هر ورودی گروهی که صریحاً در allowlist است تکرار کنید. - پذیرش گروه و مجوز فرستنده دو بررسی جداگانه هستند.
groups["*"]مجموعهٔ گروههایی را که میتوانند به پردازش گروه برسند گسترش میدهد، اما بهتنهایی هر فرستندهای را در آن گروهها مجاز نمیکند. دسترسی فرستنده همچنان جداگانه توسطchannels.whatsapp.groupPolicyوchannels.whatsapp.groupAllowFromکنترل میشود. channels.whatsapp.directهمین اثر جانبی را برای DMها ندارد.direct["*"]فقط پس از آنکه یک DM از طریقdmPolicyبههمراهallowFromیا قواعد pairing-store پذیرفته شد، یک پیکربندی پیشفرض برای گفتوگوی مستقیم فراهم میکند.
مثال:
{
channels: {
whatsapp: {
groups: {
// Use only if all groups should be admitted at the root scope.
// Applies to all accounts that do not define their own groups map.
"*": { systemPrompt: "Default prompt for all groups." },
},
direct: {
// Applies to all accounts that do not define their own direct map.
"*": { systemPrompt: "Default prompt for all direct chats." },
},
accounts: {
work: {
groups: {
// This account defines its own groups, so root groups are fully
// replaced. To keep a wildcard, define "*" explicitly here too.
"[email protected]": {
requireMention: false,
systemPrompt: "Focus on project management.",
},
// Use only if all groups should be admitted in this account.
"*": { systemPrompt: "Default prompt for work groups." },
},
direct: {
// This account defines its own direct map, so root direct entries are
// fully replaced. To keep a wildcard, define "*" explicitly here too.
"+15551234567": { systemPrompt: "Prompt for a specific work direct chat." },
"*": { systemPrompt: "Default prompt for work direct chats." },
},
},
},
},
},
}
اشارهگرهای مرجع پیکربندی
مرجع اصلی:
فیلدهای مهم WhatsApp:
- دسترسی:
dmPolicy,allowFrom,groupPolicy,groupAllowFrom,groups - تحویل:
textChunkLimit,chunkMode,mediaMaxMb,sendReadReceipts,ackReaction,reactionLevel - چندحسابی:
accounts.<id>.enabled,accounts.<id>.authDir, overrideهای سطح حساب - عملیات:
configWrites,debounceMs,web.enabled,web.heartbeatSeconds,web.reconnect.*,web.whatsapp.* - رفتار نشست:
session.dmScope,historyLimit,dmHistoryLimit,dms.<id>.historyLimit - پرامپتها:
groups.<id>.systemPrompt,groups["*"].systemPrompt,direct.<id>.systemPrompt,direct["*"].systemPrompt