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.
- package/.claude-plugin/plugin.json +1 -1
- package/.env.template +4 -1
- package/README.md +77 -27
- package/bun.lock +26 -0
- package/dist/package.json +14 -1
- package/dist/src/platforms/channeltalk/commands/auth.d.ts +2 -1
- package/dist/src/platforms/channeltalk/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/commands/auth.js +5 -3
- package/dist/src/platforms/channeltalk/commands/auth.js.map +1 -1
- package/dist/src/platforms/channeltalk/token-extractor.d.ts +2 -1
- package/dist/src/platforms/channeltalk/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/channeltalk/token-extractor.js +22 -6
- package/dist/src/platforms/channeltalk/token-extractor.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/cli.js +11 -1
- package/dist/src/platforms/channeltalkbot/cli.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/auth.js +1 -5
- package/dist/src/platforms/channeltalkbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/bot.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/bot.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/bot.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/chat.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/chat.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/chat.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/group.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/group.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/group.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/manager.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/manager.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/manager.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/message.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/message.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/commands/whoami.js +1 -6
- package/dist/src/platforms/channeltalkbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/channeltalkbot/credential-manager.d.ts +5 -0
- package/dist/src/platforms/channeltalkbot/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/channeltalkbot/credential-manager.js +34 -4
- package/dist/src/platforms/channeltalkbot/credential-manager.js.map +1 -1
- package/dist/src/platforms/discord/commands/auth.d.ts +1 -0
- package/dist/src/platforms/discord/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/discord/commands/auth.js +3 -1
- package/dist/src/platforms/discord/commands/auth.js.map +1 -1
- package/dist/src/platforms/discord/listener.d.ts +2 -0
- package/dist/src/platforms/discord/listener.d.ts.map +1 -1
- package/dist/src/platforms/discord/listener.js +51 -21
- package/dist/src/platforms/discord/listener.js.map +1 -1
- package/dist/src/platforms/discord/token-extractor.d.ts +2 -1
- package/dist/src/platforms/discord/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/discord/token-extractor.js +21 -6
- package/dist/src/platforms/discord/token-extractor.js.map +1 -1
- package/dist/src/platforms/discordbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/cli.js +12 -1
- package/dist/src/platforms/discordbot/cli.js.map +1 -1
- package/dist/src/platforms/discordbot/client.d.ts +3 -0
- package/dist/src/platforms/discordbot/client.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/client.js +3 -0
- package/dist/src/platforms/discordbot/client.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/auth.js +1 -5
- package/dist/src/platforms/discordbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/message.js +1 -6
- package/dist/src/platforms/discordbot/commands/message.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/server.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/server.js +1 -4
- package/dist/src/platforms/discordbot/commands/server.js.map +1 -1
- package/dist/src/platforms/discordbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/commands/whoami.js +1 -6
- package/dist/src/platforms/discordbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/discordbot/index.d.ts +3 -1
- package/dist/src/platforms/discordbot/index.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/index.js +2 -1
- package/dist/src/platforms/discordbot/index.js.map +1 -1
- package/dist/src/platforms/discordbot/listener.d.ts +43 -0
- package/dist/src/platforms/discordbot/listener.d.ts.map +1 -0
- package/dist/src/platforms/discordbot/listener.js +292 -0
- package/dist/src/platforms/discordbot/listener.js.map +1 -0
- package/dist/src/platforms/discordbot/types.d.ts +161 -0
- package/dist/src/platforms/discordbot/types.d.ts.map +1 -1
- package/dist/src/platforms/discordbot/types.js +34 -0
- package/dist/src/platforms/discordbot/types.js.map +1 -1
- package/dist/src/platforms/instagram/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/instagram/commands/auth.js +3 -1
- package/dist/src/platforms/instagram/commands/auth.js.map +1 -1
- package/dist/src/platforms/instagram/token-extractor.d.ts +2 -1
- package/dist/src/platforms/instagram/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/instagram/token-extractor.js +11 -2
- package/dist/src/platforms/instagram/token-extractor.js.map +1 -1
- package/dist/src/platforms/slack/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slack/commands/auth.js +4 -2
- package/dist/src/platforms/slack/commands/auth.js.map +1 -1
- package/dist/src/platforms/slack/token-extractor.d.ts +4 -1
- package/dist/src/platforms/slack/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/slack/token-extractor.js +64 -15
- package/dist/src/platforms/slack/token-extractor.js.map +1 -1
- package/dist/src/platforms/slackbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/cli.js +15 -3
- package/dist/src/platforms/slackbot/cli.js.map +1 -1
- package/dist/src/platforms/slackbot/client.d.ts +22 -1
- package/dist/src/platforms/slackbot/client.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/client.js +104 -1
- package/dist/src/platforms/slackbot/client.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/auth.js +1 -5
- package/dist/src/platforms/slackbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/file.d.ts +3 -0
- package/dist/src/platforms/slackbot/commands/file.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/commands/file.js +164 -0
- package/dist/src/platforms/slackbot/commands/file.js.map +1 -0
- package/dist/src/platforms/slackbot/commands/index.d.ts +1 -0
- package/dist/src/platforms/slackbot/commands/index.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/index.js +1 -0
- package/dist/src/platforms/slackbot/commands/index.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/message.js +19 -0
- package/dist/src/platforms/slackbot/commands/message.js.map +1 -1
- package/dist/src/platforms/slackbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/commands/whoami.js +1 -6
- package/dist/src/platforms/slackbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/slackbot/credential-manager.d.ts +1 -0
- package/dist/src/platforms/slackbot/credential-manager.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/credential-manager.js +30 -2
- package/dist/src/platforms/slackbot/credential-manager.js.map +1 -1
- package/dist/src/platforms/slackbot/index.d.ts +4 -1
- package/dist/src/platforms/slackbot/index.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/index.js +1 -0
- package/dist/src/platforms/slackbot/index.js.map +1 -1
- package/dist/src/platforms/slackbot/listener.d.ts +44 -0
- package/dist/src/platforms/slackbot/listener.d.ts.map +1 -0
- package/dist/src/platforms/slackbot/listener.js +313 -0
- package/dist/src/platforms/slackbot/listener.js.map +1 -0
- package/dist/src/platforms/slackbot/types.d.ts +196 -1
- package/dist/src/platforms/slackbot/types.d.ts.map +1 -1
- package/dist/src/platforms/slackbot/types.js +4 -1
- package/dist/src/platforms/slackbot/types.js.map +1 -1
- package/dist/src/platforms/teams/commands/auth.d.ts +1 -0
- package/dist/src/platforms/teams/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/teams/commands/auth.js +37 -6
- package/dist/src/platforms/teams/commands/auth.js.map +1 -1
- package/dist/src/platforms/teams/ensure-auth.js +31 -9
- package/dist/src/platforms/teams/ensure-auth.js.map +1 -1
- package/dist/src/platforms/teams/token-extractor.d.ts +4 -1
- package/dist/src/platforms/teams/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/teams/token-extractor.js +80 -31
- package/dist/src/platforms/teams/token-extractor.js.map +1 -1
- package/dist/src/platforms/webex/commands/auth.d.ts +1 -0
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/auth.js +3 -1
- package/dist/src/platforms/webex/commands/auth.js.map +1 -1
- package/dist/src/platforms/webex/token-extractor.d.ts +3 -1
- package/dist/src/platforms/webex/token-extractor.d.ts.map +1 -1
- package/dist/src/platforms/webex/token-extractor.js +16 -2
- package/dist/src/platforms/webex/token-extractor.js.map +1 -1
- package/dist/src/platforms/wechatbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/cli.js +11 -1
- package/dist/src/platforms/wechatbot/cli.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/auth.js +1 -5
- package/dist/src/platforms/wechatbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/message.js +1 -6
- package/dist/src/platforms/wechatbot/commands/message.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/template.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/template.js +1 -6
- package/dist/src/platforms/wechatbot/commands/template.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/user.js +1 -6
- package/dist/src/platforms/wechatbot/commands/user.js.map +1 -1
- package/dist/src/platforms/wechatbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/wechatbot/commands/whoami.js +1 -6
- package/dist/src/platforms/wechatbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/whatsappbot/cli.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/cli.js +11 -1
- package/dist/src/platforms/whatsappbot/cli.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/auth.js +1 -5
- package/dist/src/platforms/whatsappbot/commands/auth.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/message.js +1 -6
- package/dist/src/platforms/whatsappbot/commands/message.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/template.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/template.js +1 -6
- package/dist/src/platforms/whatsappbot/commands/template.js.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/whatsappbot/commands/whoami.js +1 -6
- package/dist/src/platforms/whatsappbot/commands/whoami.js.map +1 -1
- package/dist/src/shared/chromium/browsers.d.ts +8 -0
- package/dist/src/shared/chromium/browsers.d.ts.map +1 -1
- package/dist/src/shared/chromium/browsers.js +58 -3
- package/dist/src/shared/chromium/browsers.js.map +1 -1
- package/dist/src/shared/chromium/cli-options.d.ts +5 -0
- package/dist/src/shared/chromium/cli-options.d.ts.map +1 -0
- package/dist/src/shared/chromium/cli-options.js +8 -0
- package/dist/src/shared/chromium/cli-options.js.map +1 -0
- package/dist/src/shared/chromium/decryptor.d.ts +6 -0
- package/dist/src/shared/chromium/decryptor.d.ts.map +1 -1
- package/dist/src/shared/chromium/decryptor.js +26 -6
- package/dist/src/shared/chromium/decryptor.js.map +1 -1
- package/dist/src/shared/chromium/index.d.ts +3 -1
- package/dist/src/shared/chromium/index.d.ts.map +1 -1
- package/dist/src/shared/chromium/index.js +2 -1
- package/dist/src/shared/chromium/index.js.map +1 -1
- package/dist/src/shared/utils/cli-output.d.ts +7 -0
- package/dist/src/shared/utils/cli-output.d.ts.map +1 -0
- package/dist/src/shared/utils/cli-output.js +7 -0
- package/dist/src/shared/utils/cli-output.js.map +1 -0
- package/dist/src/tui/app.d.ts.map +1 -1
- package/dist/src/tui/app.js +73 -20
- package/dist/src/tui/app.js.map +1 -1
- package/docs/content/docs/cli/channeltalk.mdx +4 -0
- package/docs/content/docs/cli/discord.mdx +5 -0
- package/docs/content/docs/cli/instagram.mdx +3 -0
- package/docs/content/docs/cli/slack.mdx +5 -0
- package/docs/content/docs/cli/slackbot.mdx +60 -22
- package/docs/content/docs/cli/teams.mdx +5 -0
- package/docs/content/docs/cli/webex.mdx +3 -0
- package/docs/content/docs/sdk/channeltalkbot.mdx +38 -1
- package/docs/content/docs/sdk/discordbot.mdx +501 -0
- package/docs/content/docs/sdk/meta.json +2 -0
- package/docs/content/docs/sdk/slackbot.mdx +576 -0
- package/e2e/README.md +1 -1
- package/e2e/channeltalk.e2e.test.ts +13 -13
- package/e2e/channeltalkbot.e2e.test.ts +13 -13
- package/e2e/config.ts +9 -4
- package/e2e/discord.e2e.test.ts +24 -24
- package/e2e/discordbot.e2e.test.ts +16 -16
- package/e2e/instagram.e2e.test.ts +10 -10
- package/e2e/kakaotalk.e2e.test.ts +7 -7
- package/e2e/line.e2e.test.ts +8 -8
- package/e2e/slack.e2e.test.ts +34 -34
- package/e2e/slackbot.e2e.test.ts +14 -14
- package/e2e/teams.e2e.test.ts +23 -23
- package/e2e/telegram.e2e.test.ts +8 -8
- package/e2e/webex.e2e.test.ts +14 -14
- package/e2e/whatsapp.e2e.test.ts +8 -8
- package/e2e/whatsappbot.e2e.test.ts +6 -6
- package/examples/discordbot-listen.ts +65 -0
- package/examples/slackbot-listen.ts +65 -0
- package/package.json +14 -1
- package/skills/agent-channeltalk/SKILL.md +5 -1
- package/skills/agent-channeltalk/references/authentication.md +5 -1
- package/skills/agent-channeltalkbot/SKILL.md +17 -3
- package/skills/agent-channeltalkbot/references/authentication.md +7 -5
- package/skills/agent-discord/SKILL.md +5 -1
- package/skills/agent-discord/references/authentication.md +7 -1
- package/skills/agent-discordbot/SKILL.md +13 -2
- package/skills/agent-discordbot/references/common-patterns.md +1 -1
- package/skills/agent-instagram/SKILL.md +7 -1
- package/skills/agent-instagram/references/authentication.md +6 -0
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +5 -1
- package/skills/agent-slack/references/authentication.md +7 -1
- package/skills/agent-slackbot/SKILL.md +56 -4
- package/skills/agent-slackbot/references/authentication.md +4 -0
- package/skills/agent-teams/SKILL.md +5 -1
- package/skills/agent-teams/references/authentication.md +7 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +7 -1
- package/skills/agent-webex/references/authentication.md +6 -0
- package/skills/agent-wechatbot/SKILL.md +16 -1
- package/skills/agent-wechatbot/references/authentication.md +219 -0
- package/skills/agent-wechatbot/references/common-patterns.md +358 -0
- package/skills/agent-wechatbot/templates/account-summary.sh +122 -0
- package/skills/agent-wechatbot/templates/post-message.sh +122 -0
- package/skills/agent-wechatbot/templates/send-template.sh +152 -0
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +30 -1
- package/src/platforms/channeltalk/client.test.ts +26 -26
- package/src/platforms/channeltalk/commands/auth.test.ts +31 -19
- package/src/platforms/channeltalk/commands/auth.ts +15 -5
- package/src/platforms/channeltalk/commands/bot.test.ts +2 -2
- package/src/platforms/channeltalk/commands/chat.test.ts +3 -3
- package/src/platforms/channeltalk/commands/group.test.ts +4 -4
- package/src/platforms/channeltalk/commands/manager.test.ts +2 -2
- package/src/platforms/channeltalk/commands/message.test.ts +17 -17
- package/src/platforms/channeltalk/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalk/commands/whoami.test.ts +3 -3
- package/src/platforms/channeltalk/credential-manager.test.ts +18 -18
- package/src/platforms/channeltalk/ensure-auth.test.ts +5 -5
- package/src/platforms/channeltalk/index.test.ts +23 -23
- package/src/platforms/channeltalk/token-extractor.test.ts +21 -21
- package/src/platforms/channeltalk/token-extractor.ts +24 -5
- package/src/platforms/channeltalk/types.test.ts +12 -12
- package/src/platforms/channeltalkbot/cli.ts +9 -0
- package/src/platforms/channeltalkbot/client.test.ts +14 -14
- package/src/platforms/channeltalkbot/commands/auth.test.ts +16 -16
- package/src/platforms/channeltalkbot/commands/auth.ts +1 -5
- package/src/platforms/channeltalkbot/commands/bot.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/bot.ts +1 -6
- package/src/platforms/channeltalkbot/commands/chat.test.ts +9 -9
- package/src/platforms/channeltalkbot/commands/chat.ts +1 -6
- package/src/platforms/channeltalkbot/commands/group.test.ts +6 -6
- package/src/platforms/channeltalkbot/commands/group.ts +1 -6
- package/src/platforms/channeltalkbot/commands/manager.test.ts +3 -3
- package/src/platforms/channeltalkbot/commands/manager.ts +1 -6
- package/src/platforms/channeltalkbot/commands/message.test.ts +10 -10
- package/src/platforms/channeltalkbot/commands/message.ts +1 -6
- package/src/platforms/channeltalkbot/commands/snapshot.test.ts +7 -7
- package/src/platforms/channeltalkbot/commands/whoami.test.ts +6 -4
- package/src/platforms/channeltalkbot/commands/whoami.ts +1 -6
- package/src/platforms/channeltalkbot/credential-manager.test.ts +123 -29
- package/src/platforms/channeltalkbot/credential-manager.ts +37 -4
- package/src/platforms/channeltalkbot/index.test.ts +15 -15
- package/src/platforms/discord/client.test.ts +28 -28
- package/src/platforms/discord/commands/auth.test.ts +7 -7
- package/src/platforms/discord/commands/auth.ts +13 -2
- package/src/platforms/discord/commands/channel.test.ts +7 -7
- package/src/platforms/discord/commands/dm.test.ts +4 -4
- package/src/platforms/discord/commands/file.test.ts +4 -4
- package/src/platforms/discord/commands/friend.test.ts +6 -6
- package/src/platforms/discord/commands/member.test.ts +5 -5
- package/src/platforms/discord/commands/mention.test.ts +5 -5
- package/src/platforms/discord/commands/message.test.ts +9 -9
- package/src/platforms/discord/commands/note.test.ts +6 -6
- package/src/platforms/discord/commands/profile.test.ts +4 -4
- package/src/platforms/discord/commands/reaction.test.ts +5 -5
- package/src/platforms/discord/commands/server.test.ts +7 -7
- package/src/platforms/discord/commands/snapshot.test.ts +6 -6
- package/src/platforms/discord/commands/thread.test.ts +6 -6
- package/src/platforms/discord/commands/user.test.ts +5 -5
- package/src/platforms/discord/commands/whoami.test.ts +6 -6
- package/src/platforms/discord/credential-manager.test.ts +16 -16
- package/src/platforms/discord/ensure-auth.test.ts +8 -8
- package/src/platforms/discord/index.test.ts +17 -17
- package/src/platforms/discord/listener.test.ts +92 -34
- package/src/platforms/discord/listener.ts +43 -19
- package/src/platforms/discord/token-extractor.test.ts +53 -53
- package/src/platforms/discord/token-extractor.ts +30 -6
- package/src/platforms/discord/types.test.ts +26 -26
- package/src/platforms/discordbot/cli.ts +10 -0
- package/src/platforms/discordbot/client.test.ts +31 -31
- package/src/platforms/discordbot/client.ts +4 -0
- package/src/platforms/discordbot/commands/auth.test.ts +18 -18
- package/src/platforms/discordbot/commands/auth.ts +1 -5
- package/src/platforms/discordbot/commands/channel.test.ts +11 -11
- package/src/platforms/discordbot/commands/file.test.ts +7 -7
- package/src/platforms/discordbot/commands/message.test.ts +25 -25
- package/src/platforms/discordbot/commands/message.ts +1 -6
- package/src/platforms/discordbot/commands/reaction.test.ts +6 -6
- package/src/platforms/discordbot/commands/server.test.ts +12 -12
- package/src/platforms/discordbot/commands/server.ts +1 -5
- package/src/platforms/discordbot/commands/snapshot.test.ts +13 -13
- package/src/platforms/discordbot/commands/thread.test.ts +10 -10
- package/src/platforms/discordbot/commands/user.test.ts +9 -9
- package/src/platforms/discordbot/commands/whoami.test.ts +4 -4
- package/src/platforms/discordbot/commands/whoami.ts +1 -6
- package/src/platforms/discordbot/credential-manager.test.ts +28 -28
- package/src/platforms/discordbot/index.test.ts +82 -0
- package/src/platforms/discordbot/index.ts +27 -9
- package/src/platforms/discordbot/listener.test.ts +1002 -0
- package/src/platforms/discordbot/listener.ts +321 -0
- package/src/platforms/discordbot/types.ts +163 -0
- package/src/platforms/instagram/client.test.ts +18 -18
- package/src/platforms/instagram/commands/auth.test.ts +11 -11
- package/src/platforms/instagram/commands/auth.ts +9 -1
- package/src/platforms/instagram/commands/chat.test.ts +6 -6
- package/src/platforms/instagram/commands/message.test.ts +11 -11
- package/src/platforms/instagram/commands/shared.test.ts +12 -12
- package/src/platforms/instagram/commands/whoami.test.ts +3 -3
- package/src/platforms/instagram/credential-manager.test.ts +21 -21
- package/src/platforms/instagram/ensure-auth.test.ts +4 -4
- package/src/platforms/instagram/index.test.ts +9 -9
- package/src/platforms/instagram/listener.test.ts +8 -8
- package/src/platforms/instagram/token-extractor.test.ts +35 -35
- package/src/platforms/instagram/token-extractor.ts +13 -1
- package/src/platforms/kakaotalk/client.test.ts +33 -33
- package/src/platforms/kakaotalk/commands/auth.test.ts +11 -11
- package/src/platforms/kakaotalk/commands/chat.test.ts +6 -6
- package/src/platforms/kakaotalk/commands/message.test.ts +7 -7
- package/src/platforms/kakaotalk/commands/whoami.test.ts +5 -5
- package/src/platforms/kakaotalk/credential-manager.test.ts +15 -15
- package/src/platforms/kakaotalk/index.test.ts +15 -15
- package/src/platforms/kakaotalk/listener.test.ts +17 -17
- package/src/platforms/line/client.test.ts +17 -17
- package/src/platforms/line/commands/auth.test.ts +8 -8
- package/src/platforms/line/commands/chat.test.ts +7 -7
- package/src/platforms/line/commands/friend.test.ts +6 -6
- package/src/platforms/line/commands/message.test.ts +7 -7
- package/src/platforms/line/commands/whoami.test.ts +6 -6
- package/src/platforms/line/credential-manager.test.ts +17 -17
- package/src/platforms/line/index.test.ts +10 -10
- package/src/platforms/line/listener.test.ts +15 -15
- package/src/platforms/line/types.test.ts +14 -14
- package/src/platforms/slack/cli.test.ts +8 -8
- package/src/platforms/slack/client.test.ts +151 -151
- package/src/platforms/slack/commands/activity.test.ts +13 -13
- package/src/platforms/slack/commands/auth.test.ts +34 -34
- package/src/platforms/slack/commands/auth.ts +11 -2
- package/src/platforms/slack/commands/bookmark.test.ts +9 -9
- package/src/platforms/slack/commands/channel.test.ts +17 -17
- package/src/platforms/slack/commands/drafts.test.ts +7 -7
- package/src/platforms/slack/commands/emoji.test.ts +3 -3
- package/src/platforms/slack/commands/file.test.ts +12 -12
- package/src/platforms/slack/commands/message.test.ts +19 -19
- package/src/platforms/slack/commands/pin.test.ts +7 -7
- package/src/platforms/slack/commands/reaction.test.ts +10 -10
- package/src/platforms/slack/commands/reminder.test.ts +9 -9
- package/src/platforms/slack/commands/saved.test.ts +7 -7
- package/src/platforms/slack/commands/sections.test.ts +5 -5
- package/src/platforms/slack/commands/snapshot.test.ts +13 -13
- package/src/platforms/slack/commands/unread.test.ts +6 -6
- package/src/platforms/slack/commands/user.test.ts +10 -10
- package/src/platforms/slack/commands/usergroup.test.ts +15 -15
- package/src/platforms/slack/commands/whoami.test.ts +6 -6
- package/src/platforms/slack/commands/workspace.test.ts +26 -26
- package/src/platforms/slack/credential-manager.test.ts +14 -14
- package/src/platforms/slack/ensure-auth.test.ts +21 -21
- package/src/platforms/slack/index.test.ts +12 -12
- package/src/platforms/slack/listener.test.ts +17 -17
- package/src/platforms/slack/token-extractor-node.test.ts +2 -2
- package/src/platforms/slack/token-extractor.test.ts +133 -37
- package/src/platforms/slack/token-extractor.ts +76 -13
- package/src/platforms/slack/types.test.ts +21 -21
- package/src/platforms/slackbot/cli.ts +13 -1
- package/src/platforms/slackbot/client.test.ts +296 -22
- package/src/platforms/slackbot/client.ts +130 -2
- package/src/platforms/slackbot/commands/auth.test.ts +14 -14
- package/src/platforms/slackbot/commands/auth.ts +1 -5
- package/src/platforms/slackbot/commands/channel.test.ts +7 -7
- package/src/platforms/slackbot/commands/file.test.ts +201 -0
- package/src/platforms/slackbot/commands/file.ts +212 -0
- package/src/platforms/slackbot/commands/index.ts +1 -0
- package/src/platforms/slackbot/commands/message.test.ts +13 -13
- package/src/platforms/slackbot/commands/message.ts +22 -0
- package/src/platforms/slackbot/commands/reaction.test.ts +6 -6
- package/src/platforms/slackbot/commands/user.test.ts +7 -7
- package/src/platforms/slackbot/commands/whoami.test.ts +4 -4
- package/src/platforms/slackbot/commands/whoami.ts +1 -6
- package/src/platforms/slackbot/credential-manager.test.ts +83 -23
- package/src/platforms/slackbot/credential-manager.ts +32 -2
- package/src/platforms/slackbot/index.test.ts +59 -0
- package/src/platforms/slackbot/index.ts +31 -7
- package/src/platforms/slackbot/listener.test.ts +1012 -0
- package/src/platforms/slackbot/listener.ts +362 -0
- package/src/platforms/slackbot/types.test.ts +7 -7
- package/src/platforms/slackbot/types.ts +224 -1
- package/src/platforms/teams/client.test.ts +30 -30
- package/src/platforms/teams/commands/auth.test.ts +9 -9
- package/src/platforms/teams/commands/auth.ts +66 -7
- package/src/platforms/teams/commands/channel.test.ts +7 -7
- package/src/platforms/teams/commands/file.test.ts +4 -4
- package/src/platforms/teams/commands/message.test.ts +5 -5
- package/src/platforms/teams/commands/reaction.test.ts +4 -4
- package/src/platforms/teams/commands/snapshot.test.ts +7 -7
- package/src/platforms/teams/commands/team.test.ts +8 -8
- package/src/platforms/teams/commands/user.test.ts +4 -4
- package/src/platforms/teams/commands/whoami.test.ts +6 -6
- package/src/platforms/teams/credential-manager.test.ts +17 -17
- package/src/platforms/teams/ensure-auth.test.ts +69 -18
- package/src/platforms/teams/ensure-auth.ts +39 -11
- package/src/platforms/teams/index.test.ts +15 -15
- package/src/platforms/teams/token-extractor.test.ts +251 -69
- package/src/platforms/teams/token-extractor.ts +94 -31
- package/src/platforms/teams/types.test.ts +26 -26
- package/src/platforms/telegram/app-config.test.ts +4 -4
- package/src/platforms/telegram/chat-utils.test.ts +12 -12
- package/src/platforms/telegram/client.test.ts +4 -4
- package/src/platforms/telegram/commands/auth.test.ts +16 -16
- package/src/platforms/telegram/commands/chat.test.ts +9 -9
- package/src/platforms/telegram/commands/message.test.ts +6 -6
- package/src/platforms/telegram/commands/shared.test.ts +3 -3
- package/src/platforms/telegram/commands/whoami.test.ts +3 -3
- package/src/platforms/telegram/credential-manager.test.ts +10 -10
- package/src/platforms/telegram/types.test.ts +6 -6
- package/src/platforms/webex/app-config.test.ts +8 -8
- package/src/platforms/webex/cli.test.ts +5 -5
- package/src/platforms/webex/client.test.ts +65 -65
- package/src/platforms/webex/commands/auth.test.ts +18 -18
- package/src/platforms/webex/commands/auth.ts +13 -2
- package/src/platforms/webex/commands/member.test.ts +5 -5
- package/src/platforms/webex/commands/message.test.ts +12 -12
- package/src/platforms/webex/commands/snapshot.test.ts +5 -5
- package/src/platforms/webex/commands/space.test.ts +10 -10
- package/src/platforms/webex/commands/whoami.test.ts +6 -6
- package/src/platforms/webex/credential-manager.test.ts +22 -22
- package/src/platforms/webex/encryption.test.ts +4 -4
- package/src/platforms/webex/ensure-auth.test.ts +5 -5
- package/src/platforms/webex/index.test.ts +5 -5
- package/src/platforms/webex/markdown-to-html.test.ts +33 -33
- package/src/platforms/webex/token-extractor.test.ts +23 -23
- package/src/platforms/webex/token-extractor.ts +25 -3
- package/src/platforms/webex/types.test.ts +27 -27
- package/src/platforms/wechatbot/cli.ts +9 -0
- package/src/platforms/wechatbot/client.test.ts +27 -27
- package/src/platforms/wechatbot/commands/auth.test.ts +15 -15
- package/src/platforms/wechatbot/commands/auth.ts +1 -5
- package/src/platforms/wechatbot/commands/message.test.ts +8 -8
- package/src/platforms/wechatbot/commands/message.ts +1 -6
- package/src/platforms/wechatbot/commands/template.test.ts +9 -9
- package/src/platforms/wechatbot/commands/template.ts +1 -6
- package/src/platforms/wechatbot/commands/user.test.ts +7 -7
- package/src/platforms/wechatbot/commands/user.ts +1 -6
- package/src/platforms/wechatbot/commands/whoami.test.ts +5 -5
- package/src/platforms/wechatbot/commands/whoami.ts +1 -6
- package/src/platforms/wechatbot/credential-manager.test.ts +18 -18
- package/src/platforms/wechatbot/index.test.ts +10 -10
- package/src/platforms/wechatbot/types.test.ts +25 -25
- package/src/platforms/whatsapp/commands/auth.test.ts +13 -13
- package/src/platforms/whatsapp/commands/chat.test.ts +8 -8
- package/src/platforms/whatsapp/commands/message.test.ts +10 -10
- package/src/platforms/whatsapp/commands/whoami.test.ts +3 -3
- package/src/platforms/whatsapp/credential-manager.test.ts +23 -23
- package/src/platforms/whatsapp/ensure-auth.test.ts +4 -4
- package/src/platforms/whatsapp/index.test.ts +8 -8
- package/src/platforms/whatsapp/types.test.ts +42 -42
- package/src/platforms/whatsappbot/cli.ts +9 -0
- package/src/platforms/whatsappbot/client.test.ts +27 -27
- package/src/platforms/whatsappbot/commands/auth.test.ts +14 -14
- package/src/platforms/whatsappbot/commands/auth.ts +1 -5
- package/src/platforms/whatsappbot/commands/message.test.ts +16 -16
- package/src/platforms/whatsappbot/commands/message.ts +1 -6
- package/src/platforms/whatsappbot/commands/template.test.ts +9 -9
- package/src/platforms/whatsappbot/commands/template.ts +1 -6
- package/src/platforms/whatsappbot/commands/whoami.test.ts +5 -5
- package/src/platforms/whatsappbot/commands/whoami.ts +1 -6
- package/src/platforms/whatsappbot/credential-manager.test.ts +18 -18
- package/src/platforms/whatsappbot/index.test.ts +7 -7
- package/src/platforms/whatsappbot/types.test.ts +18 -18
- package/src/shared/chromium/browsers.test.ts +102 -22
- package/src/shared/chromium/browsers.ts +72 -3
- package/src/shared/chromium/cli-options.test.ts +22 -0
- package/src/shared/chromium/cli-options.ts +12 -0
- package/src/shared/chromium/cookie-reader.test.ts +13 -13
- package/src/shared/chromium/decryptor.test.ts +97 -32
- package/src/shared/chromium/decryptor.ts +27 -6
- package/src/shared/chromium/index.ts +3 -0
- package/src/shared/utils/cli-output.test.ts +57 -0
- package/src/shared/utils/cli-output.ts +8 -0
- package/src/shared/utils/concurrency.test.ts +6 -6
- package/src/shared/utils/derived-key-cache.test.ts +11 -11
- package/src/tui/app.ts +129 -20
- 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-whatsappbot
|
|
3
3
|
description: Interact with WhatsApp using Cloud API credentials - send messages, manage templates
|
|
4
|
-
version: 2.
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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' })
|