myaiforone 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -0
- package/agents/_template/CLAUDE.md +18 -0
- package/agents/_template/agent.json +7 -0
- package/agents/platform/agentcreator/CLAUDE.md +300 -0
- package/agents/platform/appcreator/CLAUDE.md +158 -0
- package/agents/platform/gym/CLAUDE.md +486 -0
- package/agents/platform/gym/agent.json +40 -0
- package/agents/platform/gym/programs/agent-building/program.json +160 -0
- package/agents/platform/gym/programs/automations-mastery/program.json +129 -0
- package/agents/platform/gym/programs/getting-started/program.json +124 -0
- package/agents/platform/gym/programs/mcp-integrations/program.json +116 -0
- package/agents/platform/gym/programs/multi-model-strategy/program.json +115 -0
- package/agents/platform/gym/programs/prompt-engineering/program.json +136 -0
- package/agents/platform/gym/souls/alex.md +12 -0
- package/agents/platform/gym/souls/jordan.md +12 -0
- package/agents/platform/gym/souls/morgan.md +12 -0
- package/agents/platform/gym/souls/riley.md +12 -0
- package/agents/platform/gym/souls/sam.md +12 -0
- package/agents/platform/hub/CLAUDE.md +372 -0
- package/agents/platform/promptcreator/CLAUDE.md +130 -0
- package/agents/platform/skillcreator/CLAUDE.md +163 -0
- package/bin/cli.js +566 -0
- package/config.example.json +310 -0
- package/dist/agent-registry.d.ts +32 -0
- package/dist/agent-registry.d.ts.map +1 -0
- package/dist/agent-registry.js +144 -0
- package/dist/agent-registry.js.map +1 -0
- package/dist/channels/discord.d.ts +17 -0
- package/dist/channels/discord.d.ts.map +1 -0
- package/dist/channels/discord.js +114 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/imessage.d.ts +23 -0
- package/dist/channels/imessage.d.ts.map +1 -0
- package/dist/channels/imessage.js +214 -0
- package/dist/channels/imessage.js.map +1 -0
- package/dist/channels/slack.d.ts +19 -0
- package/dist/channels/slack.d.ts.map +1 -0
- package/dist/channels/slack.js +167 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/telegram.d.ts +19 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +274 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.d.ts +44 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +18 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/whatsapp.d.ts +23 -0
- package/dist/channels/whatsapp.d.ts.map +1 -0
- package/dist/channels/whatsapp.js +189 -0
- package/dist/channels/whatsapp.js.map +1 -0
- package/dist/config.d.ts +134 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/cron.d.ts +8 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +35 -0
- package/dist/cron.js.map +1 -0
- package/dist/decrypt-keys.d.ts +7 -0
- package/dist/decrypt-keys.d.ts.map +1 -0
- package/dist/decrypt-keys.js +53 -0
- package/dist/decrypt-keys.js.map +1 -0
- package/dist/encrypt-keys.d.ts +8 -0
- package/dist/encrypt-keys.d.ts.map +1 -0
- package/dist/encrypt-keys.js +62 -0
- package/dist/encrypt-keys.js.map +1 -0
- package/dist/executor.d.ts +31 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +2009 -0
- package/dist/executor.js.map +1 -0
- package/dist/gemini-executor.d.ts +27 -0
- package/dist/gemini-executor.d.ts.map +1 -0
- package/dist/gemini-executor.js +160 -0
- package/dist/gemini-executor.js.map +1 -0
- package/dist/goals.d.ts +24 -0
- package/dist/goals.d.ts.map +1 -0
- package/dist/goals.js +189 -0
- package/dist/goals.js.map +1 -0
- package/dist/gym/activity-digest.d.ts +30 -0
- package/dist/gym/activity-digest.d.ts.map +1 -0
- package/dist/gym/activity-digest.js +506 -0
- package/dist/gym/activity-digest.js.map +1 -0
- package/dist/gym/dimension-scorer.d.ts +76 -0
- package/dist/gym/dimension-scorer.d.ts.map +1 -0
- package/dist/gym/dimension-scorer.js +236 -0
- package/dist/gym/dimension-scorer.js.map +1 -0
- package/dist/gym/gym-router.d.ts +7 -0
- package/dist/gym/gym-router.d.ts.map +1 -0
- package/dist/gym/gym-router.js +718 -0
- package/dist/gym/gym-router.js.map +1 -0
- package/dist/gym/index.d.ts +11 -0
- package/dist/gym/index.d.ts.map +1 -0
- package/dist/gym/index.js +11 -0
- package/dist/gym/index.js.map +1 -0
- package/dist/heartbeat.d.ts +21 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +163 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +254 -0
- package/dist/index.js.map +1 -0
- package/dist/keystore.d.ts +22 -0
- package/dist/keystore.d.ts.map +1 -0
- package/dist/keystore.js +178 -0
- package/dist/keystore.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +45 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory/daily.d.ts +22 -0
- package/dist/memory/daily.d.ts.map +1 -0
- package/dist/memory/daily.js +82 -0
- package/dist/memory/daily.js.map +1 -0
- package/dist/memory/embeddings.d.ts +15 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +154 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/index.d.ts +32 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +159 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/search.d.ts +21 -0
- package/dist/memory/search.d.ts.map +1 -0
- package/dist/memory/search.js +77 -0
- package/dist/memory/search.js.map +1 -0
- package/dist/memory/store.d.ts +23 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +144 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/ollama-executor.d.ts +17 -0
- package/dist/ollama-executor.d.ts.map +1 -0
- package/dist/ollama-executor.js +112 -0
- package/dist/ollama-executor.js.map +1 -0
- package/dist/openai-executor.d.ts +38 -0
- package/dist/openai-executor.d.ts.map +1 -0
- package/dist/openai-executor.js +197 -0
- package/dist/openai-executor.js.map +1 -0
- package/dist/router.d.ts +11 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +185 -0
- package/dist/router.js.map +1 -0
- package/dist/test-message.d.ts +2 -0
- package/dist/test-message.d.ts.map +1 -0
- package/dist/test-message.js +60 -0
- package/dist/test-message.js.map +1 -0
- package/dist/utils/imsg-db-reader.d.ts +24 -0
- package/dist/utils/imsg-db-reader.d.ts.map +1 -0
- package/dist/utils/imsg-db-reader.js +92 -0
- package/dist/utils/imsg-db-reader.js.map +1 -0
- package/dist/utils/imsg-rpc.d.ts +25 -0
- package/dist/utils/imsg-rpc.d.ts.map +1 -0
- package/dist/utils/imsg-rpc.js +149 -0
- package/dist/utils/imsg-rpc.js.map +1 -0
- package/dist/utils/message-formatter.d.ts +3 -0
- package/dist/utils/message-formatter.d.ts.map +1 -0
- package/dist/utils/message-formatter.js +69 -0
- package/dist/utils/message-formatter.js.map +1 -0
- package/dist/web-ui.d.ts +12 -0
- package/dist/web-ui.d.ts.map +1 -0
- package/dist/web-ui.js +5784 -0
- package/dist/web-ui.js.map +1 -0
- package/dist/whatsapp-chats.d.ts +2 -0
- package/dist/whatsapp-chats.d.ts.map +1 -0
- package/dist/whatsapp-chats.js +76 -0
- package/dist/whatsapp-chats.js.map +1 -0
- package/dist/whatsapp-login.d.ts +2 -0
- package/dist/whatsapp-login.d.ts.map +1 -0
- package/dist/whatsapp-login.js +90 -0
- package/dist/whatsapp-login.js.map +1 -0
- package/dist/wiki-sync.d.ts +21 -0
- package/dist/wiki-sync.d.ts.map +1 -0
- package/dist/wiki-sync.js +147 -0
- package/dist/wiki-sync.js.map +1 -0
- package/docs/AddNewAgentGuide.md +100 -0
- package/docs/AddNewMcpGuide.md +72 -0
- package/docs/Architecture.md +795 -0
- package/docs/CLAUDE-AI-SETUP.md +166 -0
- package/docs/Setup.md +297 -0
- package/docs/ai-gym-architecture.md +1040 -0
- package/docs/ai-gym-build-plan.md +343 -0
- package/docs/ai-gym-onboarding.md +122 -0
- package/docs/appcreator_plan.md +348 -0
- package/docs/platform-mcp-audit.md +320 -0
- package/docs/server-deployment-plan.md +503 -0
- package/docs/superpowers/plans/2026-03-25-marketplace.md +1281 -0
- package/docs/superpowers/specs/2026-03-25-marketplace-design.md +287 -0
- package/docs/user-guide.md +2016 -0
- package/mcp-catalog.json +628 -0
- package/package.json +63 -0
- package/public/MyAIforOne-logomark-512.svg +16 -0
- package/public/MyAIforOne-logomark-transparent.svg +15 -0
- package/public/activity.html +314 -0
- package/public/admin.html +1674 -0
- package/public/agent-dashboard.html +670 -0
- package/public/api-docs.html +1106 -0
- package/public/automations.html +722 -0
- package/public/canvas.css +223 -0
- package/public/canvas.js +588 -0
- package/public/changelog.html +231 -0
- package/public/gym.html +2766 -0
- package/public/home.html +1930 -0
- package/public/index.html +2809 -0
- package/public/lab.html +1643 -0
- package/public/library.html +1442 -0
- package/public/marketplace.html +1101 -0
- package/public/mcp-docs.html +441 -0
- package/public/mini.html +390 -0
- package/public/monitor.html +584 -0
- package/public/org.html +4304 -0
- package/public/projects.html +734 -0
- package/public/settings.html +645 -0
- package/public/tasks.html +932 -0
- package/public/trainers/alex.svg +12 -0
- package/public/trainers/jordan.svg +12 -0
- package/public/trainers/morgan.svg +12 -0
- package/public/trainers/riley.svg +12 -0
- package/public/trainers/sam.svg +12 -0
- package/public/user-guide.html +218 -0
- package/registry/agents.json +3 -0
- package/registry/apps.json +20 -0
- package/registry/installed-drafts.json +3 -0
- package/registry/mcps.json +1084 -0
- package/registry/prompts/personal/mcp-test-prompt.md +6 -0
- package/registry/prompts/personal/memory-recall.md +6 -0
- package/registry/prompts/platform/brainstorm.md +15 -0
- package/registry/prompts/platform/code-review.md +16 -0
- package/registry/prompts/platform/explain.md +16 -0
- package/registry/prompts.json +58 -0
- package/registry/skills/external/brainstorming.md +5 -0
- package/registry/skills/external/code-review.md +40 -0
- package/registry/skills/external/frontend-patterns.md +642 -0
- package/registry/skills/external/frontend-slides.md +184 -0
- package/registry/skills/external/systematic-debugging.md +5 -0
- package/registry/skills/external/tdd.md +328 -0
- package/registry/skills/external/verification-before-completion.md +5 -0
- package/registry/skills/external/writing-plans.md +5 -0
- package/registry/skills/platform/ai41_app_build.md +930 -0
- package/registry/skills/platform/ai41_app_deploy.md +168 -0
- package/registry/skills/platform/ai41_app_orchestrator.md +239 -0
- package/registry/skills/platform/ai41_app_patterns.md +359 -0
- package/registry/skills/platform/ai41_app_register.md +85 -0
- package/registry/skills/platform/ai41_app_scaffold.md +421 -0
- package/registry/skills/platform/ai41_app_verify.md +107 -0
- package/registry/skills/platform/opProjectCreate.md +239 -0
- package/registry/skills/platform/op_devbrowser.md +136 -0
- package/registry/skills/platform/sop_brandguidelines.md +103 -0
- package/registry/skills/platform/sop_docx.md +117 -0
- package/registry/skills/platform/sop_frontenddesign.md +44 -0
- package/registry/skills/platform/sop_frontenddesign_v2.md +659 -0
- package/registry/skills/platform/sop_mcpbuilder.md +133 -0
- package/registry/skills/platform/sop_pdf.md +172 -0
- package/registry/skills/platform/sop_pptx.md +133 -0
- package/registry/skills/platform/sop_skillcreator.md +104 -0
- package/registry/skills/platform/sop_themefactory.md +128 -0
- package/registry/skills/platform/sop_webapptesting.md +75 -0
- package/registry/skills/platform/sop_webartifactsbuilder.md +97 -0
- package/registry/skills/platform/sop_xlsx.md +134 -0
- package/registry/skills.json +1055 -0
- package/scripts/discover-chats.sh +11 -0
- package/scripts/install-service-windows.ps1 +87 -0
- package/scripts/install-service.sh +52 -0
- package/scripts/seed-registry.ts +195 -0
- package/scripts/test-send.sh +5 -0
- package/scripts/tray-indicator.ps1 +35 -0
- package/scripts/uninstall-service-windows.ps1 +23 -0
- package/scripts/uninstall-service.sh +15 -0
- package/scripts/xbar-myagent.5s.sh +32 -0
- package/server/mcp-server/dist/index.d.ts +11 -0
- package/server/mcp-server/dist/index.js +1332 -0
- package/server/mcp-server/dist/lib/api-client.d.ts +165 -0
- package/server/mcp-server/dist/lib/api-client.js +241 -0
- package/server/mcp-server/index.ts +1545 -0
- package/server/mcp-server/lib/api-client.ts +366 -0
- package/server/mcp-server/tsconfig.json +14 -0
- package/src/agent-registry.ts +180 -0
- package/src/channels/discord.ts +129 -0
- package/src/channels/imessage.ts +261 -0
- package/src/channels/slack.ts +208 -0
- package/src/channels/telegram.ts +307 -0
- package/src/channels/types.ts +62 -0
- package/src/channels/whatsapp.ts +227 -0
- package/src/config.ts +281 -0
- package/src/cron.ts +43 -0
- package/src/decrypt-keys.ts +60 -0
- package/src/encrypt-keys.ts +70 -0
- package/src/executor.ts +2190 -0
- package/src/gemini-executor.ts +212 -0
- package/src/goals.ts +240 -0
- package/src/gym/activity-digest.ts +546 -0
- package/src/gym/dimension-scorer.ts +297 -0
- package/src/gym/gym-router.ts +801 -0
- package/src/gym/index.ts +19 -0
- package/src/heartbeat.ts +220 -0
- package/src/index.ts +275 -0
- package/src/keystore.ts +190 -0
- package/src/logger.ts +51 -0
- package/src/memory/daily.ts +101 -0
- package/src/memory/embeddings.ts +185 -0
- package/src/memory/index.ts +218 -0
- package/src/memory/search.ts +124 -0
- package/src/memory/store.ts +189 -0
- package/src/ollama-executor.ts +126 -0
- package/src/openai-executor.ts +259 -0
- package/src/router.ts +230 -0
- package/src/test-message.ts +72 -0
- package/src/utils/imsg-db-reader.ts +109 -0
- package/src/utils/imsg-rpc.ts +178 -0
- package/src/utils/message-formatter.ts +90 -0
- package/src/web-ui.ts +5778 -0
- package/src/whatsapp-chats.ts +91 -0
- package/src/whatsapp-login.ts +110 -0
- package/src/wiki-sync.ts +199 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { writeFileSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { Bot } from "grammy";
|
|
5
|
+
import { splitText } from "./types.js";
|
|
6
|
+
import { log } from "../logger.js";
|
|
7
|
+
import { InputFile } from "grammy";
|
|
8
|
+
export class TelegramDriver {
|
|
9
|
+
channelId = "telegram";
|
|
10
|
+
bot;
|
|
11
|
+
botToken;
|
|
12
|
+
messageHandler = null;
|
|
13
|
+
botId = null;
|
|
14
|
+
constructor(config) {
|
|
15
|
+
const botToken = config.botToken;
|
|
16
|
+
if (!botToken) {
|
|
17
|
+
throw new Error("Telegram driver requires botToken in config");
|
|
18
|
+
}
|
|
19
|
+
this.botToken = botToken;
|
|
20
|
+
this.bot = new Bot(botToken);
|
|
21
|
+
}
|
|
22
|
+
async start() {
|
|
23
|
+
const me = await this.bot.api.getMe();
|
|
24
|
+
this.botId = me.id;
|
|
25
|
+
log.info(`Telegram bot authenticated as @${me.username} (${me.id})`);
|
|
26
|
+
this.bot.on("message:text", (ctx) => this.handleMessage(ctx));
|
|
27
|
+
this.bot.on("message:photo", (ctx) => this.handleMessage(ctx));
|
|
28
|
+
this.bot.on("message:voice", (ctx) => this.handleVoiceMessage(ctx));
|
|
29
|
+
this.bot.on("message:audio", (ctx) => this.handleVoiceMessage(ctx));
|
|
30
|
+
this.bot.catch((err) => {
|
|
31
|
+
log.error(`Telegram bot error: ${err.message}`);
|
|
32
|
+
});
|
|
33
|
+
this.bot.start({
|
|
34
|
+
onStart: () => {
|
|
35
|
+
log.info("Telegram driver started — listening for messages (long polling)");
|
|
36
|
+
},
|
|
37
|
+
}).catch((err) => {
|
|
38
|
+
// 409 Conflict means another instance is already polling — log and swallow.
|
|
39
|
+
// Any other error is also caught here to prevent crashing the Node process.
|
|
40
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
41
|
+
if (msg.includes("409")) {
|
|
42
|
+
log.warn(`Telegram polling conflict (409): another instance may be running. Telegram disabled.`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
log.error(`Telegram bot.start() error: ${msg}`);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async stop() {
|
|
50
|
+
await this.bot.stop();
|
|
51
|
+
log.info("Telegram driver stopped");
|
|
52
|
+
}
|
|
53
|
+
onMessage(handler) {
|
|
54
|
+
this.messageHandler = handler;
|
|
55
|
+
}
|
|
56
|
+
async send(msg) {
|
|
57
|
+
const chatId = parseInt(msg.chatId, 10);
|
|
58
|
+
const chunks = splitText(msg.text, 4096);
|
|
59
|
+
for (const chunk of chunks) {
|
|
60
|
+
await this.bot.api.sendMessage(chatId, chunk, {
|
|
61
|
+
...(msg.replyToId ? { reply_parameters: { message_id: parseInt(msg.replyToId, 10) } } : {}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
async sendTyping(chatId) {
|
|
66
|
+
try {
|
|
67
|
+
await this.bot.api.sendChatAction(parseInt(chatId, 10), "typing");
|
|
68
|
+
}
|
|
69
|
+
catch { /* ignore */ }
|
|
70
|
+
}
|
|
71
|
+
async sendFile(chatId, filePath, caption) {
|
|
72
|
+
try {
|
|
73
|
+
const numericId = parseInt(chatId, 10);
|
|
74
|
+
const ext = filePath.split(".").pop()?.toLowerCase() || "";
|
|
75
|
+
const imageExts = ["png", "jpg", "jpeg", "gif", "webp"];
|
|
76
|
+
if (imageExts.includes(ext)) {
|
|
77
|
+
await this.bot.api.sendPhoto(numericId, new InputFile(filePath), {
|
|
78
|
+
caption: caption || undefined,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
await this.bot.api.sendDocument(numericId, new InputFile(filePath), {
|
|
83
|
+
caption: caption || undefined,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
log.warn(`Failed to send file to Telegram: ${err}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async handleMessage(ctx) {
|
|
92
|
+
const msg = ctx.message;
|
|
93
|
+
if (!msg)
|
|
94
|
+
return;
|
|
95
|
+
if (msg.from?.id === this.botId)
|
|
96
|
+
return;
|
|
97
|
+
if (msg.from?.is_bot)
|
|
98
|
+
return;
|
|
99
|
+
const chatId = msg.chat.id.toString();
|
|
100
|
+
const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
|
|
101
|
+
const sender = msg.from?.id.toString() || "unknown";
|
|
102
|
+
const senderName = buildSenderName(msg.from);
|
|
103
|
+
const text = msg.text || msg.caption || "";
|
|
104
|
+
const attachments = await this.downloadPhotos(msg);
|
|
105
|
+
if (!text.trim() && attachments.length === 0)
|
|
106
|
+
return;
|
|
107
|
+
let replyTo;
|
|
108
|
+
if (msg.reply_to_message) {
|
|
109
|
+
replyTo = {
|
|
110
|
+
id: msg.reply_to_message.message_id.toString(),
|
|
111
|
+
text: msg.reply_to_message.text || msg.reply_to_message.caption || "",
|
|
112
|
+
sender: msg.reply_to_message.from?.id.toString(),
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const inbound = {
|
|
116
|
+
id: msg.message_id.toString(),
|
|
117
|
+
channel: this.channelId,
|
|
118
|
+
chatId,
|
|
119
|
+
chatType: isGroup ? "group" : "dm",
|
|
120
|
+
sender,
|
|
121
|
+
senderName,
|
|
122
|
+
text,
|
|
123
|
+
timestamp: msg.date * 1000,
|
|
124
|
+
isFromMe: false,
|
|
125
|
+
isGroup,
|
|
126
|
+
groupName: isGroup ? msg.chat.title : undefined,
|
|
127
|
+
replyTo,
|
|
128
|
+
attachments: attachments.length > 0 ? attachments : undefined,
|
|
129
|
+
raw: msg,
|
|
130
|
+
};
|
|
131
|
+
log.debug(`Telegram received from ${senderName} (${sender}) in ${chatId}: ${text.slice(0, 100)}${attachments.length ? ` [${attachments.length} photo(s)]` : ""}`);
|
|
132
|
+
if (this.messageHandler) {
|
|
133
|
+
this.messageHandler(inbound).catch((err) => {
|
|
134
|
+
log.error(`Telegram message handler error: ${err}`);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Feature 8: Voice note handling — download audio, transcribe if configured
|
|
139
|
+
async handleVoiceMessage(ctx) {
|
|
140
|
+
const msg = ctx.message;
|
|
141
|
+
if (!msg)
|
|
142
|
+
return;
|
|
143
|
+
if (msg.from?.id === this.botId)
|
|
144
|
+
return;
|
|
145
|
+
if (msg.from?.is_bot)
|
|
146
|
+
return;
|
|
147
|
+
const voice = msg.voice || msg.audio;
|
|
148
|
+
if (!voice)
|
|
149
|
+
return;
|
|
150
|
+
const chatId = msg.chat.id.toString();
|
|
151
|
+
const isGroup = msg.chat.type === "group" || msg.chat.type === "supergroup";
|
|
152
|
+
const sender = msg.from?.id.toString() || "unknown";
|
|
153
|
+
const senderName = buildSenderName(msg.from);
|
|
154
|
+
try {
|
|
155
|
+
const file = await this.bot.api.getFile(voice.file_id);
|
|
156
|
+
if (!file.file_path)
|
|
157
|
+
return;
|
|
158
|
+
const url = `https://api.telegram.org/file/bot${this.botToken}/${file.file_path}`;
|
|
159
|
+
const resp = await fetch(url);
|
|
160
|
+
if (!resp.ok)
|
|
161
|
+
return;
|
|
162
|
+
const buffer = Buffer.from(await resp.arrayBuffer());
|
|
163
|
+
const ext = file.file_path.split(".").pop() || "ogg";
|
|
164
|
+
const downloadDir = join(tmpdir(), "channelToAgent-telegram-voice");
|
|
165
|
+
mkdirSync(downloadDir, { recursive: true });
|
|
166
|
+
const localPath = join(downloadDir, `${msg.message_id}.${ext}`);
|
|
167
|
+
writeFileSync(localPath, buffer);
|
|
168
|
+
// Transcribe via OpenAI Whisper API if key is available
|
|
169
|
+
const transcription = await transcribeAudio(localPath);
|
|
170
|
+
if (!transcription) {
|
|
171
|
+
log.debug(`Voice message from ${senderName} — no transcription (no OPENAI_API_KEY)`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
log.debug(`Transcribed voice from ${senderName}: ${transcription.slice(0, 100)}`);
|
|
175
|
+
const inbound = {
|
|
176
|
+
id: msg.message_id.toString(),
|
|
177
|
+
channel: this.channelId,
|
|
178
|
+
chatId,
|
|
179
|
+
chatType: isGroup ? "group" : "dm",
|
|
180
|
+
sender,
|
|
181
|
+
senderName,
|
|
182
|
+
text: `[Voice message transcription]: ${transcription}`,
|
|
183
|
+
timestamp: msg.date * 1000,
|
|
184
|
+
isFromMe: false,
|
|
185
|
+
isGroup,
|
|
186
|
+
groupName: isGroup ? msg.chat.title : undefined,
|
|
187
|
+
raw: msg,
|
|
188
|
+
};
|
|
189
|
+
if (this.messageHandler) {
|
|
190
|
+
this.messageHandler(inbound).catch((err) => {
|
|
191
|
+
log.error(`Telegram voice handler error: ${err}`);
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
log.warn(`Error handling voice message: ${err}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async downloadPhotos(msg) {
|
|
200
|
+
if (!msg.photo?.length)
|
|
201
|
+
return [];
|
|
202
|
+
const downloadDir = join(tmpdir(), "channelToAgent-telegram-images");
|
|
203
|
+
mkdirSync(downloadDir, { recursive: true });
|
|
204
|
+
const results = [];
|
|
205
|
+
const largest = msg.photo.reduce((a, b) => (a.file_size || 0) > (b.file_size || 0) ? a : b);
|
|
206
|
+
try {
|
|
207
|
+
const file = await this.bot.api.getFile(largest.file_id);
|
|
208
|
+
if (!file.file_path) {
|
|
209
|
+
log.warn(`No file_path for Telegram photo ${largest.file_id}`);
|
|
210
|
+
return results;
|
|
211
|
+
}
|
|
212
|
+
const url = `https://api.telegram.org/file/bot${this.botToken}/${file.file_path}`;
|
|
213
|
+
const resp = await fetch(url);
|
|
214
|
+
if (!resp.ok) {
|
|
215
|
+
log.warn(`Failed to download Telegram photo: ${resp.status}`);
|
|
216
|
+
return results;
|
|
217
|
+
}
|
|
218
|
+
const buffer = Buffer.from(await resp.arrayBuffer());
|
|
219
|
+
if (buffer.length > 10_000_000) {
|
|
220
|
+
log.warn(`Skipping oversized Telegram photo (${buffer.length} bytes)`);
|
|
221
|
+
return results;
|
|
222
|
+
}
|
|
223
|
+
const ext = file.file_path.split(".").pop() || "jpg";
|
|
224
|
+
const localPath = join(downloadDir, `${msg.message_id}-${largest.file_id}.${ext}`);
|
|
225
|
+
writeFileSync(localPath, buffer);
|
|
226
|
+
results.push({ path: localPath, mimeType: `image/${ext === "jpg" ? "jpeg" : ext}` });
|
|
227
|
+
log.debug(`Downloaded Telegram photo: ${localPath} (${buffer.length} bytes)`);
|
|
228
|
+
}
|
|
229
|
+
catch (err) {
|
|
230
|
+
log.warn(`Error downloading Telegram photo: ${err}`);
|
|
231
|
+
}
|
|
232
|
+
return results;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
// ─── Helpers ─────────────────────────────────────────────────────────
|
|
236
|
+
function buildSenderName(from) {
|
|
237
|
+
if (!from)
|
|
238
|
+
return "unknown";
|
|
239
|
+
const parts = [from.first_name, from.last_name].filter(Boolean);
|
|
240
|
+
if (parts.length > 0)
|
|
241
|
+
return parts.join(" ");
|
|
242
|
+
return from.username || "unknown";
|
|
243
|
+
}
|
|
244
|
+
// Feature 8: Voice transcription via OpenAI Whisper API
|
|
245
|
+
async function transcribeAudio(filePath) {
|
|
246
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
247
|
+
if (!apiKey)
|
|
248
|
+
return null;
|
|
249
|
+
try {
|
|
250
|
+
const { readFileSync } = await import("node:fs");
|
|
251
|
+
const { basename } = await import("node:path");
|
|
252
|
+
const audioData = readFileSync(filePath);
|
|
253
|
+
const fileName = basename(filePath);
|
|
254
|
+
const formData = new FormData();
|
|
255
|
+
formData.append("file", new Blob([audioData]), fileName);
|
|
256
|
+
formData.append("model", "whisper-1");
|
|
257
|
+
const resp = await fetch("https://api.openai.com/v1/audio/transcriptions", {
|
|
258
|
+
method: "POST",
|
|
259
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
260
|
+
body: formData,
|
|
261
|
+
});
|
|
262
|
+
if (!resp.ok) {
|
|
263
|
+
log.warn(`Whisper API error: ${resp.status}`);
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
const result = await resp.json();
|
|
267
|
+
return result.text;
|
|
268
|
+
}
|
|
269
|
+
catch (err) {
|
|
270
|
+
log.warn(`Transcription failed: ${err}`);
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/channels/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface InboundMessage {
|
|
2
|
+
id: string;
|
|
3
|
+
channel: string;
|
|
4
|
+
chatId: string;
|
|
5
|
+
chatType: "dm" | "group";
|
|
6
|
+
sender: string;
|
|
7
|
+
senderName?: string;
|
|
8
|
+
text: string;
|
|
9
|
+
timestamp: number;
|
|
10
|
+
isFromMe: boolean;
|
|
11
|
+
isGroup: boolean;
|
|
12
|
+
groupName?: string;
|
|
13
|
+
participants?: string[];
|
|
14
|
+
replyTo?: {
|
|
15
|
+
id: string;
|
|
16
|
+
text: string;
|
|
17
|
+
sender?: string;
|
|
18
|
+
};
|
|
19
|
+
attachments?: Array<{
|
|
20
|
+
path: string;
|
|
21
|
+
mimeType?: string;
|
|
22
|
+
}>;
|
|
23
|
+
raw: unknown;
|
|
24
|
+
}
|
|
25
|
+
export interface OutboundMessage {
|
|
26
|
+
text: string;
|
|
27
|
+
chatId: string;
|
|
28
|
+
replyToId?: string;
|
|
29
|
+
attachments?: Array<{
|
|
30
|
+
path: string;
|
|
31
|
+
mimeType?: string;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export interface ChannelDriver {
|
|
35
|
+
readonly channelId: string;
|
|
36
|
+
start(): Promise<void>;
|
|
37
|
+
stop(): Promise<void>;
|
|
38
|
+
onMessage(handler: (msg: InboundMessage) => Promise<void>): void;
|
|
39
|
+
send(msg: OutboundMessage): Promise<void>;
|
|
40
|
+
sendTyping?(chatId: string): Promise<void>;
|
|
41
|
+
sendFile?(chatId: string, filePath: string, caption?: string): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
export declare function splitText(text: string, maxLen: number): string[];
|
|
44
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/channels/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,IAAI,GAAG,OAAO,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,OAAO,CAAC,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IACH,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,KAAK,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjE,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,UAAU,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,QAAQ,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9E;AAID,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAchE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// ─── Shared utilities ────────────────────────────────────────────────
|
|
2
|
+
export function splitText(text, maxLen) {
|
|
3
|
+
const chunks = [];
|
|
4
|
+
let remaining = text;
|
|
5
|
+
while (remaining.length > 0) {
|
|
6
|
+
if (remaining.length <= maxLen) {
|
|
7
|
+
chunks.push(remaining);
|
|
8
|
+
break;
|
|
9
|
+
}
|
|
10
|
+
let splitAt = remaining.lastIndexOf("\n", maxLen);
|
|
11
|
+
if (splitAt < maxLen * 0.5)
|
|
12
|
+
splitAt = maxLen;
|
|
13
|
+
chunks.push(remaining.slice(0, splitAt));
|
|
14
|
+
remaining = remaining.slice(splitAt);
|
|
15
|
+
}
|
|
16
|
+
return chunks;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/channels/types.ts"],"names":[],"mappings":"AA6CA,wEAAwE;AAExE,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,MAAc;IACpD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,IAAI,SAAS,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACvB,MAAM;QACR,CAAC;QACD,IAAI,OAAO,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAClD,IAAI,OAAO,GAAG,MAAM,GAAG,GAAG;YAAE,OAAO,GAAG,MAAM,CAAC;QAC7C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QACzC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ChannelDriver, InboundMessage, OutboundMessage } from "./types.js";
|
|
2
|
+
export declare class WhatsAppDriver implements ChannelDriver {
|
|
3
|
+
readonly channelId = "whatsapp";
|
|
4
|
+
private sock;
|
|
5
|
+
private messageHandler;
|
|
6
|
+
private authDir;
|
|
7
|
+
private selfId;
|
|
8
|
+
private retryCount;
|
|
9
|
+
private maxRetries;
|
|
10
|
+
private stopping;
|
|
11
|
+
/** Track message IDs sent by this socket so we don't echo agent replies */
|
|
12
|
+
private sentIds;
|
|
13
|
+
constructor(config: Record<string, unknown>);
|
|
14
|
+
start(): Promise<void>;
|
|
15
|
+
stop(): Promise<void>;
|
|
16
|
+
onMessage(handler: (msg: InboundMessage) => Promise<void>): void;
|
|
17
|
+
send(msg: OutboundMessage): Promise<void>;
|
|
18
|
+
private connect;
|
|
19
|
+
private handleConnectionUpdate;
|
|
20
|
+
private reconnect;
|
|
21
|
+
private handleMessagesUpsert;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=whatsapp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../src/channels/whatsapp.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAejF,qBAAa,cAAe,YAAW,aAAa;IAClD,QAAQ,CAAC,SAAS,cAAc;IAEhC,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,cAAc,CAAyD;IAC/E,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,QAAQ,CAAS;IACzB,2EAA2E;IAC3E,OAAO,CAAC,OAAO,CAAqB;gBAExB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAMrC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI1D,IAAI,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;YAMjC,OAAO;IA+BrB,OAAO,CAAC,sBAAsB;YA4ChB,SAAS;IAWvB,OAAO,CAAC,oBAAoB;CAoE7B"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { makeWASocket, useMultiFileAuthState, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, DisconnectReason, } from "@whiskeysockets/baileys";
|
|
2
|
+
import { mkdirSync } from "node:fs";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { log } from "../logger.js";
|
|
5
|
+
// Baileys is noisy — suppress its internal logger
|
|
6
|
+
const silentLogger = {
|
|
7
|
+
level: "silent",
|
|
8
|
+
child: () => silentLogger,
|
|
9
|
+
trace: () => { },
|
|
10
|
+
debug: () => { },
|
|
11
|
+
info: () => { },
|
|
12
|
+
warn: () => { },
|
|
13
|
+
error: () => { },
|
|
14
|
+
fatal: () => { },
|
|
15
|
+
};
|
|
16
|
+
export class WhatsAppDriver {
|
|
17
|
+
channelId = "whatsapp";
|
|
18
|
+
sock = null;
|
|
19
|
+
messageHandler = null;
|
|
20
|
+
authDir;
|
|
21
|
+
selfId = null;
|
|
22
|
+
retryCount = 0;
|
|
23
|
+
maxRetries = 5;
|
|
24
|
+
stopping = false;
|
|
25
|
+
/** Track message IDs sent by this socket so we don't echo agent replies */
|
|
26
|
+
sentIds = new Set();
|
|
27
|
+
constructor(config) {
|
|
28
|
+
const baseAuthDir = config.authDir ?? "./data/whatsapp-auth";
|
|
29
|
+
this.authDir = resolve(baseAuthDir);
|
|
30
|
+
mkdirSync(this.authDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
async start() {
|
|
33
|
+
this.stopping = false;
|
|
34
|
+
await this.connect();
|
|
35
|
+
}
|
|
36
|
+
async stop() {
|
|
37
|
+
this.stopping = true;
|
|
38
|
+
if (this.sock) {
|
|
39
|
+
this.sock.ev.removeAllListeners("messages.upsert");
|
|
40
|
+
this.sock.ev.removeAllListeners("connection.update");
|
|
41
|
+
this.sock.end(undefined);
|
|
42
|
+
this.sock = null;
|
|
43
|
+
}
|
|
44
|
+
log.info("WhatsApp driver stopped");
|
|
45
|
+
}
|
|
46
|
+
onMessage(handler) {
|
|
47
|
+
this.messageHandler = handler;
|
|
48
|
+
}
|
|
49
|
+
async send(msg) {
|
|
50
|
+
if (!this.sock)
|
|
51
|
+
throw new Error("WhatsApp not connected");
|
|
52
|
+
const sent = await this.sock.sendMessage(msg.chatId, { text: msg.text });
|
|
53
|
+
if (sent?.key?.id)
|
|
54
|
+
this.sentIds.add(sent.key.id);
|
|
55
|
+
}
|
|
56
|
+
async connect() {
|
|
57
|
+
const { state, saveCreds } = await useMultiFileAuthState(this.authDir);
|
|
58
|
+
const { version } = await fetchLatestBaileysVersion();
|
|
59
|
+
this.sock = makeWASocket({
|
|
60
|
+
auth: {
|
|
61
|
+
creds: state.creds,
|
|
62
|
+
keys: makeCacheableSignalKeyStore(state.keys, silentLogger),
|
|
63
|
+
},
|
|
64
|
+
version,
|
|
65
|
+
logger: silentLogger,
|
|
66
|
+
printQRInTerminal: false,
|
|
67
|
+
browser: ["channelToAgentToClaude", "Desktop", "1.0.0"],
|
|
68
|
+
syncFullHistory: false,
|
|
69
|
+
markOnlineOnConnect: false,
|
|
70
|
+
});
|
|
71
|
+
// Save credentials on update
|
|
72
|
+
this.sock.ev.on("creds.update", saveCreds);
|
|
73
|
+
// Handle connection state changes
|
|
74
|
+
this.sock.ev.on("connection.update", (update) => {
|
|
75
|
+
this.handleConnectionUpdate(update, saveCreds);
|
|
76
|
+
});
|
|
77
|
+
// Handle incoming messages
|
|
78
|
+
this.sock.ev.on("messages.upsert", (upsert) => {
|
|
79
|
+
this.handleMessagesUpsert(upsert);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
handleConnectionUpdate(update, saveCreds) {
|
|
83
|
+
const { connection, lastDisconnect, qr } = update;
|
|
84
|
+
if (qr) {
|
|
85
|
+
// Display QR code — this should only happen during initial login
|
|
86
|
+
log.warn("WhatsApp QR code generated — run the login script first: npm run whatsapp-login");
|
|
87
|
+
log.warn("QR code cannot be displayed from the background service");
|
|
88
|
+
}
|
|
89
|
+
if (connection === "open") {
|
|
90
|
+
this.selfId = this.sock?.user?.id ?? null;
|
|
91
|
+
this.retryCount = 0;
|
|
92
|
+
log.info(`WhatsApp connected as ${this.sock?.user?.name ?? this.selfId}`);
|
|
93
|
+
}
|
|
94
|
+
if (connection === "close") {
|
|
95
|
+
const reason = lastDisconnect?.error?.output?.statusCode;
|
|
96
|
+
if (reason === DisconnectReason.loggedOut) {
|
|
97
|
+
log.error("WhatsApp logged out — credentials cleared. Run: npm run whatsapp-login");
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
if (reason === 515) {
|
|
101
|
+
// Restart requested by WhatsApp
|
|
102
|
+
log.info("WhatsApp requested restart, reconnecting...");
|
|
103
|
+
this.reconnect();
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (!this.stopping && this.retryCount < this.maxRetries) {
|
|
107
|
+
this.retryCount++;
|
|
108
|
+
const delay = Math.min(5000 * Math.pow(2, this.retryCount - 1), 300_000);
|
|
109
|
+
log.warn(`WhatsApp disconnected (reason: ${reason}), reconnecting in ${delay}ms (attempt ${this.retryCount}/${this.maxRetries})`);
|
|
110
|
+
setTimeout(() => this.reconnect(), delay);
|
|
111
|
+
}
|
|
112
|
+
else if (!this.stopping) {
|
|
113
|
+
log.error(`WhatsApp disconnected after ${this.maxRetries} retries, giving up`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async reconnect() {
|
|
118
|
+
if (this.sock) {
|
|
119
|
+
this.sock.ev.removeAllListeners("messages.upsert");
|
|
120
|
+
this.sock.ev.removeAllListeners("connection.update");
|
|
121
|
+
this.sock.ev.removeAllListeners("creds.update");
|
|
122
|
+
this.sock.end(undefined);
|
|
123
|
+
this.sock = null;
|
|
124
|
+
}
|
|
125
|
+
await this.connect();
|
|
126
|
+
}
|
|
127
|
+
handleMessagesUpsert(upsert) {
|
|
128
|
+
if (upsert.type !== "notify")
|
|
129
|
+
return;
|
|
130
|
+
for (const msg of upsert.messages) {
|
|
131
|
+
// Skip status broadcasts
|
|
132
|
+
if (msg.key.remoteJid === "status@broadcast")
|
|
133
|
+
continue;
|
|
134
|
+
// Skip messages sent by this socket (agent replies) to avoid echo loops.
|
|
135
|
+
// But do NOT skip all fromMe — the user's phone shares the same WhatsApp
|
|
136
|
+
// account as this linked device, so user messages also appear as fromMe.
|
|
137
|
+
const msgId = msg.key.id || "";
|
|
138
|
+
if (this.sentIds.has(msgId)) {
|
|
139
|
+
this.sentIds.delete(msgId);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
// Extract text from various message types
|
|
143
|
+
const text = msg.message?.conversation ||
|
|
144
|
+
msg.message?.extendedTextMessage?.text ||
|
|
145
|
+
msg.message?.imageMessage?.caption ||
|
|
146
|
+
msg.message?.videoMessage?.caption ||
|
|
147
|
+
null;
|
|
148
|
+
if (!text?.trim())
|
|
149
|
+
continue;
|
|
150
|
+
const remoteJid = msg.key.remoteJid;
|
|
151
|
+
const isGroup = remoteJid.endsWith("@g.us");
|
|
152
|
+
const sender = isGroup
|
|
153
|
+
? msg.key.participant || remoteJid
|
|
154
|
+
: remoteJid;
|
|
155
|
+
// Extract reply context
|
|
156
|
+
const quotedMsg = msg.message?.extendedTextMessage?.contextInfo;
|
|
157
|
+
const replyTo = quotedMsg?.quotedMessage
|
|
158
|
+
? {
|
|
159
|
+
id: quotedMsg.stanzaId || "",
|
|
160
|
+
text: quotedMsg.quotedMessage.conversation ||
|
|
161
|
+
quotedMsg.quotedMessage.extendedTextMessage?.text ||
|
|
162
|
+
"",
|
|
163
|
+
sender: quotedMsg.participant || undefined,
|
|
164
|
+
}
|
|
165
|
+
: undefined;
|
|
166
|
+
const inbound = {
|
|
167
|
+
id: msg.key.id || String(Date.now()),
|
|
168
|
+
channel: this.channelId,
|
|
169
|
+
chatId: remoteJid,
|
|
170
|
+
chatType: isGroup ? "group" : "dm",
|
|
171
|
+
sender,
|
|
172
|
+
senderName: msg.pushName || undefined,
|
|
173
|
+
text,
|
|
174
|
+
timestamp: msg.messageTimestamp * 1000,
|
|
175
|
+
isFromMe: false,
|
|
176
|
+
isGroup,
|
|
177
|
+
groupName: undefined,
|
|
178
|
+
replyTo,
|
|
179
|
+
raw: msg,
|
|
180
|
+
};
|
|
181
|
+
if (this.messageHandler) {
|
|
182
|
+
this.messageHandler(inbound).catch((err) => {
|
|
183
|
+
log.error(`WhatsApp message handler error: ${err}`);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=whatsapp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/channels/whatsapp.ts"],"names":[],"mappings":"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"}
|