whatsapp-group-summary 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +395 -0
- package/SKILL.md +227 -0
- package/install.js +59 -0
- package/logo.jpg +0 -0
- package/package.json +16 -0
- package/references/bridge-api.md +27 -0
- package/references/record-all-group-messages.md +70 -0
- package/references/user-format-reference.md +41 -0
- package/references/verify-recording.md +27 -0
- package/references/whatsapp-bridge-limitations.md +34 -0
- package/references/whatsapp-group-ids.md +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
# ๐ค WhatsApp Group Summary Bot
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
> Bot ringkasan grup WhatsApp untuk **Hermes Agent** โ merekam **semua** chat anggota grup secara diam-diam dan mengirim ringkasan terstruktur **2x sehari** (07:00 & 23:00 WIB) dengan bahasa Indonesia santai.
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="https://img.shields.io/badge/Hermes-Agent-6C5CE7?style=flat-square" alt="Hermes Agent">
|
|
9
|
+
<img src="https://img.shields.io/badge/Platform-WhatsApp-25D366?style=flat-square&logo=whatsapp" alt="WhatsApp">
|
|
10
|
+
<img src="https://img.shields.io/badge/License-MIT-green?style=flat-square" alt="MIT License">
|
|
11
|
+
<img src="https://img.shields.io/badge/Language-ID-santai-orange?style=flat-square" alt="Bahasa Indonesia">
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## โจ Fitur
|
|
17
|
+
|
|
18
|
+
| Fitur | Deskripsi |
|
|
19
|
+
|-------|-----------|
|
|
20
|
+
| ๐ **Rekam Semua Chat** | Seluruh pesan dari **semua** anggota grup direkam ke JSONL โ bukan cuma user whitelist |
|
|
21
|
+
| ๐คซ **Silent Recording** | Bot tidak merespon chat biasa. Hanya aktif saat di-@mention atau ada perintah `/` |
|
|
22
|
+
| ๐ **Summary 2x Sehari** | Pagi (07:00 WIB) & malam (23:00 WIB) โ format terstruktur, padat, informatif |
|
|
23
|
+
| ๐ฅ **Mode Roast** | Opsional โ versi sarkas & lucu dari ringkasan buat suasana grup lebih hidup |
|
|
24
|
+
| ๐ฎ๐ฉ **Casual Indonesian** | Gaya bahasa santai (gw/lo), bukan formal โ cocok buat grup pertemanan |
|
|
25
|
+
| ๐ **Auto-detect Links** | Semua URL yang di-share otomatis tercantum di section Link-link |
|
|
26
|
+
| ๐ **Action Tracking** | Follow-up items & pertanyaan terbuka dicatat biar ga ada yang kelewat |
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## ๐ Contoh Output
|
|
31
|
+
|
|
32
|
+
### Mode Normal
|
|
33
|
+
```
|
|
34
|
+
*Summary General โ 12 jam terakhir*
|
|
35
|
+
- *Inti Diskusi*
|
|
36
|
+
- Ngobrolin tools AI: GPT 5.6 Sol, Codex, Claude vs ChatGPT 5 buat slicing UI
|
|
37
|
+
- Sharing repo token saver: oh-my-pi dari Nado dan paleo dari mmoaa
|
|
38
|
+
- Diskusi akses remote: Tailscale vs NetBird
|
|
39
|
+
- Info event Lovable + temp mail smailpro buat klaim kredit
|
|
40
|
+
- *Keputusan*
|
|
41
|
+
- Tidak ada keputusan formal.
|
|
42
|
+
- *Follow-up / Action*
|
|
43
|
+
- Pen?: cek detail deploy error
|
|
44
|
+
- Yanda Nooryuda: cek member/top hari ini
|
|
45
|
+
- mmoaa: minta stars buat repo paleo
|
|
46
|
+
- *Pertanyaan Terbuka*
|
|
47
|
+
- API Gmaps berbayar atau gratis?
|
|
48
|
+
- Sol udah masuk Codex official belum?
|
|
49
|
+
- Mending Tailscale atau NetBird buat remote?
|
|
50
|
+
- *Link-link*
|
|
51
|
+
- Nado: oh-my-pi token saver โ github.com/Fernado03/oh-my-pi-supreme-token-saver
|
|
52
|
+
- mmoaa: paleo token saver โ github.com/mocasus/paleo
|
|
53
|
+
- ไฝ ็ฎๅชๅๅฐ้ฅผๅนฒ๏ผ: bluk-cf auto CF โ github.com/iAm-182/bluk-cf
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Mode Roast ๐ฅ
|
|
57
|
+
```
|
|
58
|
+
*Summary Roast โ 12 jam terakhir ๐ฅ*
|
|
59
|
+
- *Yang Paling Nyablak*
|
|
60
|
+
- DickySusanto gas terus nanya Sol mulu, udah kayak sales GPT
|
|
61
|
+
- Pen? classic โ deploy error done tapi ga dicek
|
|
62
|
+
- *Drama & Perdebatan*
|
|
63
|
+
- Tailscale vs NetBird debat ga kelar-kelar, pada mau jadi superhero remote akses
|
|
64
|
+
- *Receh Tapi Menghibur*
|
|
65
|
+
- Azhar share link invite grup ke-15 kali ini
|
|
66
|
+
- *Keputusan (yg akhirnya diambil setelah debat panjang)*
|
|
67
|
+
- Ga ada. Seperti biasa.
|
|
68
|
+
- *PR Yang Belum Kelar*
|
|
69
|
+
- Pen?: deploy error masih menggantung
|
|
70
|
+
- Yanda: member check masih waiting
|
|
71
|
+
- *Pertanyaan Nyangkut*
|
|
72
|
+
- Gmaps bayar apa gratis? udah 3 hari ini pertanyaan yg sama
|
|
73
|
+
- *Link Berserakan*
|
|
74
|
+
- Nado: token saver โ github.com/Fernado03/oh-my-pi-supreme-token-saver
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## ๐๏ธ Arsitektur
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
83
|
+
โ WhatsApp Group โ
|
|
84
|
+
โ โโโโโโโ โโโโโโโ โโโโโโโ โโโโโโโ โ
|
|
85
|
+
โ โUser1โ โUser2โ โUser3โ โUserNโ ... โ
|
|
86
|
+
โ โโโโฌโโโ โโโโฌโโโ โโโโฌโโโ โโโโฌโโโ โ
|
|
87
|
+
โโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโผโโโโโโโโโโโโโโโโโ
|
|
88
|
+
โ โ โ โ
|
|
89
|
+
โผ โผ โผ โผ
|
|
90
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
91
|
+
โ Baileys Bridge (Node.js) โ
|
|
92
|
+
โ bridge.js โ !isGroup skip allowlistโ โโโ Patch A
|
|
93
|
+
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
|
|
94
|
+
โ
|
|
95
|
+
โผ
|
|
96
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
97
|
+
โ Python Adapter (Hermes) โ
|
|
98
|
+
โ whatsapp_common.py โ no allowlist โ โโโ Patch B
|
|
99
|
+
โ adapter.py โ _record_group_msg() โ โโโ Patch C
|
|
100
|
+
โโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโ
|
|
101
|
+
โ โ
|
|
102
|
+
โผ โผ
|
|
103
|
+
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
|
|
104
|
+
โ JSONL Logs โ โ Agent Response โ
|
|
105
|
+
โ group_logs/ โ โ (only @mention) โ
|
|
106
|
+
โ <id>.jsonl โ โ โ
|
|
107
|
+
โโโโโโโโโโฌโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโ
|
|
108
|
+
โ
|
|
109
|
+
โผ
|
|
110
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
111
|
+
โ Cron Jobs (2x daily) โ
|
|
112
|
+
โ 07:00 WIB โ Morning Summary โ
|
|
113
|
+
โ 23:00 WIB โ Evening Summary โ
|
|
114
|
+
โโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโ
|
|
115
|
+
โ
|
|
116
|
+
โผ
|
|
117
|
+
โโโโโโโโโโโโโโโโ
|
|
118
|
+
โ WhatsApp Group โ
|
|
119
|
+
โ (clean output)โ
|
|
120
|
+
โโโโโโโโโโโโโโโโ
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## ๐ฆ Instalasi
|
|
126
|
+
|
|
127
|
+
### Prasyarat
|
|
128
|
+
|
|
129
|
+
- **[Hermes Agent](https://github.com/NousResearch/hermes-agent)** terinstall & WhatsApp gateway berjalan
|
|
130
|
+
- **Akses terminal/SSH** ke server Hermes
|
|
131
|
+
- **Hermes sudah di-invite** ke grup WhatsApp target
|
|
132
|
+
- `git`, `curl`, `python3` tersedia
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
### Step 1: Install Skill
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Via npx (recommended)
|
|
140
|
+
npx github:mocasus/whatsapp-group-summary
|
|
141
|
+
|
|
142
|
+
# Atau via hermes skills install
|
|
143
|
+
hermes skills install https://raw.githubusercontent.com/mocasus/whatsapp-group-summary/main/SKILL.md
|
|
144
|
+
|
|
145
|
+
# Atau manual git clone
|
|
146
|
+
git clone https://github.com/mocasus/whatsapp-group-summary.git ~/.hermes/skills/whatsapp-group-summary-bot
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
### Step 2: Patch Source Files
|
|
152
|
+
|
|
153
|
+
> โ ๏ธ **PENTING:** Patch akan **hilang setiap `hermes update`**. Simpan repo ini dan re-apply setelah update. Gunakan skill `whatsapp-group-summary-bot` untuk auto-detect dan re-apply.
|
|
154
|
+
|
|
155
|
+
#### Patch A โ Bridge (`bridge.js`)
|
|
156
|
+
|
|
157
|
+
**File:** `~/.hermes/hermes-agent/scripts/whatsapp-bridge/bridge.js`
|
|
158
|
+
**Line:** ~637
|
|
159
|
+
|
|
160
|
+
```diff
|
|
161
|
+
- if (WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
162
|
+
+ if (!isGroup && WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Efek:** Bridge meneruskan pesan dari **semua** anggota grup, bukan cuma user whitelist.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
#### Patch B โ Adapter Logic (`whatsapp_common.py`)
|
|
170
|
+
|
|
171
|
+
**File:** `~/.hermes/hermes-agent/gateway/platforms/whatsapp_common.py`
|
|
172
|
+
**Line:** ~361-365
|
|
173
|
+
|
|
174
|
+
```diff
|
|
175
|
+
- # Only respond to whitelisted senders in groups
|
|
176
|
+
- if self._allow_from:
|
|
177
|
+
- sender_id = str(data.get("senderId") or ...)
|
|
178
|
+
- if sender_id and not self._matches_whatsapp_allowlist(...):
|
|
179
|
+
- return False
|
|
180
|
+
+ # NOTE: patched โ allowlist check skipped for groups.
|
|
181
|
+
+ # Only DMs are gated by WHATSAPP_ALLOWED_USERS.
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
**Efek:** Python adapter tidak memfilter pesan grup berdasarkan whitelist.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
#### Patch C โ Silent Recorder (`adapter.py`)
|
|
189
|
+
|
|
190
|
+
**File:** `~/.hermes/hermes-agent/plugins/platforms/whatsapp/adapter.py`
|
|
191
|
+
|
|
192
|
+
**Tambahkan method** sebelum `_build_message_event` (~line 1341):
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
def _record_group_message_sync(self, data):
|
|
196
|
+
"""Record all group messages to JSONL for cron summary (non-blocking)."""
|
|
197
|
+
try:
|
|
198
|
+
import json, os
|
|
199
|
+
chat_id = str(data.get("chatId") or "")
|
|
200
|
+
if not chat_id.endswith("@g.us"):
|
|
201
|
+
return
|
|
202
|
+
body = str(data.get("body") or "").strip()
|
|
203
|
+
if not body:
|
|
204
|
+
return
|
|
205
|
+
log_dir = os.path.expanduser("~/.hermes/platforms/whatsapp/group_logs")
|
|
206
|
+
os.makedirs(log_dir, exist_ok=True)
|
|
207
|
+
log_file = os.path.join(log_dir, f"{chat_id}.jsonl")
|
|
208
|
+
entry = {
|
|
209
|
+
"ts": data.get("timestamp", 0),
|
|
210
|
+
"sender": str(data.get("senderName") or data.get("senderId") or ""),
|
|
211
|
+
"body": body,
|
|
212
|
+
}
|
|
213
|
+
with open(log_file, "a") as f:
|
|
214
|
+
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
|
|
215
|
+
except Exception:
|
|
216
|
+
pass # never block message processing on logging failure
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Tambahkan di `_build_message_event`**, sebelum `if not self._should_process_message(data):`
|
|
220
|
+
|
|
221
|
+
```python
|
|
222
|
+
# PATCHED: Record all group messages for cron summary
|
|
223
|
+
if data.get("isGroup", False):
|
|
224
|
+
self._record_group_message_sync(data)
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Efek:** Setiap pesan grup ditulis ke file JSONL tanpa mengganggu processing normal.
|
|
228
|
+
|
|
229
|
+
---
|
|
230
|
+
|
|
231
|
+
### Step 3: Environment Variable
|
|
232
|
+
|
|
233
|
+
Tambahkan ke environment config Hermes:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
# Require @mention for bot response in groups (messages still recorded)
|
|
237
|
+
WHATSAPP_REQUIRE_MENTION=true
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
### Step 4: Restart Gateway
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
hermes gateway restart
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
> ๐ก Jika restart dari dalam gateway diblokir, jalankan dari **terminal SSH terpisah**.
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
### Step 5: Verifikasi
|
|
253
|
+
|
|
254
|
+
Kirim **satu pesan test** di grup WhatsApp mana pun, lalu:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# Cek file log per grup
|
|
258
|
+
ls -la ~/.hermes/platforms/whatsapp/group_logs/
|
|
259
|
+
|
|
260
|
+
# Lihat isi log (ganti <chat_id> dgn ID grup)
|
|
261
|
+
cat ~/.hermes/platforms/whatsapp/group_logs/<chat_id>@g.us.jsonl | tail -5
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Harusnya muncul pesan test tadi dengan format JSON:
|
|
265
|
+
```json
|
|
266
|
+
{"ts": 1783736100, "sender": "Nama Kamu", "body": "test"}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
### Step 6: Setup Cron Jobs
|
|
272
|
+
|
|
273
|
+
#### 6a. Dapatkan Group ID
|
|
274
|
+
|
|
275
|
+
Tag Hermes di grup target: **"apa id grup ini?"**
|
|
276
|
+
Hermes akan membalas dengan format `` `123456789@g.us` ``
|
|
277
|
+
|
|
278
|
+
#### 6b. Buat Cron Jobs via Hermes
|
|
279
|
+
|
|
280
|
+
```
|
|
281
|
+
Morning: schedule = 0 0 * * * (07:00 WIB)
|
|
282
|
+
Evening: schedule = 0 16 * * * (23:00 WIB)
|
|
283
|
+
Deliver: whatsapp:<chat_id>@g.us
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**Prompt Normal:**
|
|
287
|
+
```
|
|
288
|
+
Kamu adalah bot ringkasan. HANYA OUTPUT RINGKASAN. Baca ~/.hermes/platforms/whatsapp/group_logs/<CHAT_ID>.jsonl, filter 12 jam (ts=UNIX timestamp). TANPA blank line:
|
|
289
|
+
|
|
290
|
+
*Summary General โ 12 jam terakhir*
|
|
291
|
+
- *Inti Diskusi*
|
|
292
|
+
- [rangkum per topik, gabungin chat mirip]
|
|
293
|
+
- *Keputusan*
|
|
294
|
+
- [keputusan atau "Tidak ada keputusan formal."]
|
|
295
|
+
- *Follow-up / Action*
|
|
296
|
+
- [Nama]: [action]
|
|
297
|
+
- *Pertanyaan Terbuka*
|
|
298
|
+
- [pertanyaan]
|
|
299
|
+
- *Link-link*
|
|
300
|
+
- [Nama]: [desc] โ [URL]
|
|
301
|
+
|
|
302
|
+
ATURAN: No metadata, no blank line, no job info. HANYA ringkasan. Nama dari field "sender". Bahasa Indonesia santai.
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## ๐ฅ Mode Roast
|
|
308
|
+
|
|
309
|
+
Untuk mengaktifkan versi sarkas/lucu, update prompt cron job dengan:
|
|
310
|
+
|
|
311
|
+
```
|
|
312
|
+
Kamu adalah bot ringkasan versi ROAST. Gaya: sarkas, lucu, roasting anggota grup tapi tetap friendly โ kayak temen yg galak tapi sayang.
|
|
313
|
+
|
|
314
|
+
*Summary Roast โ 12 jam terakhir ๐ฅ*
|
|
315
|
+
- *Yang Paling Nyablak*
|
|
316
|
+
- [siapa paling rame + roast ringan]
|
|
317
|
+
- *Drama & Perdebatan*
|
|
318
|
+
- [topik panas + komentar sarkas]
|
|
319
|
+
- *Receh Tapi Menghibur*
|
|
320
|
+
- [chat random lucu/absurd]
|
|
321
|
+
- *Keputusan (yg akhirnya diambil setelah debat panjang)*
|
|
322
|
+
- [keputusan]
|
|
323
|
+
- *PR Yang Belum Kelar*
|
|
324
|
+
- [Nama]: [action + roast]
|
|
325
|
+
- *Pertanyaan Nyangkut*
|
|
326
|
+
- [pertanyaan + "ada yg bisa jawab ga nih?"]
|
|
327
|
+
- *Link Berserakan*
|
|
328
|
+
- [Nama]: [desc] โ [URL]
|
|
329
|
+
|
|
330
|
+
ATURAN: Roast friendly, bukan bully. No metadata, no blank line.
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Toggle via Hermes: **"ubah <nama_grup> ke mode roast"** / **"balikin <nama_grup> ke normal"**
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## ๐ Struktur Repo
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
whatsapp-group-summary/
|
|
341
|
+
โโโ README.md โ Kamu di sini
|
|
342
|
+
โโโ logo.jpg โ Logo bot
|
|
343
|
+
โโโ SKILL.md โ Skill utama (Hermes format)
|
|
344
|
+
โโโ references/
|
|
345
|
+
โโโ bridge-api.md โ WhatsApp bridge API reference
|
|
346
|
+
โโโ record-all-group-messages.md โ Recording architecture detail
|
|
347
|
+
โโโ user-format-reference.md โ Format referensi dari user
|
|
348
|
+
โโโ verify-recording.md โ Langkah verifikasi recording
|
|
349
|
+
โโโ whatsapp-bridge-limitations.md โ Batasan bridge WhatsApp
|
|
350
|
+
โโโ whatsapp-group-ids.md โ Daftar ID grup yang di-manage
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
---
|
|
354
|
+
|
|
355
|
+
## ๐ ๏ธ Troubleshooting
|
|
356
|
+
|
|
357
|
+
| Gejala | Penyebab | Solusi |
|
|
358
|
+
|--------|----------|--------|
|
|
359
|
+
| `group_logs/` kosong | Patch A/B/C belum applied | Re-apply patch, restart gateway |
|
|
360
|
+
| Recording jalan tapi bot tetep respon | `WHATSAPP_REQUIRE_MENTION` belum di-set | Pastikan ada di `.env`, restart gateway |
|
|
361
|
+
| Cron output ada `Cronjob Response:...` | Normal โ hanya muncul di DM delivery | Delivery ke grup WhatsApp langsung clean |
|
|
362
|
+
| Patch hilang setelah `hermes update` | Update menimpa source | Re-apply patch A/B/C setiap update |
|
|
363
|
+
| `gateway restart` diblokir | Berjalan dari dalam session Hermes | Restart dari terminal SSH terpisah |
|
|
364
|
+
| Blank lines di output summary | Prompt kurang "TANPA blank line" | Update prompt โ tambahkan constraint |
|
|
365
|
+
| Bridge ga kirim pesan grup | `WHATSAPP_GROUP_POLICY` bukan `open` | Set `WHATSAPP_GROUP_POLICY=open` di `.env` |
|
|
366
|
+
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## โก Quick Re-Apply After Update
|
|
370
|
+
|
|
371
|
+
Setelah `hermes update`, jalankan:
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
# Re-apply semua patch dari repo
|
|
375
|
+
cd ~/.hermes/skills/whatsapp-group-summary-bot
|
|
376
|
+
# Patch A: bridge.js
|
|
377
|
+
sed -i 's/if (WHATSAPP_DM_POLICY/if (!isGroup \&\& WHATSAPP_DM_POLICY/' \
|
|
378
|
+
~/.hermes/hermes-agent/scripts/whatsapp-bridge/bridge.js
|
|
379
|
+
# Restart gateway
|
|
380
|
+
hermes gateway restart
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
> Patch B & C perlu di-apply manual karena lebih kompleks. Cek `SKILL.md` untuk detail.
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## ๐ License
|
|
388
|
+
|
|
389
|
+
MIT ยฉ [mocasus](https://github.com/mocasus)
|
|
390
|
+
|
|
391
|
+
---
|
|
392
|
+
|
|
393
|
+
<p align="center">
|
|
394
|
+
<sub>Dibuat dengan โ dan sedikit roasting ๐ฅ</sub>
|
|
395
|
+
</p>
|
package/SKILL.md
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: whatsapp-group-summary-bot
|
|
3
|
+
description: Setup WhatsApp group summary bot โ records all messages silently via patched bridge+adapter, reads from JSONL logs, sends structured twice-daily summaries (07:00 & 23:00 WIB) in clean WhatsApp-friendly format (no metadata, no blank lines, casual Indonesian).
|
|
4
|
+
triggers:
|
|
5
|
+
- User wants auto-summary or "ringkasan" for WhatsApp group
|
|
6
|
+
- User shares WhatsApp group invite link with summary request
|
|
7
|
+
- User says "set summary" or "summary bot" in group/DM
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# WhatsApp Group Summary Bot
|
|
11
|
+
|
|
12
|
+
Two parts: **(A) message recording** via patched bridge/adapter โ JSONL, **(B) cron jobs** that read JSONL and deliver summaries.
|
|
13
|
+
|
|
14
|
+
โ ๏ธ **Core patches required.** WhatsApp normally only forwards @mentioned or whitelisted-user messages. Three source files must be patched to record ALL messages silently. Patches WILL be overwritten on `hermes update` โ re-apply after updates.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Part A: Message Recording (One-Time Setup)
|
|
19
|
+
|
|
20
|
+
### A1. Bridge โ `bridge.js`
|
|
21
|
+
|
|
22
|
+
Patch: `Hermes `scripts/whatsapp-bridge/bridge.js`` ~line 637
|
|
23
|
+
|
|
24
|
+
**Before:**
|
|
25
|
+
```js
|
|
26
|
+
if (WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
27
|
+
```
|
|
28
|
+
**After (add `!isGroup &&`):**
|
|
29
|
+
```js
|
|
30
|
+
if (!isGroup && WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### A2. Adapter Logic โ `whatsapp_common.py`
|
|
34
|
+
|
|
35
|
+
Patch: `~/.hermes/hermes-agent/gateway/platforms/whatsapp_common.py` ~lines 361-365
|
|
36
|
+
|
|
37
|
+
Remove the group allowlist check โ replace with comment noting the patch.
|
|
38
|
+
|
|
39
|
+
### A3. Silent Recorder โ `adapter.py`
|
|
40
|
+
|
|
41
|
+
Patch: `~/.hermes/hermes-agent/plugins/platforms/whatsapp/adapter.py`
|
|
42
|
+
|
|
43
|
+
Add method before `_build_message_event`:
|
|
44
|
+
```python
|
|
45
|
+
def _record_group_message_sync(self, data):
|
|
46
|
+
try:
|
|
47
|
+
import json, os
|
|
48
|
+
chat_id = str(data.get("chatId") or "")
|
|
49
|
+
if not chat_id.endswith("@g.us"): return
|
|
50
|
+
body = str(data.get("body") or "").strip()
|
|
51
|
+
if not body: return
|
|
52
|
+
log_dir = os.path.expanduser("~/.hermes/platforms/whatsapp/group_logs")
|
|
53
|
+
os.makedirs(log_dir, exist_ok=True)
|
|
54
|
+
entry = {"ts": data.get("timestamp", 0), "sender": str(data.get("senderName") or data.get("senderId") or ""), "body": body}
|
|
55
|
+
with open(os.path.join(log_dir, f"{chat_id}.jsonl"), "a") as f:
|
|
56
|
+
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
|
|
57
|
+
except Exception: pass
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
In `_build_message_event`, before `_should_process_message` check:
|
|
61
|
+
```python
|
|
62
|
+
if data.get("isGroup", False):
|
|
63
|
+
self._record_group_message_sync(data)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### A4. Env
|
|
67
|
+
|
|
68
|
+
Add to the Hermes environment config file:
|
|
69
|
+
|
|
70
|
+
### A5. Restart
|
|
71
|
+
|
|
72
|
+
`hermes gateway restart` from **external terminal** (cannot restart from inside gateway).
|
|
73
|
+
|
|
74
|
+
**Verify:** send test message in any group โ `ls ~/.hermes/platforms/whatsapp/group_logs/` should show `<chat_id>.jsonl` with your message.
|
|
75
|
+
See `references/verify-recording.md` for full checklist.
|
|
76
|
+
|
|
77
|
+
### A6. Reference Files
|
|
78
|
+
|
|
79
|
+
- `references/bridge-api.md` โ bridge HTTP API: group name lookup, recording status
|
|
80
|
+
- `references/verify-recording.md` โ step-by-step verification after patch + restart
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
## Part B: Cron Jobs
|
|
85
|
+
|
|
86
|
+
### B1. Get Group Info
|
|
87
|
+
|
|
88
|
+
- **Invite link**: `curl -sL "URL" | grep -oP '(?<=og:title" content=")[^"]+'`
|
|
89
|
+
- **Group ID**: tag Hermes in group with "apa id grup ini?" โ answer `\`<id>@g.us\``, nothing else
|
|
90
|
+
- **User MUST add Hermes to group manually** โ invite links don't work for bots
|
|
91
|
+
|
|
92
|
+
### B2. Create Jobs
|
|
93
|
+
|
|
94
|
+
| Job | Cron (UTC) | WIB |
|
|
95
|
+
|-----|-----------|-----|
|
|
96
|
+
| Morning | `0 0 * * *` | 07:00 |
|
|
97
|
+
| Evening | `0 16 * * *` | 23:00 |
|
|
98
|
+
|
|
99
|
+
Deliver to `whatsapp:<chat_id>@g.us` **immediately** โ never use `origin` as placeholder.
|
|
100
|
+
|
|
101
|
+
### B3. Cron Prompt
|
|
102
|
+
|
|
103
|
+
**Normal mode (default):**
|
|
104
|
+
```
|
|
105
|
+
Kamu adalah bot ringkasan. HANYA OUTPUT RINGKASAN. Baca ~/.hermes/platforms/whatsapp/group_logs/<CHAT_ID>.jsonl, filter 12 jam (ts=UNIX timestamp integer). TANPA blank line:
|
|
106
|
+
|
|
107
|
+
*Summary General โ 12 jam terakhir*
|
|
108
|
+
- *Inti Diskusi*
|
|
109
|
+
- [rangkum per topik, gabungin chat mirip]
|
|
110
|
+
- *Keputusan*
|
|
111
|
+
- [keputusan atau "Tidak ada keputusan formal."]
|
|
112
|
+
- *Follow-up / Action*
|
|
113
|
+
- [Nama]: [action]
|
|
114
|
+
- *Pertanyaan Terbuka*
|
|
115
|
+
- [pertanyaan]
|
|
116
|
+
- *Link-link*
|
|
117
|
+
- [Nama]: [desc] โ [URL]
|
|
118
|
+
|
|
119
|
+
ATURAN: No metadata, no blank line, no job info. HANYA ringkasan. Nama dari field "sender". Bahasa Indonesia santai.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Roast mode (๐ฅ ๆฏ่):**
|
|
123
|
+
```
|
|
124
|
+
Kamu adalah bot ringkasan versi ROAST. HANYA OUTPUT RINGKASAN. Baca ~/.hermes/platforms/whatsapp/group_logs/<CHAT_ID>.jsonl, filter 12 jam. TANPA blank line. Gaya: sarkas, lucu, roasting anggota grup tapi tetap friendly, kayak temen yg galak tapi sayang.
|
|
125
|
+
|
|
126
|
+
*Summary Roast โ 12 jam terakhir ๐ฅ*
|
|
127
|
+
- *Yang Paling Nyablak*
|
|
128
|
+
- [siapa paling rame + roasts ringan]
|
|
129
|
+
- *Drama & Perdebatan*
|
|
130
|
+
- [topik panas dibahas + komentar sarkas]
|
|
131
|
+
- *Receh Tapi Menghibur*
|
|
132
|
+
- [chat random yg lucu/absurd]
|
|
133
|
+
- *Keputusan (yg akhirnya diambil setelah debat panjang)*
|
|
134
|
+
- [keputusan + komentar]
|
|
135
|
+
- *PR Yang Belum Kelar*
|
|
136
|
+
- [Nama]: [action item + roast ringan]
|
|
137
|
+
- *Pertanyaan Nyangkut*
|
|
138
|
+
- [pertanyaan + "ada yg bisa jawab ga nih?"]
|
|
139
|
+
- *Link Berserakan*
|
|
140
|
+
- [Nama]: [desc] โ [URL]
|
|
141
|
+
|
|
142
|
+
ATURAN: No metadata, no blank line, no job info. Roast friendly โ bukan bully. Bahasa Indonesia santai + sarkas.
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### B4. Toggle Mode (On/Off)
|
|
146
|
+
|
|
147
|
+
To switch a group's summary to roast mode:
|
|
148
|
+
```
|
|
149
|
+
cronjob(action='update', job_id='<job_id>', prompt='<roast prompt above>')
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
To switch back to normal:
|
|
153
|
+
```
|
|
154
|
+
cronjob(action='update', job_id='<job_id>', prompt='<normal prompt above>')
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
User can say: "ubah MOCA PARTY ke mode roast" or "balikin hd ke normal" โ agent updates the 2 cron jobs for that group.
|
|
158
|
+
|
|
159
|
+
### B5. User Style
|
|
160
|
+
|
|
161
|
+
- **Casual Indonesian** โ "gw", "lo", "dong", "ya", "nih", "rame bahas", "muter di", "belum jelas"
|
|
162
|
+
- **Zero metadata** โ no "Cronjob Response", job_id, "Catatan teknis", "To stop..."
|
|
163
|
+
- **No blank lines** between sections โ WhatsApp renders double newlines as ugly gaps. This is the #1 format bug the user catches. Every line in the summary MUST be a consecutive dash-prefix line with ZERO blank separators anywhere.
|
|
164
|
+
- **Direct & short** โ user hates verbosity ("ribet"). Never add explanatory notes, setup context, or disclaimers to the summary.
|
|
165
|
+
- **Group similar chats** โ merge related messages into 3-5 topic bullets under Inti Diskusi, not one bullet per message.
|
|
166
|
+
- **Honest about gaps** โ write "belum ada jawaban jelas" or "tidak ada solusi valid" when appropriate; never fabricate closure.
|
|
167
|
+
|
|
168
|
+
### B6. Group Behavior (Anti-Ribet Rule)
|
|
169
|
+
|
|
170
|
+
When tagged in a WhatsApp group with **"apa id grup ini?"** or similar bare ID request:
|
|
171
|
+
- Reply with **just the ID**: `` `120363XXXXXXX@g.us` `` โ no quotes, no bold, just inline code
|
|
172
|
+
- Do NOT add: explanations, "mau dipake buat apa?", skill loading, setup offers, follow-up questions
|
|
173
|
+
- Do NOT load this skill unless explicitly asked to "set summary"
|
|
174
|
+
- Speed > conversation โ user finds verbose group responses deeply frustrating ("kenapa responmu ribet?")
|
|
175
|
+
|
|
176
|
+
### B7. Reference Format
|
|
177
|
+
|
|
178
|
+
See [references/user-format-reference.md](references/user-format-reference.md) for the user's canonical summary example. Match the tone, grouping style, and section structure from that reference closely.
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Pitfalls
|
|
183
|
+
|
|
184
|
+
| Issue | Fix |
|
|
185
|
+
|-------|-----|
|
|
186
|
+
| Patches overwritten on `hermes update` | Re-apply A1-A3 after update |
|
|
187
|
+
| Gateway restart from inside blocked | Use external SSH terminal |
|
|
188
|
+
| Bridge auto-restarts, Python doesn't | Full `hermes gateway restart` needed for Python changes |
|
|
189
|
+
| JSONL timestamps are UNIX epoch ints | Don't try ISO parsing; compare integer timestamps |
|
|
190
|
+
| Blank lines in output | "TANPA blank line" in prompt is critical |
|
|
191
|
+
| Cron delivery header `Cronjob Response: ...` | Only appears in origin/DM delivery; group delivery (`whatsapp:...`) is clean |
|
|
192
|
+
| "Ribet" group responses | When tagged for "apa id grup", reply with just `` `120363XXXX@g.us` `` โ no explanation, no skill loading |
|
|
193
|
+
| Non-whitelisted member chat not recording | Verify 3 patches (A1-A3) applied + gateway restarted from external terminal. Bridge auto-restarts but Python adapter needs full `hermes gateway restart` |
|
|
194
|
+
| Group name mismatch | Verify with `curl localhost:3000/chat/<id>@g.us` (see bridge-api.md) |
|
|
195
|
+
| Summary too verbose / one bullet per message | Merge related chats into 3-5 topic bullets; group by theme, not sender |
|
|
196
|
+
| Recording broken after gateway restart | Check `grep \"_build_message_event returned None\" gateway.log` โ if present, Python patch not applied. Also verify `ls ~/.hermes/platforms/whatsapp/group_logs/` after sending test message |
|
|
197
|
+
| Group name mislabeled | Use `curl localhost:3000/chat/<id>@g.us` to get real WhatsApp name; user often uses shortened names |
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Example Output
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
*Summary General โ 12 jam terakhir*
|
|
205
|
+
- *Inti Diskusi*
|
|
206
|
+
- Ngobrolin tools AI: GPT 5.6 Sol, Codex, Claude vs ChatGPT 5
|
|
207
|
+
- Sharing repo token saver: oh-my-pi dan paleo
|
|
208
|
+
- Diskusi akses remote: Tailscale vs NetBird
|
|
209
|
+
- *Keputusan*
|
|
210
|
+
- Tidak ada keputusan formal.
|
|
211
|
+
- *Follow-up / Action*
|
|
212
|
+
- Pen?: cek detail deploy error
|
|
213
|
+
- Yanda Nooryuda: cek member/top hari ini
|
|
214
|
+
- *Pertanyaan Terbuka*
|
|
215
|
+
- API Gmaps berbayar atau gratis?
|
|
216
|
+
- Sol udah masuk Codex official?
|
|
217
|
+
- *Link-link*
|
|
218
|
+
- Nado: token saver โ github.com/Fernado03/oh-my-pi-supreme-token-saver
|
|
219
|
+
- mmoaa: paleo โ github.com/mocasus/paleo
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Resources
|
|
225
|
+
|
|
226
|
+
- **GitHub repo:** https://github.com/mocasus/whatsapp-group-summary โ standalone repo with full README + installation guide
|
|
227
|
+
- **Skill location:** `~/.hermes/skills/whatsapp-group-summary-bot/SKILL.md`
|
package/install.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* WhatsApp Group Summary Bot โ Installer
|
|
4
|
+
*
|
|
5
|
+
* Usage: npx whatsapp-group-summary
|
|
6
|
+
*
|
|
7
|
+
* Copies the skill to ~/.hermes/skills/whatsapp-group-summary-bot
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const { execSync } = require('child_process');
|
|
13
|
+
|
|
14
|
+
const SKILL_NAME = 'whatsapp-group-summary-bot';
|
|
15
|
+
const HERMES_HOME = process.env.HERMES_HOME || path.join(require('os').homedir(), '.hermes');
|
|
16
|
+
const TARGET_DIR = path.join(HERMES_HOME, 'skills', SKILL_NAME);
|
|
17
|
+
const REPO_URL = 'https://github.com/mocasus/whatsapp-group-summary.git';
|
|
18
|
+
|
|
19
|
+
console.log('๐ค WhatsApp Group Summary Bot โ Installer');
|
|
20
|
+
console.log(` Target: ${TARGET_DIR}\n`);
|
|
21
|
+
|
|
22
|
+
if (fs.existsSync(TARGET_DIR)) {
|
|
23
|
+
console.log('โ ๏ธ Skill already exists. Updating...');
|
|
24
|
+
try {
|
|
25
|
+
execSync(`git -C "${TARGET_DIR}" pull`, { stdio: 'inherit' });
|
|
26
|
+
console.log('โ
Updated successfully!');
|
|
27
|
+
} catch {
|
|
28
|
+
console.log('โ ๏ธ Git pull failed. Re-cloning...');
|
|
29
|
+
fs.rmSync(TARGET_DIR, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!fs.existsSync(TARGET_DIR)) {
|
|
34
|
+
console.log('๐ฆ Cloning skill...');
|
|
35
|
+
try {
|
|
36
|
+
execSync(`git clone "${REPO_URL}" "${TARGET_DIR}"`, { stdio: 'inherit' });
|
|
37
|
+
console.log('โ
Skill installed!');
|
|
38
|
+
} catch (e) {
|
|
39
|
+
console.error('โ Failed to clone. Trying manual copy...');
|
|
40
|
+
fs.mkdirSync(TARGET_DIR, { recursive: true });
|
|
41
|
+
const sourceDir = path.join(__dirname, '..');
|
|
42
|
+
const files = fs.readdirSync(sourceDir);
|
|
43
|
+
for (const file of files) {
|
|
44
|
+
if (file === 'node_modules' || file === '.git' || file === 'package.json') continue;
|
|
45
|
+
const src = path.join(sourceDir, file);
|
|
46
|
+
const dest = path.join(TARGET_DIR, file);
|
|
47
|
+
fs.cpSync(src, dest, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
console.log('โ
Skill installed (manual copy)!');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
console.log('\n๐ Next steps:');
|
|
54
|
+
console.log(' 1. Apply 3 source patches (see README)');
|
|
55
|
+
console.log(' 2. Set WHATSAPP_REQUIRE_MENTION=true in Hermes env');
|
|
56
|
+
console.log(' 3. Restart gateway: hermes gateway restart');
|
|
57
|
+
console.log(' 4. Tag @Hermes in group: "apa id grup ini?"');
|
|
58
|
+
console.log(' 5. Setup 2 cron jobs (morning 07:00 + evening 23:00 WIB)');
|
|
59
|
+
console.log('\n Full guide: https://github.com/mocasus/whatsapp-group-summary');
|
package/logo.jpg
ADDED
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "whatsapp-group-summary",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "WhatsApp group chat summary bot for Hermes Agent โ record all messages silently, auto-summarize 2x daily",
|
|
5
|
+
"main": "install.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"whatsapp-group-summary": "./install.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": ["hermes-agent", "whatsapp", "summary", "group-chat", "bot"],
|
|
10
|
+
"author": "mocasus",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/mocasus/whatsapp-group-summary.git"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# WhatsApp Bridge API โ Quick Reference
|
|
2
|
+
|
|
3
|
+
When Hermes WhatsApp gateway is running, the Baileys bridge exposes an HTTP API for querying chat/group info.
|
|
4
|
+
|
|
5
|
+
## Get group name by ID
|
|
6
|
+
|
|
7
|
+
Query the bridge chat endpoint with the group ID:
|
|
8
|
+
```
|
|
9
|
+
GET /chat/<chat_id>
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
The bridge returns JSON with `name`, `isGroup`, `participants`, and other group metadata.
|
|
13
|
+
|
|
14
|
+
## Get names for all recorded groups
|
|
15
|
+
|
|
16
|
+
Iterate over JSONL log files and query each group's chat endpoint to retrieve the group name.
|
|
17
|
+
|
|
18
|
+
## JSONL format
|
|
19
|
+
|
|
20
|
+
Each line in the log file is a JSON object:
|
|
21
|
+
```json
|
|
22
|
+
{"ts": 1783736100, "sender": "Display Name", "body": "message text"}
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- `ts` = UNIX timestamp (integer, seconds)
|
|
26
|
+
- `sender` = WhatsApp display name
|
|
27
|
+
- `body` = message text (stickers show `"[Sticker]"`)
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Recording ALL Group Members' Messages on WhatsApp
|
|
2
|
+
|
|
3
|
+
By default, Hermes WhatsApp has a **double filter** that blocks group messages from non-whitelisted users:
|
|
4
|
+
|
|
5
|
+
1. **Bridge (Node.js)**: `bridge.js` line 637 โ `matchesAllowedUser(senderId, ALLOWED_USERS, ...)`
|
|
6
|
+
2. **Adapter (Python)**: `whatsapp_common.py` lines 361-365 โ `_matches_whatsapp_allowlist(sender_id, self._allow_from)`
|
|
7
|
+
|
|
8
|
+
This means only users listed in `WHATSAPP_ALLOWED_USERS` have their group messages recorded. All other members are silently dropped.
|
|
9
|
+
|
|
10
|
+
## The Fix (3 changes + restart)
|
|
11
|
+
|
|
12
|
+
### 1. Patch bridge.js โ skip allowlist for groups
|
|
13
|
+
|
|
14
|
+
**File**: Hermes `scripts/whatsapp-bridge/bridge.js`
|
|
15
|
+
|
|
16
|
+
**Change line 637** from:
|
|
17
|
+
```js
|
|
18
|
+
if (WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
19
|
+
```
|
|
20
|
+
to:
|
|
21
|
+
```js
|
|
22
|
+
if (!isGroup && WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The `!isGroup &&` prefix skips the allowlist check entirely for group messages. DMs remain gated.
|
|
26
|
+
|
|
27
|
+
### 2. Patch whatsapp_common.py โ remove allowlist check for groups
|
|
28
|
+
|
|
29
|
+
**File**: Hermes `gateway/platforms/whatsapp_common.py`
|
|
30
|
+
|
|
31
|
+
**Remove lines 361-365** (the allowlist check block):
|
|
32
|
+
```python
|
|
33
|
+
# Only respond to whitelisted senders in groups (respect WHATSAPP_ALLOWED_USERS)
|
|
34
|
+
if self._allow_from:
|
|
35
|
+
sender_id = str(data.get("senderId") or data.get("from") or "")
|
|
36
|
+
if sender_id and not self._matches_whatsapp_allowlist(sender_id, self._allow_from):
|
|
37
|
+
return False
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Replace with a comment:
|
|
41
|
+
```python
|
|
42
|
+
# NOTE: patched โ allowlist check skipped for groups so all members' messages are recorded.
|
|
43
|
+
# Only DMs are gated by WHATSAPP_ALLOWED_USERS.
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. Set WHATSAPP_REQUIRE_MENTION=true
|
|
47
|
+
|
|
48
|
+
In the Hermes environment configuration, add or update:
|
|
49
|
+
```
|
|
50
|
+
WHATSAPP_REQUIRE_MENTION=true
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This ensures Hermes **records** all group messages but only **responds** when @mentioned. Without this, Hermes would respond to every single group message, creating chaos.
|
|
54
|
+
|
|
55
|
+
### 4. Restart gateway
|
|
56
|
+
|
|
57
|
+
**CRITICAL**: Cannot restart from inside the gateway. User must run from separate terminal:
|
|
58
|
+
```bash
|
|
59
|
+
hermes gateway restart
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The bridge auto-restarts on kill (the adapter spawns it), but Python module changes require a full gateway restart.
|
|
63
|
+
|
|
64
|
+
## Verification
|
|
65
|
+
|
|
66
|
+
After restart, check recording logs at the group_logs directory configured in the adapter.
|
|
67
|
+
|
|
68
|
+
## โ ๏ธ Warning: Patches are overwritten on `hermes update`
|
|
69
|
+
|
|
70
|
+
These changes modify Hermes source code. Running `hermes update` will overwrite the patched files. Re-apply patches after each update.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# User's Reference Format
|
|
2
|
+
|
|
3
|
+
This is the exact format the user provided as a reference for how summaries should look.
|
|
4
|
+
Use this as the canonical example โ match the style, tone, and structure closely.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
*Summary General โ 12 jam terakhir*
|
|
8
|
+
- *Inti Diskusi*
|
|
9
|
+
- Grup rame bahas perbandingan model/agent: GPT 5.6 Sol/Terra/Luna, Grok, Opus, Qwen, plus setup Codex/9router. Pen? dan DickySusanto paling dominan arahkan diskusi.
|
|
10
|
+
- Banyak tanya soal akses & workflow: apakah Sol sudah masuk Codex official, beda mode sol vs sol-xhigh, serta model mana yang enak buat coding, summary, security, atau daily usage.
|
|
11
|
+
- Obrolan teknis lain muter di tokenizer/LLM from scratch, rate limit 429, remote access via Tailscale/SSH/RDP, dan integrasi Agentrouter/9router.
|
|
12
|
+
- Ada juga share metode/event/trial tools, tapi banyak yang sifatnya coba-coba komunitas dan belum jelas stabilitasnya.
|
|
13
|
+
- *Keputusan*
|
|
14
|
+
- Tidak ada keputusan formal.
|
|
15
|
+
- *Follow-up / Action*
|
|
16
|
+
- Pen?: sempat bilang "besok aja besok" buat lanjut share/tutor yang diminta.
|
|
17
|
+
- Pen?: update singkat "deploy error done", tapi belum ada detail hasil lanjutannya.
|
|
18
|
+
- Yanda Nooryuda: ada task open buat cek member/top hari ini.
|
|
19
|
+
- DickySusanto / ไฝ ็ฎๅชๅๅฐ้ฅผๅนฒ๏ผ: masih ada request open buat kirim benchmark kecil/model arena dan extension RF token.
|
|
20
|
+
- *Pertanyaan Terbuka*
|
|
21
|
+
- API Gmaps ternyata berbayar atau tidak?
|
|
22
|
+
- Bagusan Tailscale atau NetBird untuk akses remote?
|
|
23
|
+
- Sol sekarang bisa dipakai langsung di Codex CLI atau tetap harus lewat 9router?
|
|
24
|
+
- Untuk slicing UI, lebih cocok Claude atau ChatGPT versi terbaru?
|
|
25
|
+
- *Link-link*
|
|
26
|
+
- Nado: share repo token saver di GitHub โ github.com/Fernado03/oh-my-pi-supreme-token-saver
|
|
27
|
+
- Bayu Anugerah: share extension codex-auth di Chrome Web Store.
|
|
28
|
+
- Yanda Nooryuda / Azhar: share ulang link invite grup WhatsApp.
|
|
29
|
+
- Mzxn Amnah: share event/community Lovable + temp mail smailpro buat klaim credit.
|
|
30
|
+
- gn: share repo Vandivier/ladderly-3 terkait issue/ref lain.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Key formatting rules extracted:
|
|
34
|
+
|
|
35
|
+
1. **No blank lines** between sections โ WhatsApp renders these as ugly gaps
|
|
36
|
+
2. **Dash-prefix for everything** โ `- *Section Name*` then `- content`
|
|
37
|
+
3. **Group related chats into 3-5 topic bullets** under Inti Diskusi
|
|
38
|
+
4. **Names**: use the WhatsApp display name, not phone number
|
|
39
|
+
5. **Casual Indonesian**: "rame bahas", "muter di", "belum jelas"
|
|
40
|
+
6. **Links at the bottom**: sender name, description, URL
|
|
41
|
+
7. **Honest about uncertainty**: "belum ada jawaban jelas", "tidak ada solusi valid"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Recording Verification Checklist
|
|
2
|
+
|
|
3
|
+
After applying all 3 patches and restarting the gateway:
|
|
4
|
+
|
|
5
|
+
## 1. Check environment
|
|
6
|
+
|
|
7
|
+
Verify `WHATSAPP_REQUIRE_MENTION` is set to `true` in the Hermes environment configuration.
|
|
8
|
+
|
|
9
|
+
## 2. Verify bridge allows all group messages
|
|
10
|
+
|
|
11
|
+
Check bridge is running with patched code:
|
|
12
|
+
```bash
|
|
13
|
+
ps aux | grep "bridge.js" | grep -v grep
|
|
14
|
+
# Should show node process with --mode bot
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 3. Verify JSONL recording
|
|
18
|
+
|
|
19
|
+
Send a test message in any group where Hermes is a member, then check the group_logs directory for a new JSONL file with your message.
|
|
20
|
+
|
|
21
|
+
## 4. Verify silent recording (no agent response)
|
|
22
|
+
|
|
23
|
+
Check gateway logs โ regular messages should show `"_build_message_event returned None"` (not `"inbound message"`). These are silently recorded โ no agent session created, no LLM cost.
|
|
24
|
+
|
|
25
|
+
## 5. Verify mention still triggers agent
|
|
26
|
+
|
|
27
|
+
Tag @Hermes in a group โ it should create a session and respond normally. Gateway logs should show `"inbound message"` with the group chat ID.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# WhatsApp Bridge Limitations for Group Summaries
|
|
2
|
+
|
|
3
|
+
## The Problem
|
|
4
|
+
|
|
5
|
+
The WhatsApp Baileys bridge (`scripts/whatsapp-bridge/bridge.js`) has a hard filter at line 637:
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
if (WHATSAPP_DM_POLICY !== 'pairing' && !matchesAllowedUser(senderId, ALLOWED_USERS, SESSION_DIR)) {
|
|
9
|
+
continue; // silently drop the message
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This runs for ALL incoming messages (`messages.upsert` handler, line 520). In bot mode (`WHATSAPP_MODE=bot`), this means group messages from non-whitelisted users are dropped at the bridge level โ before they ever reach the Python gateway or the session database.
|
|
14
|
+
|
|
15
|
+
## Impact on Summary Bots
|
|
16
|
+
|
|
17
|
+
- **Only conversations from `WHATSAPP_ALLOWED_USERS` appear in summary output**
|
|
18
|
+
- Group members not in the allowlist are invisible to the bot
|
|
19
|
+
- The `WHATSAPP_GROUP_POLICY=open` setting and `WHATSAPP_REQUIRE_MENTION=false` default are irrelevant because the bridge drops messages first
|
|
20
|
+
|
|
21
|
+
## Solution
|
|
22
|
+
|
|
23
|
+
This skill patches the bridge to skip the allowlist check for group messages by adding `!isGroup &&` to the condition at line 637. DMs remain fully gated by the allowlist.
|
|
24
|
+
|
|
25
|
+
The Python adapter (`gateway/platforms/whatsapp_common.py`) also needs a matching patch to remove its group allowlist check.
|
|
26
|
+
|
|
27
|
+
## Code Locations
|
|
28
|
+
|
|
29
|
+
| Component | File | Key Lines |
|
|
30
|
+
|-----------|------|-----------|
|
|
31
|
+
| Bridge message handler | `scripts/whatsapp-bridge/bridge.js` | 520-640 (upsert handler, allowlist check at 637) |
|
|
32
|
+
| Python adapter | `plugins/platforms/whatsapp/adapter.py` | `_should_process_message` call |
|
|
33
|
+
| Message processing logic | `gateway/platforms/whatsapp_common.py` | 348-385 (group policy, mention gating) |
|
|
34
|
+
| Environment config | Hermes env file | `WHATSAPP_ALLOWED_USERS`, `WHATSAPP_DM_POLICY`, `WHATSAPP_REQUIRE_MENTION` |
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# WhatsApp Group ID & Delivery Reference
|
|
2
|
+
|
|
3
|
+
## Group ID Format
|
|
4
|
+
|
|
5
|
+
WhatsApp group IDs always follow this pattern:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
<digits>@g.us
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Examples:
|
|
12
|
+
- `120363273766916972@g.us` (MOCA PARTY)
|
|
13
|
+
- `120363309894459310@g.us` (hd)
|
|
14
|
+
- `120363307689756041@g.us` (BagiProject)
|
|
15
|
+
- `120363411000649302@g.us` (unnes 1)
|
|
16
|
+
|
|
17
|
+
## Getting the Group ID
|
|
18
|
+
|
|
19
|
+
1. **User provides it directly** โ fastest. Ask "apa ID grupnya?" in the group. Respond with JUST the ID, no explanations.
|
|
20
|
+
2. **From session_search** โ look for the group name in session titles when Hermes receives messages.
|
|
21
|
+
3. **User tags Hermes in group** โ when tagged "apa id grub ini", respond with: `ID grup ini: \`<id>@g.us\`` โ keep it ONE line, no follow-up questions.
|
|
22
|
+
|
|
23
|
+
## Delivery Format
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
deliver: "whatsapp:<group_id>@g.us"
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Example: `deliver: "whatsapp:120363273766916972@g.us"`
|
|
30
|
+
|
|
31
|
+
## Cron Schedule (WIB timezone)
|
|
32
|
+
|
|
33
|
+
| Time (WIB) | UTC | Cron expression |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| 07:00 pagi | 00:00 | `0 0 * * *` |
|
|
36
|
+
| 23:00 malam | 16:00 | `0 16 * * *` |
|
|
37
|
+
|
|
38
|
+
WIB = UTC+7.
|
|
39
|
+
|
|
40
|
+
## Batch Creation Pattern
|
|
41
|
+
|
|
42
|
+
Always create both morning and evening jobs in parallel (single tool call with two `cronjob(action='create')` invocations) to save round-trips. Only ask for the group name once, then create both.
|