@officedesk/plugin-whatsapp
v0.0.3
Published
WhatsApp Cloud API and personal WhatsApp Web integration plugin for officedesk-ai
Readme
@officedesk/plugin-whatsapp
WhatsApp integration plugin for officedesk-ai.
It supports two execution modes:
- cloud mode through Meta's official WhatsApp Cloud API
- personal mode through WhatsApp Web with QR login
Current capabilities include:
- profile based cloud configuration
- QR login with persisted personal sessions
- detached personal listener management
- personal session status inspection and logout
- listener diagnostics for state and logs
- listing personal conversations including direct messages and groups
- viewing recent message history for a known chat id
- inspecting the explicit participant roster for a known group chat
- finding groups by participant name or id through live group metadata
- replying to a specific personal WhatsApp message by message id
- searching cached personal messages with structured query operators
- listing recent cached personal messages without a query
- sending plain text messages in cloud mode or personal mode
- listing approved templates in cloud mode
- sending approved template messages in cloud mode
Preferred Invocation
officedesk plugin-whatsapp configure
officedesk plugin-whatsapp login --mode=personal
officedesk plugin-whatsapp status --mode=personal
officedesk plugin-whatsapp list-chats --mode=personal
officedesk plugin-whatsapp chat-participants --mode=personal [email protected]
officedesk plugin-whatsapp find-groups-by-member --mode=personal --query="Ferdaus"
officedesk plugin-whatsapp send-message --to=16505551234 --text="Hello from OfficeDesk"
officedesk plugin-whatsapp send-template --to=16505551234 --name=hello_world --language-code=en_USMode Overview
Use cloud mode when you need official business delivery through Meta APIs.
Use personal mode when you explicitly need WhatsApp Web backed behavior from a logged in personal session.
Mode specific rules:
configure,list-templates, andsend-templateare cloud onlylogin,logout,status, listener commands,list-chats,chat-messages,chat-participants,find-groups-by-member,reply-message,search-messages, andrecent-messagesare personal onlysend-messageworks in both modes
Configuration
Default profile:
officedesk plugin-whatsapp configureNamed profile:
officedesk plugin-whatsapp configure --profile=financeThe plugin writes configuration into:
- default profile:
$OFFICEDESK_HOME/plugins/plugin-whatsapp/.env - named profile:
$OFFICEDESK_HOME/plugins/plugin-whatsapp/.env.<profile>
Supported cloud variables:
WHATSAPP_ACCESS_TOKENWHATSAPP_PHONE_NUMBER_IDWHATSAPP_WABA_IDWHATSAPP_API_VERSIONoptional, defaults tov23.0
Personal mode stores session data under:
$OFFICEDESK_HOME/plugins/plugin-whatsapp/tokens/personal/
Personal mode does not use the cloud credentials.
Meta permissions commonly include:
whatsapp_business_messagingwhatsapp_business_managementbusiness_management
Developer Notes
For an implementation walkthrough of the personal mode runtime, including listener lifecycle, cache flow, RPC handling, and recovery behavior, see personal-session.md.
Personal Mode Workflow
Login with QR auth:
officedesk plugin-whatsapp login --mode=personalAfter login succeeds, the plugin starts a detached listener that keeps the browser session alive and appends observed messages into a local cache.
Check personal session status:
officedesk plugin-whatsapp status --mode=personalInspect detached listener state:
officedesk plugin-whatsapp listener-status --mode=personalRead recent listener logs:
officedesk plugin-whatsapp listener-log --mode=personal --lines=100Stop the detached listener without removing the saved session:
officedesk plugin-whatsapp listener-stop --mode=personalRestart the detached listener against the saved session:
officedesk plugin-whatsapp listener-restart --mode=personalRemove the persisted personal session:
officedesk plugin-whatsapp logout --mode=personalLogout also clears the local runtime data for that profile, including cached messages, listener state, and pending listener RPC files.
Personal Conversation And Message Inspection
List current personal chats:
officedesk plugin-whatsapp list-chats --mode=personalList only groups:
officedesk plugin-whatsapp list-chats --mode=personal --kind=group --limit=20Filter chats by a simple text match plus common state flags:
officedesk plugin-whatsapp list-chats --mode=personal --search='ops' --kind=group --unread-only --not-archived --limit=20Use the advanced chat query syntax when you want richer combinations:
officedesk plugin-whatsapp list-chats --mode=personal --query='chat:"Ops Team" is:archived is:pinned has:unread deploy'Fetch recent message history for a specific chat id:
officedesk plugin-whatsapp chat-messages --mode=personal [email protected] --limit=50Fetch the explicit participant roster for a known group chat:
officedesk plugin-whatsapp chat-participants --mode=personal [email protected]Find groups by participant name or id using live group metadata:
officedesk plugin-whatsapp find-groups-by-member --mode=personal --query="Ferdaus"Summarize a chat thread into key points, open questions, and next steps:
officedesk plugin-whatsapp summarize-chat --mode=personal [email protected] --limit=200Download all recent attachments from a chat:
officedesk plugin-whatsapp download-attachments --mode=personal [email protected] --limit=200 --output-dir=./downloads/kptDownload one specific attachment by message id:
officedesk plugin-whatsapp download-attachments --mode=personal [email protected] [email protected]_ABC123 --output-dir=./downloads/kptIf WhatsApp Web thread loading fails for a known chat, chat-messages falls back to cached messages already captured for that chat.
Reply to a specific message in a known chat:
officedesk plugin-whatsapp reply-message --mode=personal [email protected] [email protected]_3AF93938FAB62C1CB4AF --text="Acknowledged"Search cached personal messages:
officedesk plugin-whatsapp search-messages --mode=personal --query='chat:"Ops Team" deploy' --limit=20List the latest personal messages without a query:
officedesk plugin-whatsapp recent-messages --mode=personal --limit=20Useful list-chats filters:
--search=TEXT--kind=all|dm|group--archivedor--not-archived--pinnedor--not-pinned--mutedor--not-muted--unread-only--query='...'
Useful list-chats query operators:
- bare text terms match chat id, display name, and last message preview
chat:TEXTkind:dmorkind:groupis:dmoris:groupis:archivedoris:activeis:pinnedis:mutedhas:unread
Useful search operators:
from:TEXTchat:TEXTkind:dmorkind:groupdirection:incomingordirection:outgoingis:dmoris:grouphas:mediaafter:2026-03-01before:2026-03-31
Thread summary notes:
summarize-chatreuses the recent thread window fromchat-messages- the summary is deterministic and built from message content, questions, document requests, and next-step style phrasing
- system events such as group metadata changes are counted separately from the main summary bullets
Group participant notes:
chat-participantsreturns the explicit live roster for a group chat and fails clearly when the target chat is not a groupfind-groups-by-membersearches participant names, push names, and ids across available live group metadata, not the cached message index- unlike
search-messages, these membership commands do not depend on whether the participant has posted recently - these membership commands require a live personal WhatsApp Web session because participant rosters are not read from the local cache
- for small ad hoc groups,
chatNameand conversationnamemay be normalized from participant display names when WhatsApp still exposes only an id-like or phone-number-based title
Attachment download notes:
download-attachmentssaves files to the provided--output-dir, or to the plugin runtime downloads folder when omitted- absolute
--output-dirvalues are used as-is, and relative--output-dirvalues resolve from the caller's current working directory outputPathin the JSON response is the real final saved path- use
--message-idwhen you want one exact attachment instead of scanning the recent thread window chat-messagesand cached search results includehasMedia, and live thread fetches also include media filename and MIME metadata when available
Personal search notes:
- search uses the local cache, not a remote WhatsApp search API
- cache coverage starts when the personal listener begins observing messages
- messages sent through the personal CLI are also appended to that cache
- when the listener becomes ready it backfills unread messages from chats that currently show unread counts
- if unread backfill hits a WhatsApp Web fetch issue, the listener stays ready and records the warning in
lastWarningrather thanlastError - cached personal data is reset when you log out or when the same profile starts against a different WhatsApp account
Sending Messages
Cloud mode plain text message:
officedesk plugin-whatsapp send-message --to=16505551234 --text="Hello from OfficeDesk"Cloud mode with URL preview:
officedesk plugin-whatsapp send-message --to=16505551234 --text="https://officedesk.ai" --preview-urlPersonal mode plain text message:
officedesk plugin-whatsapp send-message --mode=personal --to=16505551234 --text="Hello from my personal WhatsApp"Personal mode group message by exact chat id:
officedesk plugin-whatsapp send-message --mode=personal [email protected] --text="Hello group"For personal sends, --to accepts either a phone number for direct messages or an exact personal chatId such as [email protected], [email protected], or 142081930604660@lid.
For reply-message, use the exact chatId plus the message id returned by chat-messages, recent-messages, or search-messages.
Send a cloud template message:
officedesk plugin-whatsapp send-template --to=16505551234 --name=hello_world --language-code=en_USSend a template with body parameters:
officedesk plugin-whatsapp send-template --to=16505551234 --name=invoice_ready --language-code=en_US --body-parameters='["INV 001","152.33"]'List approved templates:
officedesk plugin-whatsapp list-templatesList configured profiles:
officedesk plugin-whatsapp list-profilesDelivery notes:
- free form cloud messages are only allowed during the customer service window, so use approved templates when needed
- phone numbers must be provided in international format without a leading plus sign
send-templaterequires cloud mode and approved template metadata- there is no dry run support for sends, so treat send commands as live actions
JSON Output
Structured results are written to stdout as JSON.
Operational messages such as QR prompts, listener diagnostics, and runtime logs are written to stderr.
Useful response patterns:
send-messagereturns delivery records includingmessageId, plusphoneNumberIdin cloud mode orchatIdandackin personal modesend-templatereturnstemplateName,languageCode,parameterCount, andmessageId- personal inspection commands include listener metadata, cache paths, or runtime paths where relevant
Operational Notes
- personal mode uses
whatsapp-web.js, which is unofficial and can break or be blocked by WhatsApp - personal mode requires a working browser runtime; if Puppeteer install scripts were skipped, you may need to install or point to a compatible Chromium manually
- when running through the compiled
officedesk-plugin-whatsappbinary, personal mode delegates to the packaged Node.js CLI underdist/cli.js; the plugin runtime must includepackage.json,dist/, and the required npmnode_modules/for personal mode to work without any workspace package fallback - if cached results look stale, inspect
listener-statusorlistener-logbefore assuming the search index is complete
See Also
- AGENT_TUTORIAL.md for the full agent workflow guide
