פרק 5
ההודעה הראשונה, תתקין לי GOWA
פרק זה מיועד למי שבוחר במסלול ההתקנה המודולרי, צעד אחר צעד. אם כבר הפעלתם את ההודעה האחת המלאה, מנוע GOWA ושרת ה-MCP כבר הותקנו ומוגדרים, ותוכלו לדלג ישירות לפרק השימוש.
במסלול זה, ההודעה הנוכחית מתמקדת בהקמת מנוע GOWA בלבד בתוך קונטיינר Docker מאובטח. לפי התיעוד הרשמי נכון ל-2026-11-02, Docker חוסך התקנה של Go, FFmpeg ו-webp על המחשב עצמו. בבנייה מהמקור נדרש Go 1.26.0 ומעלה. חבילת webp מספקת את cwebp, dwebp ו-webpmux, וכלי libwebp (webpmux ו-dwebp) משמשים למדבקות WebP מונפשות. החל מגרסה 9 של הפרויקט, מצב rest כולל בתוכו גם את שרת ה-MCP המובנה בנתיב /mcp עם תמיכה בהזרמת HTTP וגם את ה-REST API, ללא צורך בהרצת תהליך נפרד. התיעוד הרשמי עוקב אחרי main שמוזג, כולל שינויים שאחרי v9.7.0. בתג או בבינארי נעול בודקים את הערות הגרסה ואת GET /app/info. הפקודה ./whatsapp version מדפיסה רק את מספר הגרסה. בתיעוד מופיעה לכך הדוגמה 9.6.0. תמונות רשמיות מתפרסמות ב-Docker Hub וב-GitHub Container Registry (ghcr.io/aldinokemal/go-whatsapp-web-multidevice). במסלול זה נשארים עם תמונת Docker Hub. בסיום ההרצה תקבלו כתובת מקומית ופרטי גישה לסריקת קוד ה-QR בדפדפן.
#מהלך ההרצה הצפוי
- הסוכן מוודא ש-Docker פעיל על המחשב.
- נוצרת תיקיית עבודה מקומית עם קובץ
docker-compose.ymlוסיסמת Basic Auth חזקה ואקראית. - קונטיינר ה-GOWA מופעל במצב
rest. - הסוכן מציג את כתובת הדפדפן (לדוגמה:
http://127.0.0.1:3000), שם המשתמש והסיסמה. - הסוכן עוצר את פעולתו וממתין לסריקת הברקוד באפליקציית וואטסאפ בטלפון.
#הטקסט המלא להעתקה
התקן עבורי על גבי מחשב זה את מנוע GOWA (פרויקט go-whatsapp-web-multidevice) כדי לחבר חשבון וואטסאפ ל-AI.
הסבר לי את הפעולות בעברית פשוטה ובהירה ללא ניקוד, והנחה אותי מה עלי ללחוץ בכל שלב.
הנחיות התקנה טכניות:
- התקנה באמצעות Docker בלבד (תמונה רשמית: aldinokemal2104/go-whatsapp-web-multidevice).
- פקודת הפעלה: rest (בגרסה 9 שרת ה-MCP זמין תחת מצב rest בנתיב /mcp).
- ממשק הדפדפן ו-REST API יהיו זמינים בכתובת מקומית בלבד.
הנחיות אבטחה מחייבות:
- האזנה אך ורק על כתובת מקומית 127.0.0.1 (פורט ברירת מחדל 3000 או 3100 אם תפוס). אין לחשוף את הפורט ל-0.0.0.0.
- יצירת סיסמת Basic Auth אקראית וחזקה. איסור מוחלט על סיסמאות ברירת מחדל כמו admin:admin.
- הצגת שם המשתמש והסיסמה פעם אחת בלבד במסך, ושמירתם בקובץ מקומי מאובטח מחוץ ל-git.
- הגדרת volume קבוע לספריית הנתונים (./data:/app/storages) כדי שהחיבור ומטמון הממשק יישמרו גם לאחר אתחול המחשב.
- הגדרת דגל --os עם שם מזהה ברור ("Claude GOWA") כדי שניתן יהיה לזהות את המכשיר בטלפון.
- ללא הגדרת Webhook ציבורי וללא מענה אוטומטי (autoreply).
לאחר עליית הקונטיינר:
1. בצע בדיקת בריאות (health check) מקומית.
2. הצג לי במדויק את כתובת הדפדפן לפתיחה.
3. הצג לי את שם המשתמש והסיסמה שיש להזין בחלון ההתחברות.
4. עצור כאן! אל תבצע פעולות נוספות או חיבורי MCP. השלב הבא הוא סריקת הברקוד בטלפון.
אם Docker אינו מותקן או שאינו פעיל, עצור והסבר לי כיצד להפעיל אותו בהתאם למערכת ההפעלה הנוכחית.#לאחר הרצת הפרומפט
קלוד קוד יוריד את תמונת ה-Docker, יפעיל את הקונטיינר ויציג סיכום ברור:
- כתובת ממשק הניהול בדפדפן.
- פרטי ה-Basic Auth (שם משתמש וסיסמה).
- הנחיה לפתוח את הדפדפן ולסרוק את קוד ה-QR.
שמרו את פרטי הגישה במנהל סיסמאות מאובטח.
בפרק הבא נלמד כיצד לבצע את סריקת קוד ה-QR באפליקציית וואטסאפ בטלפון הנייד.
#הגדרות ומשתני סביבה
לפי התיעוד הרשמי נכון ל-2026-11-02, סדר טעינת ההגדרות הוא:
- קודם מאותחלים דגלי שורת הפקודה.
- אחר כך מוחלים רוב משתני הסביבה. ערך סביבה שמוגדר יכול לדרוס את הדגל התואם.
- קובץ
.envממלא רק משתנים שעדיין לא הוגדרו בסביבת התהליך.
דגלים מפורשים מנצחים עבור הגדרות MCP OAuth, --allow-unauthenticated, --trusted-origins, --chatwoot-webhook-allow-unsigned ו---webhook-all-device-receipts. מגדירים כל אפשרות במקום אחד, כדי שלא יהיו ערכים סותרים. לדוגמה, WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY=true דורס --webhook-insecure-skip-verify=false.
לשימוש במשתני סביבה:
- מספריית השורש של המאגר, העתיקו את קובץ הדוגמה:
cp src/.env.example src/.env. - עדכנו את הערכים בקובץ
src/.envלפי הצורך. - לחלופין, הגדירו את אותם המשתנים בסביבת הריצה של התהליך.
להלן משתני הסביבה מתוך התיעוד הרשמי:
| משתנה | תיאור | ברירת מחדל | דוגמה |
|---|---|---|---|
APP_PORT | פורט היישום | 3000 | APP_PORT=8080 |
APP_HOST | כתובת מארח להאזנת השרת | 0.0.0.0 | APP_HOST=127.0.0.1 |
APP_DEBUG | הפעלת רישום ניפוי שגיאות | false | APP_DEBUG=true |
APP_OS | שם מערכת ההפעלה (שם המכשיר בוואטסאפ) | GOWA | APP_OS=MyApp |
APP_BASIC_AUTH | פרטי Basic Auth. נדרש בהאזנה שאינה loopback, עם שם משתמש וסיסמה בכל רשומה. על loopback השרת נשאר פתוח לפיתוח מקומי | ריק | APP_BASIC_AUTH=user1:pass1,user2:pass2 |
APP_ALLOW_UNAUTHENTICATED | חשיפת ה-API בלי Basic Auth בהאזנה שאינה loopback (לא מאובטח, עבור פרוקסי הפוך) | false | APP_ALLOW_UNAUTHENTICATED=true |
APP_TRUSTED_ORIGINS | מקורות דפדפן נוספים לבקשות שמשנות מצב (מארח הבקשה ומקורות CORS מפורשים כבר כלולים). פרוקסי שמשכתב Host צריך proxy_set_header Host $host, או APP_TRUSTED_PROXIES עם X-Forwarded-Host, או את המקור הציבורי כאן. מקורות אפליקציה והרחבה כמו capacitor://localhost מותאמים כפי שנכתבו. null אינו מהימן: gowa-ui שנפתח מכתובת file:// אינו יכול לבצע שינויים או לפתוח /ws, ולכן מגישים אותו מ-gowa (ברירת המחדל) או ממקור http(s) שרשום כאן | ריק | APP_TRUSTED_ORIGINS=https://ui.example.com |
APP_BASE_PATH | נתיב בסיס לפריסה תחת תת נתיב | ריק | APP_BASE_PATH=/gowa |
APP_TRUSTED_PROXIES | טווחי IP מהימנים של שרתי פרוקסי הפוך | ריק | APP_TRUSTED_PROXIES=0.0.0.0/0 |
APP_CORS_ALLOWED_ORIGINS | מקורות מורשים ב-CORS (ריק מאפשר כל מקור). תו כללי (*, ברירת המחדל) אינו מאשר בקשות שמשנות מצב או את /ws. לוח בקרה במקור נפרד חייב להופיע ב-APP_TRUSTED_ORIGINS או כאן כמקור מפורש | ריק | APP_CORS_ALLOWED_ORIGINS=https://ui.example.com |
APP_UI_ENABLED | הגשת לוח הבקרה gowa-ui שהורד | true | APP_UI_ENABLED=false |
APP_UI_AUTO_UPDATE | הורדה ורענון תקופתי של לוח הבקרה העדכני | true | APP_UI_AUTO_UPDATE=false |
APP_UI_REPO | מאגר GitHub המכיל את גרסאות gowa-ui | aldinokemal/gowa-ui | APP_UI_REPO=my-org/gowa-ui |
APP_UI_ASSET_NAME | שם קובץ הנכס של לוח הבקרה | gowa-ui.html | APP_UI_ASSET_NAME=gowa-ui.html |
APP_UI_UPDATE_INTERVAL | מרווח הזמן בין בדיקות עדכון של לוח הבקרה | 3h | APP_UI_UPDATE_INTERVAL=6h |
APP_UI_GITHUB_TOKEN | טוקן GitHub אופציונלי להגדלת מגבלת הבקשות ב-API | ריק | APP_UI_GITHUB_TOKEN=github_pat_xxx |
APP_UI_ASSET_SHA256 | חתימת SHA-256 אופציונלית לנעילת קובץ הנכס של לוח הבקרה | ריק | APP_UI_ASSET_SHA256=<hex-digest> |
MCP_ENABLED | הגשת נקודת קצה HTTP עם תמיכה בהזרמה של MCP בנתיב /mcp | true | MCP_ENABLED=false |
MCP_OAUTH_ENABLED | הפעלת אימות OAuth 2.1 עבור MCP | false | MCP_OAUTH_ENABLED=true |
MCP_OAUTH_ISSUER_URL | כתובת HTTPS ציבורית של מנפיק ה-OAuth | ריק | MCP_OAUTH_ISSUER_URL=https://gowa.example.com |
MCP_OAUTH_RESOURCE_URL | כתובת MCP ציבורית קנונית אופציונלית | נגזר מהמנפיק ומנתיב הבסיס | MCP_OAUTH_RESOURCE_URL=https://gowa.example.com/mcp |
MCP_OAUTH_DB_URI | כתובת SQLite עבור לקוחות OAuth, קודים וגיבובי טוקנים | file:storages/oauth.db | MCP_OAUTH_DB_URI=file:storages/oauth.db |
DB_URI | כתובת החיבור למסד הנתונים. כתובת Postgres בלי sslmode (או PGSSLMODE) משתמשת ב-verify-full למארח מרוחק וב-disable ליעדי loopback (localhost, 127.0.0.1, ::1) או לשקעי unix. sslmode=require שומר TLS בלי אימות | file:storages/whatsapp.db | DB_URI=postgres://user:pass@host/db |
DB_KEYS_URI | כתובת מסד נתונים אופציונלית למטמון מפתחות הצפנה ומפתחות הפעלה (השאירו ריק כדי להשתמש ב-DB_URI, הימנעו מאחסון בזיכרון בסביבת ייצור עקב אובדן מצב ההתחברות באתחול). כתובת Postgres מקבלת את אותה ברירת מחדל של sslmode כמו DB_URI | ריק | DB_KEYS_URI=file:storages/whatsapp-keys.db?_foreign_keys=on |
CHAT_STORAGE_MAX_OPEN_CONNS | מספר מרבי של חיבורי SQLite מקבילים לאחסון שיחות | 5 | CHAT_STORAGE_MAX_OPEN_CONNS=10 |
WHATSAPP_AUTO_REPLY | הודעת מענה אוטומטי | ריק | WHATSAPP_AUTO_REPLY="Auto reply message" |
WHATSAPP_AUTO_MARK_READ | סימון אוטומטי של הודעות נכנסות כנקראו | false | WHATSAPP_AUTO_MARK_READ=true |
WHATSAPP_AUTO_DOWNLOAD_MEDIA | הורדה אוטומטית של קובצי מדיה מהודעות נכנסות | true | WHATSAPP_AUTO_DOWNLOAD_MEDIA=false |
WHATSAPP_IGNORE_STATUS_MEDIA | התעלמות מהורדת מדיה מעדכוני סטטוס (status@broadcast) | false | WHATSAPP_IGNORE_STATUS_MEDIA=true |
WHATSAPP_AUTO_REJECT_CALL | דחייה אוטומטית של שיחות וואטסאפ נכנסות | false | WHATSAPP_AUTO_REJECT_CALL=true |
WHATSAPP_WEBHOOK | כתובות Webhook לאירועים (מופרדות בפסיקים) | ריק | WHATSAPP_WEBHOOK=https://webhook.site/xxx |
WHATSAPP_WEBHOOK_SECRET | סוד HMAC ל-Webhook. יוצרים אחד עם openssl rand -hex 32. ערך ריק או ערך שפורסם (secret, super-secret-key, your-private-key) מוחלף במפתח אקראי לתהליך | ריק | WHATSAPP_WEBHOOK_SECRET=<generated key> |
WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY | דילוג על אימות תעודת TLS עבור Webhook (לא מאובטח) | false | WHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY=true |
WHATSAPP_WEBHOOK_EVENTS | רשימה לבנה של אירועים להעברה (מופרדת בפסיקים, ריק מעביר הכל) | ריק | WHATSAPP_WEBHOOK_EVENTS=message,message.ack |
WHATSAPP_WEBHOOK_IGNORE_JIDS | מזהי JID או תווים כלליים לדילוג בהעברה (מופרדים בפסיקים) | ריק | [email protected] |
WHATSAPP_WEBHOOK_ALL_DEVICE_RECEIPTS | העברת כל אישורי המכשירים המקושרים. הצרכן מטפל בכפילויות ובעדכונים שלא לפי הסדר | false | WHATSAPP_WEBHOOK_ALL_DEVICE_RECEIPTS=true |
WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL | Webhook של מכשיר מתווסף לכתובות הגלובליות במקום להחליף אותן | false | WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL=true |
WHATSAPP_ACCOUNT_VALIDATION | הפעלת אימות חשבון | true | WHATSAPP_ACCOUNT_VALIDATION=false |
WHATSAPP_PRESENCE_ON_CONNECT | נוכחות בעת חיבור: available, unavailable או none | unavailable | WHATSAPP_PRESENCE_ON_CONNECT=unavailable |
WHATSAPP_PROXY | פרוקסי יוצא ל-WebSocket של וואטסאפ (SOCKS5/HTTP/HTTPS) | ריק | WHATSAPP_PROXY=socks5://user:pass@host:1080 |
WHATSAPP_PRESENCE_PULSE_ENABLED | הפעלת פעימת נוכחות יומית של available ו-unavailable | true | WHATSAPP_PRESENCE_PULSE_ENABLED=false |
WHATSAPP_PRESENCE_PULSE_INTERVAL | מרווח בין פעימות נוכחות | 24h | WHATSAPP_PRESENCE_PULSE_INTERVAL=24h |
WHATSAPP_PRESENCE_PULSE_DURATION | משך השהייה במצב available בכל פעימה | 5m | WHATSAPP_PRESENCE_PULSE_DURATION=5m |
CHATWOOT_ENABLED | הפעלת שילוב Chatwoot | false | CHATWOOT_ENABLED=true |
CHATWOOT_URL | כתובת מופע Chatwoot | ריק | CHATWOOT_URL=https://app.chatwoot.com |
CHATWOOT_API_TOKEN | טוקן גישה ל-API של Chatwoot | ריק | CHATWOOT_API_TOKEN=your-api-token |
CHATWOOT_ACCOUNT_ID | מזהה חשבון Chatwoot | ריק | CHATWOOT_ACCOUNT_ID=12345 |
CHATWOOT_INBOX_ID | מזהה תיבת דואר נכנס ב-Chatwoot | ריק | CHATWOOT_INBOX_ID=67890 |
CHATWOOT_DEVICE_ID | מזהה מכשיר וואטסאפ ל-Chatwoot (גיבוי למכשיר יחיד או לסביבה) | ריק | [email protected] |
CHATWOOT_ALLOWED_HOSTS | רשימת מארחי Chatwoot מותרים להגדרות לפי מכשיר (הגנה מפני SSRF) | ריק | CHATWOOT_ALLOWED_HOSTS=app.chatwoot.com,chat.example.com |
CHATWOOT_IMPORT_MESSAGES | סנכרון היסטוריית הודעות אל Chatwoot | false | CHATWOOT_IMPORT_MESSAGES=true |
CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES | מספר ימי היסטוריה לייבוא | 3 | CHATWOOT_DAYS_LIMIT_IMPORT_MESSAGES=7 |
CHATWOOT_IMPORT_DB_URI | כתובת PostgreSQL ישירה של Chatwoot לסנכרון היסטוריה | ריק | CHATWOOT_IMPORT_DB_URI=postgresql://user:pass@host:5432/chatwoot_production?sslmode=disable |
CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE | הוספת מציין מקום טקסט לשורות מדיה בייבוא ישיר למסד | true | CHATWOOT_IMPORT_PLACEHOLDER_MEDIA_MESSAGE=true |
CHATWOOT_IMPORT_MEDIA_WITH_REST | העלאת שורות מדיה מייבוא ישיר דרך REST של Chatwoot | false | CHATWOOT_IMPORT_MEDIA_WITH_REST=true |
CHATWOOT_AUTO_CREATE | יצירה או שימוש חוזר בתיבת API של Chatwoot בעת ההפעלה | false | CHATWOOT_AUTO_CREATE=true |
CHATWOOT_INBOX_NAME | שם התיבה כשאפשרות היצירה האוטומטית פעילה | WhatsApp | CHATWOOT_INBOX_NAME=WhatsApp Support |
CHATWOOT_WEBHOOK_URL | כתובת Webhook ציבורית לתשובות Chatwoot אל GOWA | ריק | CHATWOOT_WEBHOOK_URL=https://api.example.com/chatwoot/webhook |
CHATWOOT_WEBHOOK_SECRET | סוד לאימות חתימת Webhook נכנס מ-Chatwoot. ערך ריק דוחה את הקריאות | ריק | CHATWOOT_WEBHOOK_SECRET=channel-webhook-secret |
CHATWOOT_WEBHOOK_ALLOW_UNSIGNED | קבלת Webhook של Chatwoot כשאין סוד מוגדר (לא מאובטח) | false | CHATWOOT_WEBHOOK_ALLOW_UNSIGNED=true |
CHATWOOT_WEBHOOK_SIGNATURE_TOLERANCE | גיל מרבי של חותמת הזמן ב-Webhook חתום מ-Chatwoot | 5m | CHATWOOT_WEBHOOK_SIGNATURE_TOLERANCE=2m |
CHATWOOT_REOPEN_CONVERSATION | פתיחה מחדש של שיחות Chatwoot שנסגרו כשאיש קשר חוזר | true | CHATWOOT_REOPEN_CONVERSATION=false |
CHATWOOT_CONVERSATION_PENDING | יצירת שיחות Chatwoot חדשות במצב ממתין | false | CHATWOOT_CONVERSATION_PENDING=true |
CHATWOOT_IGNORE_JIDS | מזהי JID או תווים כלליים שלא יועברו ל-Chatwoot | ריק | [email protected],[email protected] |
CHATWOOT_SIGN_MSG | הוספת שם הסוכן לפני תשובות סוכן מ-Chatwoot | false | CHATWOOT_SIGN_MSG=true |
CHATWOOT_SIGN_DELIMITER | מפריד בין חתימת סוכן Chatwoot לגוף ההודעה | \n\n | CHATWOOT_SIGN_DELIMITER=" - " |
CHATWOOT_FORWARD_EDITS | שיקוף עריכות וואטסאפ להערות משורשרות ב-Chatwoot | true | CHATWOOT_FORWARD_EDITS=false |
CHATWOOT_FORWARD_DELETES | שיקוף מחיקה לכולם בוואטסאפ להערות ב-Chatwoot | true | CHATWOOT_FORWARD_DELETES=false |
CHATWOOT_MESSAGE_READ | סנכרון מצב נקרא בין הודעות וואטסאפ ו-Chatwoot מקושרות | false | CHATWOOT_MESSAGE_READ=true |
CHATWOOT_MESSAGE_DELETE | מחיקת ההודעה המקושרת בצד השני כשמדווחת מחיקה | false | CHATWOOT_MESSAGE_DELETE=true |
נתיבי Chatwoot נרשמים רק כאשר CHATWOOT_ENABLED=true. במסלול ההתקנה שבפרק זה לא מפעילים Chatwoot ולא Webhook.
#מלכודות שכדאי להכיר
- איחוד מצבי העבודה בגרסה 9: בעבר היה צורך להפעיל את השרת במצב נפרד עבור MCP (באמצעות תת הפקודה
whatsapp mcp). החל מגרסה 9 אין פקודתmcpעצמאית. מפעילים אך ורק./whatsapp rest, ומצב זה מגיש גם את ה-REST API וגם את שרת ה-MCP להזרמת HTTP בנתיב/mcp. אפשר לכבות את נקודת הקצה עםMCP_ENABLED=falseאו--mcp-enabled=false. ברירת המחדל היא פעיל. הכתובת המלאה היאhttp://<host>:<port><base-path>/mcp, ובברירת מחדלhttp://localhost:3000/mcp. במעבר מהמצב הישן,http://localhost:8080/sseמוחלפת בכתובת הזו. לפי רשימת הכלים בתיעוד הרשמי נכון ל-2026-11-02 יש שבעה כלים מאוחדים, והפעולה נבחרת בארגומנטtypeאוaction:whatsapp_send,whatsapp_schedule,whatsapp_message,whatsapp_chat,whatsapp_group,whatsapp_app,whatsapp_newsletter. פסקת המעבר באותו עמוד כותבת חמישה כלים.whatsapp_sendמקבל גםscheduled_at,timezone,recurrence,weekdays,day_of_month,end_atו-occurrence_limitכדי לתזמן שליחה, והניהול נעשה בכליwhatsapp_schedule. תזמונים שורדים אתחול וממתינים למכשיר לא מקוון. מופע שנכשל מנוסה שוב תחת אותו מזהה הודעה של וואטסאפ, כך ששליחה שאישור שלה אבד אינה נשלחת מחדש תחת זהות חדשה. גם ניסיונות חוזרים של סקר משתמשים בסוד שנשמר. מופעים בפרוטוקול החדש שהופסקו באתחול ממשיכים באותו אופן. ניסיונות ישנים עם תוצאה לא ידועה מדולגים או נכשלים. זה אינו מבטיח מסירה של פעם אחת בדיוק. מנויי מונים חיים של ערוצים נשמרים בזיכרון. אחרי אתחול השרת נרשמים אליהם מחדש, ואירועי המונה מגיעים כ-webhook מסוגnewsletter.message.POST /send/interactiveהוא ניסיוני, מיידי בלבד ו-REST בלבד (כפתורי native-flow, בקשת מיקום וקרוסלת תמונות). תאימות הנמען משתנה, ואין לו ערךtypeבתוךwhatsapp_send.
ערכי type ו-action לפי אותו עמוד, נכון ל-2026-11-02:
| כלי | ערכי type / action |
|---|---|
whatsapp_send | text, image, video, audio, document, sticker, location, contact, poll, link, forward |
whatsapp_schedule | list, get, pause, resume, cancel |
whatsapp_message | react, edit, revoke, delete, mark_read, mark_played, star, unstar, download_media |
whatsapp_chat | list_chats, list_contacts, get_messages, archive |
whatsapp_group | create, join_with_link, leave, info, participants, add_participants, remove_participants, promote, demote, invite_link, set_name, set_topic, set_settings, join_requests, manage_join_requests |
whatsapp_app | status, login_qr, login_code, logout, reconnect |
whatsapp_newsletter | follow, unfollow, info, directory, messages, message_updates, live_updates_subscribe, live_updates_unsubscribe, live_updates_list |
- הורדת ממשק הדפדפן בהפעלה ראשונה: לוח הבקרה אינו ארוז עוד בקוד השרת, אלא מנוהל במאגר נפרד בשם
aldinokemal/gowa-uiונמסר כקובץ יחיד בשםgowa-ui.html. בעת ההפעלה, ושוב בכלAPP_UI_UPDATE_INTERVAL(ברירת מחדל3h), השרת מוריד את גרסת לוח הבקרה העדכנית ביותר מ-releases/latest, מוודא שחתימת ה-SHA-256 תואמת למה ש-GitHub מפרסם, שומר אותו במטמון תחתstorages/ui/, ומגיש אותו בנתיב/מאחורי Basic Auth. חתימת הגרסה מוכיחה שההורדה תואמת לפרסום של GitHub. החתימה אינה מאמתת את זהות מי שפרסם את הקובץ. לכן נדרש חיבור רשת בעלייה הראשונה, וחובה למפות את ספרייתstoragesלנפח קבוע כדי למנוע הורדה חוזרת בכל אתחול.APP_UI_REPOעוקב תמיד אחרי הגרסה האחרונה של המאגר, בלי נעילת מספר גרסה. אפשר להפנות אותו למזלג שבשליטתכם, וגם אז העדכון עוקב אחרי הגרסה האחרונה של אותו מאגר.APP_UI_ASSET_SHA256הוא ההגדרה היחידה שנועלת בנייה מדויקת: לכל גרסה מצורף קובץ.sha256, והשרת יסרב לקובץ שהחתימה שלו שונה מהנעילה. בשרת בלי יציאה לרשת מניחים קובץgowa-ui.htmlשהורד מראש בנתיבstorages/ui/index.htmlומגדיריםAPP_UI_AUTO_UPDATE=false. אפשר גם לארח את לוח הבקרה כקבצים סטטיים במקום אחר ולהפנות אותו לכתובת השרת הזה, לפי ה-README של gowa-ui. כאשרAPP_UI_ENABLED=false, הנתיב/מחזיר באנר JSON והשרת נשאר API בלבד. - אובדן נתונים באחסון בזיכרון: התיעוד הרשמי מזהיר משימוש באחסון בזיכרון (in-memory) עבור מפתחות ההצפנה או מסד הנתונים בסביבת ייצור, מכיוון שכל אתחול עלול לגרום לאובדן מצב ההתחברות (session state) של וואטסאפ ולדרוש סריקת ברקוד מחודשת. אם המשתנה
DB_KEYS_URIנשאר ריק, השרת משתמש בערך המוגדר ב-DB_URI. לאחסון סשנים ומפתחות ב-PostgreSQL מנוהל, התיעוד הרשמי מפנה למדריך ההגדרה של Neon. כתובת Postgres בליsslmodeמקבלתverify-fullלמארח מרוחק ו-disableל-loopback או לשקע unix, ואותו כלל חל עלDB_KEYS_URI. - תמיכה בריבוי מכשירים ותחימת בקשות: החל מגרסה 8 נוספה תמיכה בחיבור חשבונות מרובים במקביל במופע שרת יחיד באמצעות נקודות קצה תחת
/devices. כל קריאת REST API המיועדת למכשיר מסוים דורשת כותרתX-Device-Idאו פרמטר שאילתהdevice_id. כאשר מחובר מכשיר אחד בלבד, הוא משמש כברירת מחדל ללא צורך לציין מזהה מכשיר מפורש. בחיבורי WebSocket יש לציין את המכשיר בנתיב:/ws?device_id=<id>. לפי התיעוד הרשמי, הפרמטר אינו מבודד אירועים בין חשבונות: רכזת ה-WebSocket הנוכחית משדרת אירועי לוח בקרה לכל המנויים המאומתים. לאינטגרציות יישומיות משתמשים ב-webhook לפי מכשיר. בחיבור לקוח MCP, אותה כותרתX-Device-Idבוחרת את המכשיר לכל קריאות הכלים באותו חיבור. קריאה בודדת יכולה לעקוף זאת בארגומנטdevice_id. - ממשק מרוחק ופרטי הזדהות ב-WebSocket: הגדרת CORS מאפשרת העברת כותרות
Authorizationו-X-Device-Id, כך שממשק רשת חיצוני יכול לפנות ישירות ל-API. תו כללי ב-CORS אינו מאשר בקשות שמשנות מצב או פתיחת/ws. לוח בקרה במקור נפרד נרשם ב-APP_TRUSTED_ORIGINSאו כמקור CORS מפורש. מקורnullאינו מהימן, ולכן קובץfile://של gowa-ui אינו יכול לבצע שינויים או לפתוח/ws.GET /app/infoמחזיר את גרסת השרת ואת מגבלות גודל המדיה. מאחר שדפדפנים אינם מאפשרים להגדיר כותרות בחיבורי WebSocket, כאשר Basic Auth מופעל יש להעביר את פרטי ההזדהות בנתיב ה-URL בצורה:/ws?device_id=<id>&authorization=<base64(user:pass)>. התיעוד הרשמי מבהיר כי במצב זה חובה להשתמש ב-TLS, כיוון שפרטי ההזדהות גלויים בכתובת ה-URL. - האזנה מקומית מול Basic Auth:
APP_BASIC_AUTHנדרש כשהשרת מאזין לכתובת שאינה loopback, וכל רשומה כוללת שם משתמש וסיסמה. על loopback השרת נשאר פתוח לפיתוח מקומי.APP_ALLOW_UNAUTHENTICATED=trueחושף את ה-API בלי Basic Auth גם מחוץ ל-loopback. במסלול הפרק הזה ההאזנה נשארת על127.0.0.1ועם סיסמה אקראית. - בדיקת הבריאות ונתיב בסיס:
GET /healthציבורי ותמיד רשום בנתיב השורש, גם כאשרAPP_BASE_PATHמוגדר.GET /app/metricsמאומת, ואינו דורש כותרת מכשיר. הוא מחזיר JSON על התהליך, הזיכרון, הדיסק, מספר המכשירים ומטא-דאטה של האחסון, ולא טקסט Prometheus. - נוכחות אחרי החיבור: ברירת המחדל של
WHATSAPP_PRESENCE_ON_CONNECTהיאunavailable, כלומר שם הדחיפה נרשם בלי מעבר למצב מקוון, וההתראות בטלפון נשמרות. הערךavailableמסמן את החשבון כמקוון ומדכא התראות בטלפון. הערךnoneמדלג על נוכחות לגמרי, ושם הדחיפה לא נרשם, כך שאנשי קשר עשויים לראות-כשם. פעימת הנוכחות פעילה כברירת מחדל (WHATSAPP_PRESENCE_PULSE_ENABLED=true): כל24hהחשבון נשארavailableלמשך5mואז חוזר ל-unavailable.POST /user/presence/subscribeנרשם לעדכוני מחובר או לא מחובר של איש קשר, והם מגיעים באירוע webhook בשםpresence. שליחת הנוכחות של החשבון עצמו נשארת ב-POST /send/presence. - תמונת פרופיל:
GET /user/avatarמבדיל בין404 AVATAR_NOT_SETל-403 AVATAR_HIDDEN. משתמשים בקוד השגיאה לפני שפוסלים תמונה שנשמרה במטמון. - צימוד Passkey: התיעוד הרשמי כולל גם
GET /app/passkey,POST /app/passkey/responseו-POST /app/passkey/confirm. מסלול ההתקנה בפרק זה נשאר סריקת QR. - Webhook לפי מכשיר: לכל מכשיר אפשר להגדיר כתובת ומסנני אירועים משלו דרך
PATCH /devices/:device_id/webhookעם{"webhook_url": "https://device-webhook.site/handler"}, ולקרוא אותם ב-GET /devices/:device_id/webhook. כשמוגדר Webhook למכשיר, אירועי המכשיר נשלחים לכתובת הזו. כשאין, הם נופלים ל-Webhook הגלובלי (--webhook). שרשורwebhook_urlריק ב-PATCHמנקה את ההגדרה ומחזיר את הגלובלי.WHATSAPP_WEBHOOK_DEVICE_MERGE_GLOBAL=true(או--webhook-device-merge-global=true) הופך את כתובת המכשיר לתוספת: הכתובות הגלובליות עדיין מקבלות את אירועי המכשיר, חתומות בסוד הגלובלי ומסוננות לפיWHATSAPP_WEBHOOK_EVENTS, וכתובת המכשיר שומרת סוד ומסנן משלה.WHATSAPP_WEBHOOK_IGNORE_JIDSמדלג על צ'אטים או שולחים לפני ההעברה, כולל תווים כלליים@g.us,@s.whatsapp.netו-@lid, בנפרד מסינון סוג האירוע.WHATSAPP_WEBHOOK_ALL_DEVICE_RECEIPTS=true(או--webhook-all-device-receipts) מעביר את כל אישורי המכשירים המקושרים, והצרכן מטפל בכפילויות ובעדכונים שלא לפי הסדר. ברירת המחדל היאfalse. כל גוף Webhook כולל שדה עליוןdevice_idשל המכשיר שקיבל את האירוע. הבקשה נושאת חתימת HMAC-SHA-256 בכותרתX-Hub-Signature-256. הסוד הישן שפורסם,secret, אינו בשימוש. אם לא הוגדר סוד, התהליך מייצר מפתח אקראי, רושם אזהרה, והמפתח משתנה בכל אתחול. ערך ריק או אחד מהערכים שפורסמו (secret,super-secret-key,your-private-key) מוחלף במפתח אקראי לתהליך. לסוד יציב מריצים פעם אחתopenssl rand -hex 32ומגדירים אותו ב---webhook-secretאו ב-WHATSAPP_WEBHOOK_SECRET. אירועי ה-webhook המתועדים הםmessage,message.reaction,message.revoked,message.edited,message.ack,message.deleted,presence(אחרי הרשמה לנוכחות איש קשר),chat_presence,group.participants,group.info,group.joined,label.edit,label.association,newsletter.joined,newsletter.left,newsletter.message(מונים חיים ממנוי פעיל),newsletter.mute,call.offer,device.logged_out(כולל הסיבה),device.temporary_banו-device.reachout_timelock. רשימה ריקה מעבירה את כולם. אם אימות תעודת TLS נכשל,--webhook-insecure-skip-verify=trueאוWHATSAPP_WEBHOOK_INSECURE_SKIP_VERIFY=trueמכבים את אימות התעודה. לפי התיעוד זה מתאים לפיתוח, לבדיקות, או לרשת פנימית עם תעודה בחתימה עצמית. מנהרת Cloudflare אינה הופכת חיבור TLS יוצא בלי אימות לבטוח. בייצור משתמשים בתעודה תקפה, למשל מ-Let's Encrypt. - תמיכה באפשרות אימות OAuth 2.1 עבור MCP: התיעוד הרשמי מציין אפשרות להפעיל אימות OAuth 2.1 עבור שרת ה-MCP באמצעות המשתנה
MCP_OAUTH_ENABLED=true. יכולת זו מיועדת לחיבור לקוחות MCP מרוחקים שאינם מסוגלים להעביר כותרת Basic Auth, והיא כבויה כברירת מחדל. כשהיא פעילה,/mcpמקבל טוקן Bearer או את פרטי ה-Basic Auth המוגדרים. OAuth אינו מאמת את נתיבי ה-REST או את ממשק הדפדפן. דגלי MCP OAuth המפורשים מנצחים את משתני הסביבה התואמים.