agent-messenger 2.10.1 → 2.11.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.
Files changed (536) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/.env.template +4 -1
  3. package/README.md +77 -27
  4. package/bun.lock +26 -0
  5. package/dist/package.json +14 -1
  6. package/dist/src/platforms/channeltalk/commands/auth.d.ts +2 -1
  7. package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
  8. package/dist/src/platforms/channeltalk/commands/auth.js +5 -3
  9. package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
  10. package/dist/src/platforms/channeltalk/token-extractor.d.ts +2 -1
  11. package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
  12. package/dist/src/platforms/channeltalk/token-extractor.js +22 -6
  13. package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
  14. package/dist/src/platforms/channeltalkbot/cli.d.ts.map +1 -1
  15. package/dist/src/platforms/channeltalkbot/cli.js +11 -1
  16. package/dist/src/platforms/channeltalkbot/cli.js.map +1 -1
  17. package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
  18. package/dist/src/platforms/channeltalkbot/commands/auth.js +1 -5
  19. package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
  20. package/dist/src/platforms/channeltalkbot/commands/bot.d.ts.map +1 -1
  21. package/dist/src/platforms/channeltalkbot/commands/bot.js +1 -6
  22. package/dist/src/platforms/channeltalkbot/commands/bot.js.map +1 -1
  23. package/dist/src/platforms/channeltalkbot/commands/chat.d.ts.map +1 -1
  24. package/dist/src/platforms/channeltalkbot/commands/chat.js +1 -6
  25. package/dist/src/platforms/channeltalkbot/commands/chat.js.map +1 -1
  26. package/dist/src/platforms/channeltalkbot/commands/group.d.ts.map +1 -1
  27. package/dist/src/platforms/channeltalkbot/commands/group.js +1 -6
  28. package/dist/src/platforms/channeltalkbot/commands/group.js.map +1 -1
  29. package/dist/src/platforms/channeltalkbot/commands/manager.d.ts.map +1 -1
  30. package/dist/src/platforms/channeltalkbot/commands/manager.js +1 -6
  31. package/dist/src/platforms/channeltalkbot/commands/manager.js.map +1 -1
  32. package/dist/src/platforms/channeltalkbot/commands/message.d.ts.map +1 -1
  33. package/dist/src/platforms/channeltalkbot/commands/message.js +1 -6
  34. package/dist/src/platforms/channeltalkbot/commands/message.js.map +1 -1
  35. package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts.map +1 -1
  36. package/dist/src/platforms/channeltalkbot/commands/whoami.js +1 -6
  37. package/dist/src/platforms/channeltalkbot/commands/whoami.js.map +1 -1
  38. package/dist/src/platforms/channeltalkbot/credential-manager.d.ts +5 -0
  39. package/dist/src/platforms/channeltalkbot/credential-manager.d.ts.map +1 -1
  40. package/dist/src/platforms/channeltalkbot/credential-manager.js +34 -4
  41. package/dist/src/platforms/channeltalkbot/credential-manager.js.map +1 -1
  42. package/dist/src/platforms/discord/commands/auth.d.ts +1 -0
  43. package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -1
  44. package/dist/src/platforms/discord/commands/auth.js +3 -1
  45. package/dist/src/platforms/discord/commands/auth.js.map +1 -1
  46. package/dist/src/platforms/discord/listener.d.ts +2 -0
  47. package/dist/src/platforms/discord/listener.d.ts.map +1 -1
  48. package/dist/src/platforms/discord/listener.js +51 -21
  49. package/dist/src/platforms/discord/listener.js.map +1 -1
  50. package/dist/src/platforms/discord/token-extractor.d.ts +2 -1
  51. package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
  52. package/dist/src/platforms/discord/token-extractor.js +21 -6
  53. package/dist/src/platforms/discord/token-extractor.js.map +1 -1
  54. package/dist/src/platforms/discordbot/cli.d.ts.map +1 -1
  55. package/dist/src/platforms/discordbot/cli.js +12 -1
  56. package/dist/src/platforms/discordbot/cli.js.map +1 -1
  57. package/dist/src/platforms/discordbot/client.d.ts +3 -0
  58. package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
  59. package/dist/src/platforms/discordbot/client.js +3 -0
  60. package/dist/src/platforms/discordbot/client.js.map +1 -1
  61. package/dist/src/platforms/discordbot/commands/auth.d.ts.map +1 -1
  62. package/dist/src/platforms/discordbot/commands/auth.js +1 -5
  63. package/dist/src/platforms/discordbot/commands/auth.js.map +1 -1
  64. package/dist/src/platforms/discordbot/commands/message.d.ts.map +1 -1
  65. package/dist/src/platforms/discordbot/commands/message.js +1 -6
  66. package/dist/src/platforms/discordbot/commands/message.js.map +1 -1
  67. package/dist/src/platforms/discordbot/commands/server.d.ts.map +1 -1
  68. package/dist/src/platforms/discordbot/commands/server.js +1 -4
  69. package/dist/src/platforms/discordbot/commands/server.js.map +1 -1
  70. package/dist/src/platforms/discordbot/commands/whoami.d.ts.map +1 -1
  71. package/dist/src/platforms/discordbot/commands/whoami.js +1 -6
  72. package/dist/src/platforms/discordbot/commands/whoami.js.map +1 -1
  73. package/dist/src/platforms/discordbot/index.d.ts +3 -1
  74. package/dist/src/platforms/discordbot/index.d.ts.map +1 -1
  75. package/dist/src/platforms/discordbot/index.js +2 -1
  76. package/dist/src/platforms/discordbot/index.js.map +1 -1
  77. package/dist/src/platforms/discordbot/listener.d.ts +43 -0
  78. package/dist/src/platforms/discordbot/listener.d.ts.map +1 -0
  79. package/dist/src/platforms/discordbot/listener.js +292 -0
  80. package/dist/src/platforms/discordbot/listener.js.map +1 -0
  81. package/dist/src/platforms/discordbot/types.d.ts +161 -0
  82. package/dist/src/platforms/discordbot/types.d.ts.map +1 -1
  83. package/dist/src/platforms/discordbot/types.js +34 -0
  84. package/dist/src/platforms/discordbot/types.js.map +1 -1
  85. package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
  86. package/dist/src/platforms/instagram/commands/auth.js +3 -1
  87. package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
  88. package/dist/src/platforms/instagram/token-extractor.d.ts +2 -1
  89. package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
  90. package/dist/src/platforms/instagram/token-extractor.js +11 -2
  91. package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
  92. package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
  93. package/dist/src/platforms/slack/commands/auth.js +4 -2
  94. package/dist/src/platforms/slack/commands/auth.js.map +1 -1
  95. package/dist/src/platforms/slack/token-extractor.d.ts +4 -1
  96. package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
  97. package/dist/src/platforms/slack/token-extractor.js +64 -15
  98. package/dist/src/platforms/slack/token-extractor.js.map +1 -1
  99. package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
  100. package/dist/src/platforms/slackbot/cli.js +15 -3
  101. package/dist/src/platforms/slackbot/cli.js.map +1 -1
  102. package/dist/src/platforms/slackbot/client.d.ts +22 -1
  103. package/dist/src/platforms/slackbot/client.d.ts.map +1 -1
  104. package/dist/src/platforms/slackbot/client.js +104 -1
  105. package/dist/src/platforms/slackbot/client.js.map +1 -1
  106. package/dist/src/platforms/slackbot/commands/auth.d.ts.map +1 -1
  107. package/dist/src/platforms/slackbot/commands/auth.js +1 -5
  108. package/dist/src/platforms/slackbot/commands/auth.js.map +1 -1
  109. package/dist/src/platforms/slackbot/commands/file.d.ts +3 -0
  110. package/dist/src/platforms/slackbot/commands/file.d.ts.map +1 -0
  111. package/dist/src/platforms/slackbot/commands/file.js +164 -0
  112. package/dist/src/platforms/slackbot/commands/file.js.map +1 -0
  113. package/dist/src/platforms/slackbot/commands/index.d.ts +1 -0
  114. package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -1
  115. package/dist/src/platforms/slackbot/commands/index.js +1 -0
  116. package/dist/src/platforms/slackbot/commands/index.js.map +1 -1
  117. package/dist/src/platforms/slackbot/commands/message.d.ts.map +1 -1
  118. package/dist/src/platforms/slackbot/commands/message.js +19 -0
  119. package/dist/src/platforms/slackbot/commands/message.js.map +1 -1
  120. package/dist/src/platforms/slackbot/commands/whoami.d.ts.map +1 -1
  121. package/dist/src/platforms/slackbot/commands/whoami.js +1 -6
  122. package/dist/src/platforms/slackbot/commands/whoami.js.map +1 -1
  123. package/dist/src/platforms/slackbot/credential-manager.d.ts +1 -0
  124. package/dist/src/platforms/slackbot/credential-manager.d.ts.map +1 -1
  125. package/dist/src/platforms/slackbot/credential-manager.js +30 -2
  126. package/dist/src/platforms/slackbot/credential-manager.js.map +1 -1
  127. package/dist/src/platforms/slackbot/index.d.ts +4 -1
  128. package/dist/src/platforms/slackbot/index.d.ts.map +1 -1
  129. package/dist/src/platforms/slackbot/index.js +1 -0
  130. package/dist/src/platforms/slackbot/index.js.map +1 -1
  131. package/dist/src/platforms/slackbot/listener.d.ts +44 -0
  132. package/dist/src/platforms/slackbot/listener.d.ts.map +1 -0
  133. package/dist/src/platforms/slackbot/listener.js +313 -0
  134. package/dist/src/platforms/slackbot/listener.js.map +1 -0
  135. package/dist/src/platforms/slackbot/types.d.ts +196 -1
  136. package/dist/src/platforms/slackbot/types.d.ts.map +1 -1
  137. package/dist/src/platforms/slackbot/types.js +4 -1
  138. package/dist/src/platforms/slackbot/types.js.map +1 -1
  139. package/dist/src/platforms/teams/commands/auth.d.ts +1 -0
  140. package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
  141. package/dist/src/platforms/teams/commands/auth.js +37 -6
  142. package/dist/src/platforms/teams/commands/auth.js.map +1 -1
  143. package/dist/src/platforms/teams/ensure-auth.js +31 -9
  144. package/dist/src/platforms/teams/ensure-auth.js.map +1 -1
  145. package/dist/src/platforms/teams/token-extractor.d.ts +4 -1
  146. package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
  147. package/dist/src/platforms/teams/token-extractor.js +80 -31
  148. package/dist/src/platforms/teams/token-extractor.js.map +1 -1
  149. package/dist/src/platforms/webex/commands/auth.d.ts +1 -0
  150. package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
  151. package/dist/src/platforms/webex/commands/auth.js +3 -1
  152. package/dist/src/platforms/webex/commands/auth.js.map +1 -1
  153. package/dist/src/platforms/webex/token-extractor.d.ts +3 -1
  154. package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
  155. package/dist/src/platforms/webex/token-extractor.js +16 -2
  156. package/dist/src/platforms/webex/token-extractor.js.map +1 -1
  157. package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -1
  158. package/dist/src/platforms/wechatbot/cli.js +11 -1
  159. package/dist/src/platforms/wechatbot/cli.js.map +1 -1
  160. package/dist/src/platforms/wechatbot/commands/auth.d.ts.map +1 -1
  161. package/dist/src/platforms/wechatbot/commands/auth.js +1 -5
  162. package/dist/src/platforms/wechatbot/commands/auth.js.map +1 -1
  163. package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
  164. package/dist/src/platforms/wechatbot/commands/message.js +1 -6
  165. package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
  166. package/dist/src/platforms/wechatbot/commands/template.d.ts.map +1 -1
  167. package/dist/src/platforms/wechatbot/commands/template.js +1 -6
  168. package/dist/src/platforms/wechatbot/commands/template.js.map +1 -1
  169. package/dist/src/platforms/wechatbot/commands/user.d.ts.map +1 -1
  170. package/dist/src/platforms/wechatbot/commands/user.js +1 -6
  171. package/dist/src/platforms/wechatbot/commands/user.js.map +1 -1
  172. package/dist/src/platforms/wechatbot/commands/whoami.d.ts.map +1 -1
  173. package/dist/src/platforms/wechatbot/commands/whoami.js +1 -6
  174. package/dist/src/platforms/wechatbot/commands/whoami.js.map +1 -1
  175. package/dist/src/platforms/whatsappbot/cli.d.ts.map +1 -1
  176. package/dist/src/platforms/whatsappbot/cli.js +11 -1
  177. package/dist/src/platforms/whatsappbot/cli.js.map +1 -1
  178. package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
  179. package/dist/src/platforms/whatsappbot/commands/auth.js +1 -5
  180. package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
  181. package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
  182. package/dist/src/platforms/whatsappbot/commands/message.js +1 -6
  183. package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
  184. package/dist/src/platforms/whatsappbot/commands/template.d.ts.map +1 -1
  185. package/dist/src/platforms/whatsappbot/commands/template.js +1 -6
  186. package/dist/src/platforms/whatsappbot/commands/template.js.map +1 -1
  187. package/dist/src/platforms/whatsappbot/commands/whoami.d.ts.map +1 -1
  188. package/dist/src/platforms/whatsappbot/commands/whoami.js +1 -6
  189. package/dist/src/platforms/whatsappbot/commands/whoami.js.map +1 -1
  190. package/dist/src/shared/chromium/browsers.d.ts +8 -0
  191. package/dist/src/shared/chromium/browsers.d.ts.map +1 -1
  192. package/dist/src/shared/chromium/browsers.js +58 -3
  193. package/dist/src/shared/chromium/browsers.js.map +1 -1
  194. package/dist/src/shared/chromium/cli-options.d.ts +5 -0
  195. package/dist/src/shared/chromium/cli-options.d.ts.map +1 -0
  196. package/dist/src/shared/chromium/cli-options.js +8 -0
  197. package/dist/src/shared/chromium/cli-options.js.map +1 -0
  198. package/dist/src/shared/chromium/decryptor.d.ts +6 -0
  199. package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
  200. package/dist/src/shared/chromium/decryptor.js +26 -6
  201. package/dist/src/shared/chromium/decryptor.js.map +1 -1
  202. package/dist/src/shared/chromium/index.d.ts +3 -1
  203. package/dist/src/shared/chromium/index.d.ts.map +1 -1
  204. package/dist/src/shared/chromium/index.js +2 -1
  205. package/dist/src/shared/chromium/index.js.map +1 -1
  206. package/dist/src/shared/utils/cli-output.d.ts +7 -0
  207. package/dist/src/shared/utils/cli-output.d.ts.map +1 -0
  208. package/dist/src/shared/utils/cli-output.js +7 -0
  209. package/dist/src/shared/utils/cli-output.js.map +1 -0
  210. package/dist/src/tui/app.d.ts.map +1 -1
  211. package/dist/src/tui/app.js +73 -20
  212. package/dist/src/tui/app.js.map +1 -1
  213. package/docs/content/docs/cli/channeltalk.mdx +4 -0
  214. package/docs/content/docs/cli/discord.mdx +5 -0
  215. package/docs/content/docs/cli/instagram.mdx +3 -0
  216. package/docs/content/docs/cli/slack.mdx +5 -0
  217. package/docs/content/docs/cli/slackbot.mdx +60 -22
  218. package/docs/content/docs/cli/teams.mdx +5 -0
  219. package/docs/content/docs/cli/webex.mdx +3 -0
  220. package/docs/content/docs/sdk/channeltalkbot.mdx +38 -1
  221. package/docs/content/docs/sdk/discordbot.mdx +501 -0
  222. package/docs/content/docs/sdk/meta.json +2 -0
  223. package/docs/content/docs/sdk/slackbot.mdx +576 -0
  224. package/e2e/README.md +1 -1
  225. package/e2e/channeltalk.e2e.test.ts +13 -13
  226. package/e2e/channeltalkbot.e2e.test.ts +13 -13
  227. package/e2e/config.ts +9 -4
  228. package/e2e/discord.e2e.test.ts +24 -24
  229. package/e2e/discordbot.e2e.test.ts +16 -16
  230. package/e2e/instagram.e2e.test.ts +10 -10
  231. package/e2e/kakaotalk.e2e.test.ts +7 -7
  232. package/e2e/line.e2e.test.ts +8 -8
  233. package/e2e/slack.e2e.test.ts +34 -34
  234. package/e2e/slackbot.e2e.test.ts +14 -14
  235. package/e2e/teams.e2e.test.ts +23 -23
  236. package/e2e/telegram.e2e.test.ts +8 -8
  237. package/e2e/webex.e2e.test.ts +14 -14
  238. package/e2e/whatsapp.e2e.test.ts +8 -8
  239. package/e2e/whatsappbot.e2e.test.ts +6 -6
  240. package/examples/discordbot-listen.ts +65 -0
  241. package/examples/slackbot-listen.ts +65 -0
  242. package/package.json +14 -1
  243. package/skills/agent-channeltalk/SKILL.md +5 -1
  244. package/skills/agent-channeltalk/references/authentication.md +5 -1
  245. package/skills/agent-channeltalkbot/SKILL.md +17 -3
  246. package/skills/agent-channeltalkbot/references/authentication.md +7 -5
  247. package/skills/agent-discord/SKILL.md +5 -1
  248. package/skills/agent-discord/references/authentication.md +7 -1
  249. package/skills/agent-discordbot/SKILL.md +13 -2
  250. package/skills/agent-discordbot/references/common-patterns.md +1 -1
  251. package/skills/agent-instagram/SKILL.md +7 -1
  252. package/skills/agent-instagram/references/authentication.md +6 -0
  253. package/skills/agent-kakaotalk/SKILL.md +1 -1
  254. package/skills/agent-line/SKILL.md +1 -1
  255. package/skills/agent-slack/SKILL.md +5 -1
  256. package/skills/agent-slack/references/authentication.md +7 -1
  257. package/skills/agent-slackbot/SKILL.md +56 -4
  258. package/skills/agent-slackbot/references/authentication.md +4 -0
  259. package/skills/agent-teams/SKILL.md +5 -1
  260. package/skills/agent-teams/references/authentication.md +7 -1
  261. package/skills/agent-telegram/SKILL.md +1 -1
  262. package/skills/agent-webex/SKILL.md +7 -1
  263. package/skills/agent-webex/references/authentication.md +6 -0
  264. package/skills/agent-wechatbot/SKILL.md +16 -1
  265. package/skills/agent-wechatbot/references/authentication.md +219 -0
  266. package/skills/agent-wechatbot/references/common-patterns.md +358 -0
  267. package/skills/agent-wechatbot/templates/account-summary.sh +122 -0
  268. package/skills/agent-wechatbot/templates/post-message.sh +122 -0
  269. package/skills/agent-wechatbot/templates/send-template.sh +152 -0
  270. package/skills/agent-whatsapp/SKILL.md +1 -1
  271. package/skills/agent-whatsappbot/SKILL.md +30 -1
  272. package/src/platforms/channeltalk/client.test.ts +26 -26
  273. package/src/platforms/channeltalk/commands/auth.test.ts +31 -19
  274. package/src/platforms/channeltalk/commands/auth.ts +15 -5
  275. package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
  276. package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
  277. package/src/platforms/channeltalk/commands/group.test.ts +4 -4
  278. package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
  279. package/src/platforms/channeltalk/commands/message.test.ts +17 -17
  280. package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
  281. package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
  282. package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
  283. package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
  284. package/src/platforms/channeltalk/index.test.ts +23 -23
  285. package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
  286. package/src/platforms/channeltalk/token-extractor.ts +24 -5
  287. package/src/platforms/channeltalk/types.test.ts +12 -12
  288. package/src/platforms/channeltalkbot/cli.ts +9 -0
  289. package/src/platforms/channeltalkbot/client.test.ts +14 -14
  290. package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
  291. package/src/platforms/channeltalkbot/commands/auth.ts +1 -5
  292. package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
  293. package/src/platforms/channeltalkbot/commands/bot.ts +1 -6
  294. package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
  295. package/src/platforms/channeltalkbot/commands/chat.ts +1 -6
  296. package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
  297. package/src/platforms/channeltalkbot/commands/group.ts +1 -6
  298. package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
  299. package/src/platforms/channeltalkbot/commands/manager.ts +1 -6
  300. package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
  301. package/src/platforms/channeltalkbot/commands/message.ts +1 -6
  302. package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
  303. package/src/platforms/channeltalkbot/commands/whoami.test.ts +6 -4
  304. package/src/platforms/channeltalkbot/commands/whoami.ts +1 -6
  305. package/src/platforms/channeltalkbot/credential-manager.test.ts +123 -29
  306. package/src/platforms/channeltalkbot/credential-manager.ts +37 -4
  307. package/src/platforms/channeltalkbot/index.test.ts +15 -15
  308. package/src/platforms/discord/client.test.ts +28 -28
  309. package/src/platforms/discord/commands/auth.test.ts +7 -7
  310. package/src/platforms/discord/commands/auth.ts +13 -2
  311. package/src/platforms/discord/commands/channel.test.ts +7 -7
  312. package/src/platforms/discord/commands/dm.test.ts +4 -4
  313. package/src/platforms/discord/commands/file.test.ts +4 -4
  314. package/src/platforms/discord/commands/friend.test.ts +6 -6
  315. package/src/platforms/discord/commands/member.test.ts +5 -5
  316. package/src/platforms/discord/commands/mention.test.ts +5 -5
  317. package/src/platforms/discord/commands/message.test.ts +9 -9
  318. package/src/platforms/discord/commands/note.test.ts +6 -6
  319. package/src/platforms/discord/commands/profile.test.ts +4 -4
  320. package/src/platforms/discord/commands/reaction.test.ts +5 -5
  321. package/src/platforms/discord/commands/server.test.ts +7 -7
  322. package/src/platforms/discord/commands/snapshot.test.ts +6 -6
  323. package/src/platforms/discord/commands/thread.test.ts +6 -6
  324. package/src/platforms/discord/commands/user.test.ts +5 -5
  325. package/src/platforms/discord/commands/whoami.test.ts +6 -6
  326. package/src/platforms/discord/credential-manager.test.ts +16 -16
  327. package/src/platforms/discord/ensure-auth.test.ts +8 -8
  328. package/src/platforms/discord/index.test.ts +17 -17
  329. package/src/platforms/discord/listener.test.ts +92 -34
  330. package/src/platforms/discord/listener.ts +43 -19
  331. package/src/platforms/discord/token-extractor.test.ts +53 -53
  332. package/src/platforms/discord/token-extractor.ts +30 -6
  333. package/src/platforms/discord/types.test.ts +26 -26
  334. package/src/platforms/discordbot/cli.ts +10 -0
  335. package/src/platforms/discordbot/client.test.ts +31 -31
  336. package/src/platforms/discordbot/client.ts +4 -0
  337. package/src/platforms/discordbot/commands/auth.test.ts +18 -18
  338. package/src/platforms/discordbot/commands/auth.ts +1 -5
  339. package/src/platforms/discordbot/commands/channel.test.ts +11 -11
  340. package/src/platforms/discordbot/commands/file.test.ts +7 -7
  341. package/src/platforms/discordbot/commands/message.test.ts +25 -25
  342. package/src/platforms/discordbot/commands/message.ts +1 -6
  343. package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
  344. package/src/platforms/discordbot/commands/server.test.ts +12 -12
  345. package/src/platforms/discordbot/commands/server.ts +1 -5
  346. package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
  347. package/src/platforms/discordbot/commands/thread.test.ts +10 -10
  348. package/src/platforms/discordbot/commands/user.test.ts +9 -9
  349. package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
  350. package/src/platforms/discordbot/commands/whoami.ts +1 -6
  351. package/src/platforms/discordbot/credential-manager.test.ts +28 -28
  352. package/src/platforms/discordbot/index.test.ts +82 -0
  353. package/src/platforms/discordbot/index.ts +27 -9
  354. package/src/platforms/discordbot/listener.test.ts +1002 -0
  355. package/src/platforms/discordbot/listener.ts +321 -0
  356. package/src/platforms/discordbot/types.ts +163 -0
  357. package/src/platforms/instagram/client.test.ts +18 -18
  358. package/src/platforms/instagram/commands/auth.test.ts +11 -11
  359. package/src/platforms/instagram/commands/auth.ts +9 -1
  360. package/src/platforms/instagram/commands/chat.test.ts +6 -6
  361. package/src/platforms/instagram/commands/message.test.ts +11 -11
  362. package/src/platforms/instagram/commands/shared.test.ts +12 -12
  363. package/src/platforms/instagram/commands/whoami.test.ts +3 -3
  364. package/src/platforms/instagram/credential-manager.test.ts +21 -21
  365. package/src/platforms/instagram/ensure-auth.test.ts +4 -4
  366. package/src/platforms/instagram/index.test.ts +9 -9
  367. package/src/platforms/instagram/listener.test.ts +8 -8
  368. package/src/platforms/instagram/token-extractor.test.ts +35 -35
  369. package/src/platforms/instagram/token-extractor.ts +13 -1
  370. package/src/platforms/kakaotalk/client.test.ts +33 -33
  371. package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
  372. package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
  373. package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
  374. package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
  375. package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
  376. package/src/platforms/kakaotalk/index.test.ts +15 -15
  377. package/src/platforms/kakaotalk/listener.test.ts +17 -17
  378. package/src/platforms/line/client.test.ts +17 -17
  379. package/src/platforms/line/commands/auth.test.ts +8 -8
  380. package/src/platforms/line/commands/chat.test.ts +7 -7
  381. package/src/platforms/line/commands/friend.test.ts +6 -6
  382. package/src/platforms/line/commands/message.test.ts +7 -7
  383. package/src/platforms/line/commands/whoami.test.ts +6 -6
  384. package/src/platforms/line/credential-manager.test.ts +17 -17
  385. package/src/platforms/line/index.test.ts +10 -10
  386. package/src/platforms/line/listener.test.ts +15 -15
  387. package/src/platforms/line/types.test.ts +14 -14
  388. package/src/platforms/slack/cli.test.ts +8 -8
  389. package/src/platforms/slack/client.test.ts +151 -151
  390. package/src/platforms/slack/commands/activity.test.ts +13 -13
  391. package/src/platforms/slack/commands/auth.test.ts +34 -34
  392. package/src/platforms/slack/commands/auth.ts +11 -2
  393. package/src/platforms/slack/commands/bookmark.test.ts +9 -9
  394. package/src/platforms/slack/commands/channel.test.ts +17 -17
  395. package/src/platforms/slack/commands/drafts.test.ts +7 -7
  396. package/src/platforms/slack/commands/emoji.test.ts +3 -3
  397. package/src/platforms/slack/commands/file.test.ts +12 -12
  398. package/src/platforms/slack/commands/message.test.ts +19 -19
  399. package/src/platforms/slack/commands/pin.test.ts +7 -7
  400. package/src/platforms/slack/commands/reaction.test.ts +10 -10
  401. package/src/platforms/slack/commands/reminder.test.ts +9 -9
  402. package/src/platforms/slack/commands/saved.test.ts +7 -7
  403. package/src/platforms/slack/commands/sections.test.ts +5 -5
  404. package/src/platforms/slack/commands/snapshot.test.ts +13 -13
  405. package/src/platforms/slack/commands/unread.test.ts +6 -6
  406. package/src/platforms/slack/commands/user.test.ts +10 -10
  407. package/src/platforms/slack/commands/usergroup.test.ts +15 -15
  408. package/src/platforms/slack/commands/whoami.test.ts +6 -6
  409. package/src/platforms/slack/commands/workspace.test.ts +26 -26
  410. package/src/platforms/slack/credential-manager.test.ts +14 -14
  411. package/src/platforms/slack/ensure-auth.test.ts +21 -21
  412. package/src/platforms/slack/index.test.ts +12 -12
  413. package/src/platforms/slack/listener.test.ts +17 -17
  414. package/src/platforms/slack/token-extractor-node.test.ts +2 -2
  415. package/src/platforms/slack/token-extractor.test.ts +133 -37
  416. package/src/platforms/slack/token-extractor.ts +76 -13
  417. package/src/platforms/slack/types.test.ts +21 -21
  418. package/src/platforms/slackbot/cli.ts +13 -1
  419. package/src/platforms/slackbot/client.test.ts +296 -22
  420. package/src/platforms/slackbot/client.ts +130 -2
  421. package/src/platforms/slackbot/commands/auth.test.ts +14 -14
  422. package/src/platforms/slackbot/commands/auth.ts +1 -5
  423. package/src/platforms/slackbot/commands/channel.test.ts +7 -7
  424. package/src/platforms/slackbot/commands/file.test.ts +201 -0
  425. package/src/platforms/slackbot/commands/file.ts +212 -0
  426. package/src/platforms/slackbot/commands/index.ts +1 -0
  427. package/src/platforms/slackbot/commands/message.test.ts +13 -13
  428. package/src/platforms/slackbot/commands/message.ts +22 -0
  429. package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
  430. package/src/platforms/slackbot/commands/user.test.ts +7 -7
  431. package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
  432. package/src/platforms/slackbot/commands/whoami.ts +1 -6
  433. package/src/platforms/slackbot/credential-manager.test.ts +83 -23
  434. package/src/platforms/slackbot/credential-manager.ts +32 -2
  435. package/src/platforms/slackbot/index.test.ts +59 -0
  436. package/src/platforms/slackbot/index.ts +31 -7
  437. package/src/platforms/slackbot/listener.test.ts +1012 -0
  438. package/src/platforms/slackbot/listener.ts +362 -0
  439. package/src/platforms/slackbot/types.test.ts +7 -7
  440. package/src/platforms/slackbot/types.ts +224 -1
  441. package/src/platforms/teams/client.test.ts +30 -30
  442. package/src/platforms/teams/commands/auth.test.ts +9 -9
  443. package/src/platforms/teams/commands/auth.ts +66 -7
  444. package/src/platforms/teams/commands/channel.test.ts +7 -7
  445. package/src/platforms/teams/commands/file.test.ts +4 -4
  446. package/src/platforms/teams/commands/message.test.ts +5 -5
  447. package/src/platforms/teams/commands/reaction.test.ts +4 -4
  448. package/src/platforms/teams/commands/snapshot.test.ts +7 -7
  449. package/src/platforms/teams/commands/team.test.ts +8 -8
  450. package/src/platforms/teams/commands/user.test.ts +4 -4
  451. package/src/platforms/teams/commands/whoami.test.ts +6 -6
  452. package/src/platforms/teams/credential-manager.test.ts +17 -17
  453. package/src/platforms/teams/ensure-auth.test.ts +69 -18
  454. package/src/platforms/teams/ensure-auth.ts +39 -11
  455. package/src/platforms/teams/index.test.ts +15 -15
  456. package/src/platforms/teams/token-extractor.test.ts +251 -69
  457. package/src/platforms/teams/token-extractor.ts +94 -31
  458. package/src/platforms/teams/types.test.ts +26 -26
  459. package/src/platforms/telegram/app-config.test.ts +4 -4
  460. package/src/platforms/telegram/chat-utils.test.ts +12 -12
  461. package/src/platforms/telegram/client.test.ts +4 -4
  462. package/src/platforms/telegram/commands/auth.test.ts +16 -16
  463. package/src/platforms/telegram/commands/chat.test.ts +9 -9
  464. package/src/platforms/telegram/commands/message.test.ts +6 -6
  465. package/src/platforms/telegram/commands/shared.test.ts +3 -3
  466. package/src/platforms/telegram/commands/whoami.test.ts +3 -3
  467. package/src/platforms/telegram/credential-manager.test.ts +10 -10
  468. package/src/platforms/telegram/types.test.ts +6 -6
  469. package/src/platforms/webex/app-config.test.ts +8 -8
  470. package/src/platforms/webex/cli.test.ts +5 -5
  471. package/src/platforms/webex/client.test.ts +65 -65
  472. package/src/platforms/webex/commands/auth.test.ts +18 -18
  473. package/src/platforms/webex/commands/auth.ts +13 -2
  474. package/src/platforms/webex/commands/member.test.ts +5 -5
  475. package/src/platforms/webex/commands/message.test.ts +12 -12
  476. package/src/platforms/webex/commands/snapshot.test.ts +5 -5
  477. package/src/platforms/webex/commands/space.test.ts +10 -10
  478. package/src/platforms/webex/commands/whoami.test.ts +6 -6
  479. package/src/platforms/webex/credential-manager.test.ts +22 -22
  480. package/src/platforms/webex/encryption.test.ts +4 -4
  481. package/src/platforms/webex/ensure-auth.test.ts +5 -5
  482. package/src/platforms/webex/index.test.ts +5 -5
  483. package/src/platforms/webex/markdown-to-html.test.ts +33 -33
  484. package/src/platforms/webex/token-extractor.test.ts +23 -23
  485. package/src/platforms/webex/token-extractor.ts +25 -3
  486. package/src/platforms/webex/types.test.ts +27 -27
  487. package/src/platforms/wechatbot/cli.ts +9 -0
  488. package/src/platforms/wechatbot/client.test.ts +27 -27
  489. package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
  490. package/src/platforms/wechatbot/commands/auth.ts +1 -5
  491. package/src/platforms/wechatbot/commands/message.test.ts +8 -8
  492. package/src/platforms/wechatbot/commands/message.ts +1 -6
  493. package/src/platforms/wechatbot/commands/template.test.ts +9 -9
  494. package/src/platforms/wechatbot/commands/template.ts +1 -6
  495. package/src/platforms/wechatbot/commands/user.test.ts +7 -7
  496. package/src/platforms/wechatbot/commands/user.ts +1 -6
  497. package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
  498. package/src/platforms/wechatbot/commands/whoami.ts +1 -6
  499. package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
  500. package/src/platforms/wechatbot/index.test.ts +10 -10
  501. package/src/platforms/wechatbot/types.test.ts +25 -25
  502. package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
  503. package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
  504. package/src/platforms/whatsapp/commands/message.test.ts +10 -10
  505. package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
  506. package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
  507. package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
  508. package/src/platforms/whatsapp/index.test.ts +8 -8
  509. package/src/platforms/whatsapp/types.test.ts +42 -42
  510. package/src/platforms/whatsappbot/cli.ts +9 -0
  511. package/src/platforms/whatsappbot/client.test.ts +27 -27
  512. package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
  513. package/src/platforms/whatsappbot/commands/auth.ts +1 -5
  514. package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
  515. package/src/platforms/whatsappbot/commands/message.ts +1 -6
  516. package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
  517. package/src/platforms/whatsappbot/commands/template.ts +1 -6
  518. package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
  519. package/src/platforms/whatsappbot/commands/whoami.ts +1 -6
  520. package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
  521. package/src/platforms/whatsappbot/index.test.ts +7 -7
  522. package/src/platforms/whatsappbot/types.test.ts +18 -18
  523. package/src/shared/chromium/browsers.test.ts +102 -22
  524. package/src/shared/chromium/browsers.ts +72 -3
  525. package/src/shared/chromium/cli-options.test.ts +22 -0
  526. package/src/shared/chromium/cli-options.ts +12 -0
  527. package/src/shared/chromium/cookie-reader.test.ts +13 -13
  528. package/src/shared/chromium/decryptor.test.ts +97 -32
  529. package/src/shared/chromium/decryptor.ts +27 -6
  530. package/src/shared/chromium/index.ts +3 -0
  531. package/src/shared/utils/cli-output.test.ts +57 -0
  532. package/src/shared/utils/cli-output.ts +8 -0
  533. package/src/shared/utils/concurrency.test.ts +6 -6
  534. package/src/shared/utils/derived-key-cache.test.ts +11 -11
  535. package/src/tui/app.ts +129 -20
  536. package/src/tui/utils.test.ts +31 -31
@@ -0,0 +1,122 @@
1
+ #!/bin/bash
2
+ #
3
+ # post-message.sh - Send a customer service message via WeChat Official Account API
4
+ #
5
+ # Usage:
6
+ # ./post-message.sh <openid> <message>
7
+ #
8
+ # Arguments:
9
+ # openid - Recipient OpenID (e.g. oABCD1234)
10
+ # message - Message text to send
11
+ #
12
+ # Example:
13
+ # ./post-message.sh oABCD1234 "Hello from script!"
14
+ # ./post-message.sh oABCD1234 "Thanks for your purchase ✅"
15
+ #
16
+ # Note: Customer service messages only work within the 48-hour interaction window.
17
+ # Outside that window, use template messages via send-template.sh.
18
+
19
+ set -euo pipefail
20
+
21
+ # Check arguments
22
+ if [ $# -lt 2 ]; then
23
+ echo "Usage: $0 <openid> <message>"
24
+ echo ""
25
+ echo "Examples:"
26
+ echo " $0 oABCD1234 'Hello world!'"
27
+ echo " $0 oABCD1234 'Build completed'"
28
+ exit 1
29
+ fi
30
+
31
+ OPENID="$1"
32
+ MESSAGE="$2"
33
+
34
+ # Colors for output
35
+ RED='\033[0;31m'
36
+ GREEN='\033[0;32m'
37
+ YELLOW='\033[1;33m'
38
+ NC='\033[0m' # No Color
39
+
40
+ # Function to send message with retry logic
41
+ send_message() {
42
+ local openid=$1
43
+ local message=$2
44
+ local max_attempts=3
45
+ local attempt=1
46
+
47
+ while [ $attempt -le $max_attempts ]; do
48
+ echo -e "${YELLOW}Attempt $attempt/$max_attempts...${NC}"
49
+
50
+ # Send message and capture result
51
+ RESULT=$(agent-wechatbot message send "$openid" "$message" 2>&1) || true
52
+
53
+ # Check if successful (no error field)
54
+ if ! echo "$RESULT" | jq -e '.error' > /dev/null 2>&1; then
55
+ echo -e "${GREEN}✓ Message sent successfully!${NC}"
56
+ echo ""
57
+ echo "Message details:"
58
+ echo " To OpenID: $openid"
59
+ return 0
60
+ fi
61
+
62
+ # Extract error information
63
+ ERROR_MSG=$(echo "$RESULT" | jq -r '.error // "Unknown error"')
64
+ echo -e "${RED}✗ Failed: $ERROR_MSG${NC}"
65
+
66
+ # Don't retry on certain errors
67
+ if echo "$ERROR_MSG" | grep -qE "40164|IP whitelist"; then
68
+ echo -e "${RED}IP not in WeChat whitelist. Add your server IP in the admin panel.${NC}"
69
+ return 1
70
+ fi
71
+
72
+ if echo "$ERROR_MSG" | grep -qE "48h|48-hour"; then
73
+ echo -e "${YELLOW}Outside 48h window. Use a template message instead:${NC}"
74
+ echo " ./send-template.sh $openid <template-id> --data '...'"
75
+ return 1
76
+ fi
77
+
78
+ # Exponential backoff before retry
79
+ if [ $attempt -lt $max_attempts ]; then
80
+ SLEEP_TIME=$((attempt * 2))
81
+ echo "Retrying in ${SLEEP_TIME}s..."
82
+ sleep $SLEEP_TIME
83
+ fi
84
+
85
+ attempt=$((attempt + 1))
86
+ done
87
+
88
+ echo -e "${RED}Failed after $max_attempts attempts${NC}"
89
+ return 1
90
+ }
91
+
92
+ # Check if agent-wechatbot is installed
93
+ if ! command -v agent-wechatbot &> /dev/null; then
94
+ echo -e "${RED}Error: agent-wechatbot not found${NC}"
95
+ echo ""
96
+ echo "Install it with:"
97
+ echo " npm install -g agent-messenger"
98
+ exit 1
99
+ fi
100
+
101
+ # Check authentication
102
+ echo "Checking authentication..."
103
+ AUTH_STATUS=$(agent-wechatbot auth status 2>&1) || true
104
+
105
+ if echo "$AUTH_STATUS" | jq -e '.error' > /dev/null 2>&1; then
106
+ echo -e "${RED}Not authenticated!${NC}"
107
+ echo ""
108
+ echo "Run this to authenticate:"
109
+ echo " agent-wechatbot auth set <app-id> <app-secret>"
110
+ exit 1
111
+ fi
112
+
113
+ APP_ID=$(echo "$AUTH_STATUS" | jq -r '.app_id // "Unknown"')
114
+ echo -e "${GREEN}✓ Authenticated (App ID: $APP_ID)${NC}"
115
+ echo ""
116
+
117
+ # Send the message
118
+ echo "Sending message to $OPENID..."
119
+ echo "Message: $MESSAGE"
120
+ echo ""
121
+
122
+ send_message "$OPENID" "$MESSAGE"
@@ -0,0 +1,152 @@
1
+ #!/bin/bash
2
+ #
3
+ # send-template.sh - Send a WeChat template message via Official Account API
4
+ #
5
+ # Usage:
6
+ # ./send-template.sh <openid> <template-id> --data <json> [--url <url>]
7
+ #
8
+ # Arguments:
9
+ # openid - Recipient follower OpenID (e.g. oABCD1234)
10
+ # template-id - Pre-approved template ID (e.g. TM00001)
11
+ #
12
+ # Options:
13
+ # --data <json> - Required. JSON object with template parameters.
14
+ # Format: {"<param>":{"value":"<text>","color":"<#hex>"}}
15
+ # --url <url> - Optional. URL the message links to when tapped.
16
+ #
17
+ # Example:
18
+ # ./send-template.sh oABCD1234 TM00001 \
19
+ # --data '{"order_id":{"value":"ORD-9876"},"customer_name":{"value":"Alice"}}'
20
+ #
21
+ # ./send-template.sh oABCD1234 TM00001 \
22
+ # --data '{"status":{"value":"shipped","color":"#00AA00"}}' \
23
+ # --url "https://example.com/orders/9876"
24
+
25
+ set -euo pipefail
26
+
27
+ if [ $# -lt 2 ]; then
28
+ echo "Usage: $0 <openid> <template-id> --data <json> [--url <url>]"
29
+ echo ""
30
+ echo "Examples:"
31
+ echo " $0 oABCD1234 TM00001 --data '{\"order_id\":{\"value\":\"ORD-001\"}}'"
32
+ echo " $0 oABCD1234 TM00001 --data '{...}' --url https://example.com/path"
33
+ exit 1
34
+ fi
35
+
36
+ OPENID="$1"
37
+ TEMPLATE_ID="$2"
38
+ shift 2
39
+
40
+ DATA=""
41
+ URL=""
42
+
43
+ while [ $# -gt 0 ]; do
44
+ case "$1" in
45
+ --data)
46
+ if [ $# -lt 2 ]; then
47
+ echo "Error: --data requires a JSON value"
48
+ exit 1
49
+ fi
50
+ DATA="$2"
51
+ shift 2
52
+ ;;
53
+ --url)
54
+ if [ $# -lt 2 ]; then
55
+ echo "Error: --url requires a value"
56
+ exit 1
57
+ fi
58
+ URL="$2"
59
+ shift 2
60
+ ;;
61
+ *)
62
+ echo "Unknown option: $1"
63
+ exit 1
64
+ ;;
65
+ esac
66
+ done
67
+
68
+ if [ -z "$DATA" ]; then
69
+ echo "Error: --data is required"
70
+ exit 1
71
+ fi
72
+
73
+ RED='\033[0;31m'
74
+ GREEN='\033[0;32m'
75
+ YELLOW='\033[1;33m'
76
+ NC='\033[0m'
77
+
78
+ # Check if agent-wechatbot is installed
79
+ if ! command -v agent-wechatbot &> /dev/null; then
80
+ echo -e "${RED}Error: agent-wechatbot not found${NC}"
81
+ echo ""
82
+ echo "Install it with:"
83
+ echo " npm install -g agent-messenger"
84
+ exit 1
85
+ fi
86
+
87
+ # Check authentication
88
+ echo "Checking authentication..."
89
+ AUTH_STATUS=$(agent-wechatbot auth status 2>&1) || true
90
+
91
+ if echo "$AUTH_STATUS" | jq -e '.error' > /dev/null 2>&1; then
92
+ echo -e "${RED}Not authenticated!${NC}"
93
+ echo ""
94
+ echo "Run this to authenticate:"
95
+ echo " agent-wechatbot auth set <app-id> <app-secret>"
96
+ exit 1
97
+ fi
98
+
99
+ APP_ID=$(echo "$AUTH_STATUS" | jq -r '.app_id // "Unknown"')
100
+ echo -e "${GREEN}✓ Authenticated (App ID: $APP_ID)${NC}"
101
+ echo ""
102
+
103
+ # Send template message with retry
104
+ max_attempts=3
105
+ attempt=1
106
+
107
+ echo "Sending template '$TEMPLATE_ID' to $OPENID..."
108
+ if [ -n "$URL" ]; then
109
+ echo "URL: $URL"
110
+ fi
111
+ echo ""
112
+
113
+ while [ $attempt -le $max_attempts ]; do
114
+ echo -e "${YELLOW}Attempt $attempt/$max_attempts...${NC}"
115
+
116
+ if [ -n "$URL" ]; then
117
+ RESULT=$(agent-wechatbot template send "$OPENID" "$TEMPLATE_ID" --data "$DATA" --url "$URL" 2>&1) || true
118
+ else
119
+ RESULT=$(agent-wechatbot template send "$OPENID" "$TEMPLATE_ID" --data "$DATA" 2>&1) || true
120
+ fi
121
+
122
+ if ! echo "$RESULT" | jq -e '.error' > /dev/null 2>&1; then
123
+ echo -e "${GREEN}✓ Template message sent successfully!${NC}"
124
+ echo ""
125
+ echo "Message details:"
126
+ echo " To OpenID: $OPENID"
127
+ echo " Template: $TEMPLATE_ID"
128
+ if [ -n "$URL" ]; then
129
+ echo " URL: $URL"
130
+ fi
131
+ exit 0
132
+ fi
133
+
134
+ ERROR_MSG=$(echo "$RESULT" | jq -r '.error // "Unknown error"')
135
+ echo -e "${RED}✗ Failed: $ERROR_MSG${NC}"
136
+
137
+ # Don't retry on permanent errors
138
+ if echo "$ERROR_MSG" | grep -qE "40164|IP whitelist|40125|Invalid App"; then
139
+ exit 1
140
+ fi
141
+
142
+ if [ $attempt -lt $max_attempts ]; then
143
+ SLEEP_TIME=$((attempt * 2))
144
+ echo "Retrying in ${SLEEP_TIME}s..."
145
+ sleep $SLEEP_TIME
146
+ fi
147
+
148
+ attempt=$((attempt + 1))
149
+ done
150
+
151
+ echo -e "${RED}Failed after $max_attempts attempts${NC}"
152
+ exit 1
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-whatsapp
3
3
  description: Interact with WhatsApp - send messages, read chats, manage conversations
4
- version: 2.10.1
4
+ version: 2.11.0
5
5
  allowed-tools: Bash(agent-whatsapp:*)
6
6
  metadata:
7
7
  openclaw:
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: agent-whatsappbot
3
3
  description: Interact with WhatsApp using Cloud API credentials - send messages, manage templates
4
- version: 2.10.1
4
+ version: 2.11.0
5
5
  allowed-tools: Bash(agent-whatsappbot:*)
6
6
  metadata:
7
7
  openclaw:
@@ -245,6 +245,8 @@ agent-whatsappbot template list --pretty
245
245
 
246
246
  ## Common Patterns
247
247
 
248
+ See `references/common-patterns.md` for additional workflows.
249
+
248
250
  ### Send a notification outside the 24h window
249
251
 
250
252
  Template messages are required when the customer hasn't messaged you in the last 24 hours. Always check your available templates first:
@@ -286,6 +288,14 @@ agent-whatsappbot message send-template 15559876543 deployment_alert \
286
288
  --components '[{"type":"body","parameters":[{"type":"text","text":"v2.1.0"},{"type":"text","text":"production"},{"type":"text","text":"success"}]}]'
287
289
  ```
288
290
 
291
+ ## Templates
292
+
293
+ See `templates/` directory for runnable examples:
294
+
295
+ - `post-message.sh` - Send messages with error handling and retries
296
+ - `account-summary.sh` - Generate account and template summary
297
+ - `send-template.sh` - Send a template message with parameters
298
+
289
299
  ## Error Handling
290
300
 
291
301
  All commands return consistent error format:
@@ -318,6 +328,20 @@ Config format:
318
328
  }
319
329
  ```
320
330
 
331
+ ## Key Differences from agent-whatsapp
332
+
333
+ | Feature | agent-whatsapp | agent-whatsappbot |
334
+ | ----------------- | ------------------------------------ | ---------------------------------- |
335
+ | Auth type | User account (Baileys, QR/pairing) | Cloud API (Phone Number ID + Token) |
336
+ | Token source | Pairing flow with phone number | Meta Business Manager |
337
+ | Read messages | Yes | No (webhook-only inbound) |
338
+ | Group chats | Yes | No |
339
+ | Template messages | No | Yes (required outside 24h window) |
340
+ | Free-form text | Anytime | Only within 24h customer window |
341
+ | Media uploads | Direct (local files) | URL only |
342
+ | Multi-account | Multi-phone, single CLI session | Multi-account by Phone Number ID |
343
+ | CI/CD friendly | Requires phone, pairing flow | Yes (just set token) |
344
+
321
345
  ## Limitations
322
346
 
323
347
  - **Cannot list or read received messages** — WhatsApp Cloud API delivers inbound messages via webhooks only. This CLI is send-only.
@@ -378,3 +402,8 @@ WhatsApp enforces rate limits based on your business tier. The CLI automatically
378
402
  - Use full international format without `+` prefix (e.g., `15551234567` not `+1-555-123-4567`)
379
403
  - If outside the 24h window, use `message send-template` instead of `message send`
380
404
  - Check that your WhatsApp Business account is active and not restricted
405
+
406
+ ## References
407
+
408
+ - [Authentication Guide](references/authentication.md)
409
+ - [Common Patterns](references/common-patterns.md)
@@ -1,4 +1,4 @@
1
- import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
1
+ import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
2
2
 
3
3
  import { ChannelClient } from './client'
4
4
  import { ChannelError } from './types'
@@ -51,7 +51,7 @@ describe('ChannelClient', () => {
51
51
  const getJsonBody = (callIndex = 0) =>
52
52
  JSON.parse(String(fetchCalls[callIndex]?.options?.body)) as Record<string, unknown>
53
53
 
54
- test('login() requires account cookie', async () => {
54
+ it('login() requires account cookie', async () => {
55
55
  await expect(new ChannelClient().login({ accountCookie: '' })).rejects.toThrow(ChannelError)
56
56
  await expect(new ChannelClient().login({ accountCookie: '', sessionCookie: 'session-cookie' })).rejects.toThrow(
57
57
  ChannelError,
@@ -62,7 +62,7 @@ describe('ChannelClient', () => {
62
62
  expect(client2).toBeInstanceOf(ChannelClient)
63
63
  })
64
64
 
65
- test('successful GET request returns unwrapped JSON', async () => {
65
+ it('successful GET request returns unwrapped JSON', async () => {
66
66
  mockResponse({
67
67
  account: {
68
68
  id: 'acc-1',
@@ -82,7 +82,7 @@ describe('ChannelClient', () => {
82
82
  expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/account')
83
83
  })
84
84
 
85
- test('cookie auth headers are set on every request', async () => {
85
+ it('cookie auth headers are set on every request', async () => {
86
86
  mockResponse({
87
87
  account: {
88
88
  id: 'acc-1',
@@ -108,7 +108,7 @@ describe('ChannelClient', () => {
108
108
  }
109
109
  })
110
110
 
111
- test('429 response triggers retry with Retry-After wait', async () => {
111
+ it('429 response triggers retry with Retry-After wait', async () => {
112
112
  mockResponse({ errors: [{ message: 'Rate limited' }] }, 429, { 'Retry-After': '0.05' })
113
113
  mockResponse({
114
114
  account: {
@@ -132,7 +132,7 @@ describe('ChannelClient', () => {
132
132
  expect(elapsed).toBeGreaterThanOrEqual(40)
133
133
  })
134
134
 
135
- test('500 response triggers retry with exponential backoff for GET requests', async () => {
135
+ it('500 response triggers retry with exponential backoff for GET requests', async () => {
136
136
  mockResponse({ errors: [{ message: 'Server error' }] }, 500)
137
137
  mockResponse({ errors: [{ message: 'Server error' }] }, 500)
138
138
  mockResponse({
@@ -157,7 +157,7 @@ describe('ChannelClient', () => {
157
157
  expect(elapsed).toBeGreaterThanOrEqual(280)
158
158
  })
159
159
 
160
- test('4xx non-429 throws immediately without retry', async () => {
160
+ it('4xx non-429 throws immediately without retry', async () => {
161
161
  mockResponse({ type: 'forbidden', errors: [{ message: 'Forbidden' }] }, 403)
162
162
 
163
163
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -165,7 +165,7 @@ describe('ChannelClient', () => {
165
165
  expect(fetchCalls).toHaveLength(1)
166
166
  })
167
167
 
168
- test('network error retries then throws ChannelError with code network_error', async () => {
168
+ it('network error retries then throws ChannelError with code network_error', async () => {
169
169
  ;(globalThis as Record<string, unknown>).fetch = async (
170
170
  url: string | URL | Request,
171
171
  options?: RequestInit,
@@ -186,7 +186,7 @@ describe('ChannelClient', () => {
186
186
  }
187
187
  })
188
188
 
189
- test('204 response returns undefined', async () => {
189
+ it('204 response returns undefined', async () => {
190
190
  mockResponse(null, 204)
191
191
 
192
192
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -197,7 +197,7 @@ describe('ChannelClient', () => {
197
197
  expect(result).toBeUndefined()
198
198
  })
199
199
 
200
- test('wrapTextInBlocks returns a single text block and extractText joins block and plain text', () => {
200
+ it('wrapTextInBlocks returns a single text block and extractText joins block and plain text', () => {
201
201
  expect(ChannelClient.wrapTextInBlocks('Hello world')).toEqual([{ type: 'text', value: 'Hello world' }])
202
202
 
203
203
  expect(
@@ -212,7 +212,7 @@ describe('ChannelClient', () => {
212
212
  ).toBe('hello\nworld\nfallback')
213
213
  })
214
214
 
215
- test('listChannels includes query params', async () => {
215
+ it('listChannels includes query params', async () => {
216
216
  mockResponse({ channels: [{ id: 'ch-1', name: 'Support' }] })
217
217
 
218
218
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -222,7 +222,7 @@ describe('ChannelClient', () => {
222
222
  expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels?limit=500')
223
223
  })
224
224
 
225
- test('getChannel uses the channel detail endpoint', async () => {
225
+ it('getChannel uses the channel detail endpoint', async () => {
226
226
  mockResponse({ channel: { id: 'ch-1', name: 'Support' } })
227
227
 
228
228
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -231,7 +231,7 @@ describe('ChannelClient', () => {
231
231
  expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1')
232
232
  })
233
233
 
234
- test('listManagers uses the managers endpoint', async () => {
234
+ it('listManagers uses the managers endpoint', async () => {
235
235
  mockResponse({ managers: [{ id: 'mgr-1', channelId: 'ch-1', accountId: 'acc-1', name: 'Alex' }] })
236
236
 
237
237
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -241,7 +241,7 @@ describe('ChannelClient', () => {
241
241
  expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1/managers?limit=200')
242
242
  })
243
243
 
244
- test('getManagerRole unwraps the role response', async () => {
244
+ it('getManagerRole unwraps the role response', async () => {
245
245
  mockResponse({ role: { permissions: ['read'] } })
246
246
 
247
247
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -251,7 +251,7 @@ describe('ChannelClient', () => {
251
251
  expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1/managers/me/role')
252
252
  })
253
253
 
254
- test('group endpoints build the expected URLs', async () => {
254
+ it('group endpoints build the expected URLs', async () => {
255
255
  mockResponse({ groups: [{ id: 'grp-1', channelId: 'ch-1', name: 'ops' }] })
256
256
  mockResponse({ group: { id: 'grp-1', channelId: 'ch-1', name: 'ops' } })
257
257
  mockResponse({ messages: [{ id: 'msg-1' }] })
@@ -273,7 +273,7 @@ describe('ChannelClient', () => {
273
273
  expect(messagesUrl.searchParams.get('since')).toBe('cursor-1')
274
274
  })
275
275
 
276
- test('sendGroupMessage includes requestId in the body', async () => {
276
+ it('sendGroupMessage includes requestId in the body', async () => {
277
277
  mockResponse({ message: { id: 'msg-1', requestId: 'req-123' } })
278
278
 
279
279
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -285,7 +285,7 @@ describe('ChannelClient', () => {
285
285
  expect(getJsonBody()).toEqual({ blocks, requestId: 'req-123' })
286
286
  })
287
287
 
288
- test('direct chat endpoints build the expected URLs', async () => {
288
+ it('direct chat endpoints build the expected URLs', async () => {
289
289
  mockResponse({ directChats: [{ id: 'dm-1', channelId: 'ch-1' }] })
290
290
  mockResponse({ messages: [{ id: 'msg-1' }] })
291
291
  mockResponse({ message: { id: 'msg-2', requestId: 'req-234' } })
@@ -305,7 +305,7 @@ describe('ChannelClient', () => {
305
305
  expect(getJsonBody(2)).toEqual({ blocks, requestId: 'req-234' })
306
306
  })
307
307
 
308
- test('user chat endpoints build the expected URLs', async () => {
308
+ it('user chat endpoints build the expected URLs', async () => {
309
309
  mockResponse({ userChats: [{ id: 'uc-1', channelId: 'ch-1', state: 'opened' }] })
310
310
  mockResponse({ userChat: { id: 'uc-1', channelId: 'ch-1', state: 'opened' } })
311
311
  mockResponse({ messages: [{ id: 'msg-1' }] })
@@ -330,7 +330,7 @@ describe('ChannelClient', () => {
330
330
  expect(getJsonBody(3)).toEqual({ blocks, requestId: 'req-345' })
331
331
  })
332
332
 
333
- test('listBots uses the bots endpoint', async () => {
333
+ it('listBots uses the bots endpoint', async () => {
334
334
  mockResponse({ bots: [{ id: 'bot-1', channelId: 'ch-1', name: 'DeskBot' }] })
335
335
 
336
336
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -340,7 +340,7 @@ describe('ChannelClient', () => {
340
340
  expect(fetchCalls[0].url).toBe('https://desk-api.channel.io/desk/channels/ch-1/bots?limit=1000')
341
341
  })
342
342
 
343
- test('5xx on POST does not retry', async () => {
343
+ it('5xx on POST does not retry', async () => {
344
344
  mockResponse({ type: 'server_error', errors: [{ message: 'Server error' }] }, 500)
345
345
 
346
346
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -350,7 +350,7 @@ describe('ChannelClient', () => {
350
350
  expect(fetchCalls).toHaveLength(1)
351
351
  })
352
352
 
353
- test('error responses use desk API error fields', async () => {
353
+ it('error responses use desk API error fields', async () => {
354
354
  mockResponse({ type: 'not_found', status: 404, errors: [{ message: 'Missing resource' }], language: 'en' }, 404)
355
355
 
356
356
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -365,7 +365,7 @@ describe('ChannelClient', () => {
365
365
  }
366
366
  })
367
367
 
368
- test('rate limit headers delay the next request when remaining is zero', async () => {
368
+ it('rate limit headers delay the next request when remaining is zero', async () => {
369
369
  mockResponse(
370
370
  {
371
371
  account: {
@@ -407,7 +407,7 @@ describe('ChannelClient', () => {
407
407
  expect(fetchCalls).toHaveLength(2)
408
408
  })
409
409
 
410
- test('generated requests still include the cookie header on post endpoints', async () => {
410
+ it('generated requests still include the cookie header on post endpoints', async () => {
411
411
  mockResponse({ message: { id: 'msg-1' } })
412
412
 
413
413
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })
@@ -416,7 +416,7 @@ describe('ChannelClient', () => {
416
416
  expect(getHeaders().Cookie).toBe('x-account=account-cookie; ch-session-1=session-cookie')
417
417
  })
418
418
 
419
- test('searchTeamChatMessages builds correct URL with query and limit', async () => {
419
+ it('searchTeamChatMessages builds correct URL with query and limit', async () => {
420
420
  const searchResponse = {
421
421
  hits: [
422
422
  {
@@ -443,7 +443,7 @@ describe('ChannelClient', () => {
443
443
  expect(result.hits).toHaveLength(1)
444
444
  })
445
445
 
446
- test('searchUserChatMessages builds correct URL with query', async () => {
446
+ it('searchUserChatMessages builds correct URL with query', async () => {
447
447
  const searchResponse = {
448
448
  hits: [],
449
449
  bots: [],
@@ -461,7 +461,7 @@ describe('ChannelClient', () => {
461
461
  expect(result.hits).toHaveLength(0)
462
462
  })
463
463
 
464
- test('searchTeamChatMessages works without limit parameter', async () => {
464
+ it('searchTeamChatMessages works without limit parameter', async () => {
465
465
  mockResponse({ hits: [], bots: [], sessions: [] })
466
466
 
467
467
  const client = await new ChannelClient().login({ accountCookie: 'account-cookie', sessionCookie: 'session-cookie' })