whale-code 6.4.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 +95 -0
- package/bin/swag-agent.js +9 -0
- package/bin/swagmanager-mcp.js +321 -0
- package/dist/cli/app.d.ts +26 -0
- package/dist/cli/app.js +64 -0
- package/dist/cli/chat/AgentSelector.d.ts +14 -0
- package/dist/cli/chat/AgentSelector.js +14 -0
- package/dist/cli/chat/ChatApp.d.ts +9 -0
- package/dist/cli/chat/ChatApp.js +267 -0
- package/dist/cli/chat/ChatInput.d.ts +39 -0
- package/dist/cli/chat/ChatInput.js +509 -0
- package/dist/cli/chat/MarkdownText.d.ts +10 -0
- package/dist/cli/chat/MarkdownText.js +20 -0
- package/dist/cli/chat/MessageList.d.ts +37 -0
- package/dist/cli/chat/MessageList.js +80 -0
- package/dist/cli/chat/ModelSelector.d.ts +20 -0
- package/dist/cli/chat/ModelSelector.js +73 -0
- package/dist/cli/chat/RewindViewer.d.ts +26 -0
- package/dist/cli/chat/RewindViewer.js +185 -0
- package/dist/cli/chat/StoreSelector.d.ts +14 -0
- package/dist/cli/chat/StoreSelector.js +24 -0
- package/dist/cli/chat/StreamingText.d.ts +12 -0
- package/dist/cli/chat/StreamingText.js +12 -0
- package/dist/cli/chat/SubagentPanel.d.ts +45 -0
- package/dist/cli/chat/SubagentPanel.js +110 -0
- package/dist/cli/chat/TeamPanel.d.ts +21 -0
- package/dist/cli/chat/TeamPanel.js +42 -0
- package/dist/cli/chat/ToolIndicator.d.ts +25 -0
- package/dist/cli/chat/ToolIndicator.js +436 -0
- package/dist/cli/chat/hooks/useAgentLoop.d.ts +39 -0
- package/dist/cli/chat/hooks/useAgentLoop.js +382 -0
- package/dist/cli/chat/hooks/useSlashCommands.d.ts +37 -0
- package/dist/cli/chat/hooks/useSlashCommands.js +387 -0
- package/dist/cli/commands/config-cmd.d.ts +10 -0
- package/dist/cli/commands/config-cmd.js +99 -0
- package/dist/cli/commands/doctor.d.ts +14 -0
- package/dist/cli/commands/doctor.js +172 -0
- package/dist/cli/commands/init.d.ts +16 -0
- package/dist/cli/commands/init.js +278 -0
- package/dist/cli/commands/mcp.d.ts +12 -0
- package/dist/cli/commands/mcp.js +162 -0
- package/dist/cli/login/LoginApp.d.ts +7 -0
- package/dist/cli/login/LoginApp.js +157 -0
- package/dist/cli/print-mode.d.ts +31 -0
- package/dist/cli/print-mode.js +202 -0
- package/dist/cli/serve-mode.d.ts +37 -0
- package/dist/cli/serve-mode.js +636 -0
- package/dist/cli/services/agent-definitions.d.ts +25 -0
- package/dist/cli/services/agent-definitions.js +91 -0
- package/dist/cli/services/agent-events.d.ts +178 -0
- package/dist/cli/services/agent-events.js +175 -0
- package/dist/cli/services/agent-loop.d.ts +90 -0
- package/dist/cli/services/agent-loop.js +762 -0
- package/dist/cli/services/agent-worker-base.d.ts +97 -0
- package/dist/cli/services/agent-worker-base.js +220 -0
- package/dist/cli/services/auth-service.d.ts +30 -0
- package/dist/cli/services/auth-service.js +160 -0
- package/dist/cli/services/background-processes.d.ts +126 -0
- package/dist/cli/services/background-processes.js +318 -0
- package/dist/cli/services/browser-auth.d.ts +24 -0
- package/dist/cli/services/browser-auth.js +180 -0
- package/dist/cli/services/claude-md-loader.d.ts +16 -0
- package/dist/cli/services/claude-md-loader.js +58 -0
- package/dist/cli/services/config-store.d.ts +47 -0
- package/dist/cli/services/config-store.js +79 -0
- package/dist/cli/services/debug-log.d.ts +10 -0
- package/dist/cli/services/debug-log.js +52 -0
- package/dist/cli/services/error-logger.d.ts +58 -0
- package/dist/cli/services/error-logger.js +269 -0
- package/dist/cli/services/file-history.d.ts +21 -0
- package/dist/cli/services/file-history.js +83 -0
- package/dist/cli/services/format-server-response.d.ts +16 -0
- package/dist/cli/services/format-server-response.js +440 -0
- package/dist/cli/services/git-context.d.ts +11 -0
- package/dist/cli/services/git-context.js +66 -0
- package/dist/cli/services/hooks.d.ts +85 -0
- package/dist/cli/services/hooks.js +258 -0
- package/dist/cli/services/interactive-tools.d.ts +125 -0
- package/dist/cli/services/interactive-tools.js +260 -0
- package/dist/cli/services/keybinding-manager.d.ts +52 -0
- package/dist/cli/services/keybinding-manager.js +115 -0
- package/dist/cli/services/local-tools.d.ts +22 -0
- package/dist/cli/services/local-tools.js +697 -0
- package/dist/cli/services/lsp-manager.d.ts +18 -0
- package/dist/cli/services/lsp-manager.js +717 -0
- package/dist/cli/services/mcp-client.d.ts +48 -0
- package/dist/cli/services/mcp-client.js +157 -0
- package/dist/cli/services/memory-manager.d.ts +16 -0
- package/dist/cli/services/memory-manager.js +57 -0
- package/dist/cli/services/model-manager.d.ts +18 -0
- package/dist/cli/services/model-manager.js +71 -0
- package/dist/cli/services/model-router.d.ts +26 -0
- package/dist/cli/services/model-router.js +149 -0
- package/dist/cli/services/permission-modes.d.ts +13 -0
- package/dist/cli/services/permission-modes.js +43 -0
- package/dist/cli/services/rewind.d.ts +84 -0
- package/dist/cli/services/rewind.js +194 -0
- package/dist/cli/services/ripgrep.d.ts +28 -0
- package/dist/cli/services/ripgrep.js +138 -0
- package/dist/cli/services/sandbox.d.ts +29 -0
- package/dist/cli/services/sandbox.js +97 -0
- package/dist/cli/services/server-tools.d.ts +61 -0
- package/dist/cli/services/server-tools.js +543 -0
- package/dist/cli/services/session-persistence.d.ts +23 -0
- package/dist/cli/services/session-persistence.js +99 -0
- package/dist/cli/services/subagent-worker.d.ts +19 -0
- package/dist/cli/services/subagent-worker.js +41 -0
- package/dist/cli/services/subagent.d.ts +47 -0
- package/dist/cli/services/subagent.js +647 -0
- package/dist/cli/services/system-prompt.d.ts +7 -0
- package/dist/cli/services/system-prompt.js +198 -0
- package/dist/cli/services/team-lead.d.ts +73 -0
- package/dist/cli/services/team-lead.js +512 -0
- package/dist/cli/services/team-state.d.ts +77 -0
- package/dist/cli/services/team-state.js +398 -0
- package/dist/cli/services/teammate.d.ts +31 -0
- package/dist/cli/services/teammate.js +689 -0
- package/dist/cli/services/telemetry.d.ts +61 -0
- package/dist/cli/services/telemetry.js +209 -0
- package/dist/cli/services/tools/agent-tools.d.ts +14 -0
- package/dist/cli/services/tools/agent-tools.js +347 -0
- package/dist/cli/services/tools/file-ops.d.ts +15 -0
- package/dist/cli/services/tools/file-ops.js +487 -0
- package/dist/cli/services/tools/search-tools.d.ts +8 -0
- package/dist/cli/services/tools/search-tools.js +186 -0
- package/dist/cli/services/tools/shell-exec.d.ts +10 -0
- package/dist/cli/services/tools/shell-exec.js +168 -0
- package/dist/cli/services/tools/task-manager.d.ts +28 -0
- package/dist/cli/services/tools/task-manager.js +209 -0
- package/dist/cli/services/tools/web-tools.d.ts +11 -0
- package/dist/cli/services/tools/web-tools.js +395 -0
- package/dist/cli/setup/SetupApp.d.ts +9 -0
- package/dist/cli/setup/SetupApp.js +191 -0
- package/dist/cli/shared/MatrixIntro.d.ts +4 -0
- package/dist/cli/shared/MatrixIntro.js +83 -0
- package/dist/cli/shared/Theme.d.ts +74 -0
- package/dist/cli/shared/Theme.js +127 -0
- package/dist/cli/shared/WhaleBanner.d.ts +10 -0
- package/dist/cli/shared/WhaleBanner.js +12 -0
- package/dist/cli/shared/markdown.d.ts +21 -0
- package/dist/cli/shared/markdown.js +756 -0
- package/dist/cli/status/StatusApp.d.ts +4 -0
- package/dist/cli/status/StatusApp.js +105 -0
- package/dist/cli/stores/StoreApp.d.ts +7 -0
- package/dist/cli/stores/StoreApp.js +81 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +538 -0
- package/dist/local-agent/connection.d.ts +48 -0
- package/dist/local-agent/connection.js +332 -0
- package/dist/local-agent/discovery.d.ts +18 -0
- package/dist/local-agent/discovery.js +146 -0
- package/dist/local-agent/executor.d.ts +34 -0
- package/dist/local-agent/executor.js +241 -0
- package/dist/local-agent/index.d.ts +14 -0
- package/dist/local-agent/index.js +198 -0
- package/dist/node/adapters/base.d.ts +35 -0
- package/dist/node/adapters/base.js +10 -0
- package/dist/node/adapters/discord.d.ts +29 -0
- package/dist/node/adapters/discord.js +299 -0
- package/dist/node/adapters/email.d.ts +23 -0
- package/dist/node/adapters/email.js +218 -0
- package/dist/node/adapters/imessage.d.ts +17 -0
- package/dist/node/adapters/imessage.js +118 -0
- package/dist/node/adapters/slack.d.ts +26 -0
- package/dist/node/adapters/slack.js +259 -0
- package/dist/node/adapters/sms.d.ts +23 -0
- package/dist/node/adapters/sms.js +161 -0
- package/dist/node/adapters/telegram.d.ts +17 -0
- package/dist/node/adapters/telegram.js +101 -0
- package/dist/node/adapters/webchat.d.ts +27 -0
- package/dist/node/adapters/webchat.js +160 -0
- package/dist/node/adapters/whatsapp.d.ts +28 -0
- package/dist/node/adapters/whatsapp.js +230 -0
- package/dist/node/cli.d.ts +2 -0
- package/dist/node/cli.js +325 -0
- package/dist/node/config.d.ts +17 -0
- package/dist/node/config.js +31 -0
- package/dist/node/runtime.d.ts +50 -0
- package/dist/node/runtime.js +351 -0
- package/dist/server/handlers/__test-utils__/mock-supabase.d.ts +11 -0
- package/dist/server/handlers/__test-utils__/mock-supabase.js +393 -0
- package/dist/server/handlers/analytics.d.ts +17 -0
- package/dist/server/handlers/analytics.js +266 -0
- package/dist/server/handlers/api-keys.d.ts +6 -0
- package/dist/server/handlers/api-keys.js +221 -0
- package/dist/server/handlers/billing.d.ts +33 -0
- package/dist/server/handlers/billing.js +272 -0
- package/dist/server/handlers/browser.d.ts +10 -0
- package/dist/server/handlers/browser.js +517 -0
- package/dist/server/handlers/catalog.d.ts +99 -0
- package/dist/server/handlers/catalog.js +976 -0
- package/dist/server/handlers/comms.d.ts +254 -0
- package/dist/server/handlers/comms.js +588 -0
- package/dist/server/handlers/creations.d.ts +6 -0
- package/dist/server/handlers/creations.js +479 -0
- package/dist/server/handlers/crm.d.ts +89 -0
- package/dist/server/handlers/crm.js +538 -0
- package/dist/server/handlers/discovery.d.ts +6 -0
- package/dist/server/handlers/discovery.js +288 -0
- package/dist/server/handlers/embeddings.d.ts +92 -0
- package/dist/server/handlers/embeddings.js +197 -0
- package/dist/server/handlers/enrichment.d.ts +8 -0
- package/dist/server/handlers/enrichment.js +768 -0
- package/dist/server/handlers/image-gen.d.ts +6 -0
- package/dist/server/handlers/image-gen.js +409 -0
- package/dist/server/handlers/inventory.d.ts +319 -0
- package/dist/server/handlers/inventory.js +447 -0
- package/dist/server/handlers/kali.d.ts +10 -0
- package/dist/server/handlers/kali.js +210 -0
- package/dist/server/handlers/llm-providers.d.ts +6 -0
- package/dist/server/handlers/llm-providers.js +673 -0
- package/dist/server/handlers/local-agent.d.ts +6 -0
- package/dist/server/handlers/local-agent.js +118 -0
- package/dist/server/handlers/meta-ads.d.ts +111 -0
- package/dist/server/handlers/meta-ads.js +2279 -0
- package/dist/server/handlers/nodes.d.ts +33 -0
- package/dist/server/handlers/nodes.js +699 -0
- package/dist/server/handlers/operations.d.ts +138 -0
- package/dist/server/handlers/operations.js +131 -0
- package/dist/server/handlers/platform.d.ts +23 -0
- package/dist/server/handlers/platform.js +227 -0
- package/dist/server/handlers/supply-chain.d.ts +19 -0
- package/dist/server/handlers/supply-chain.js +327 -0
- package/dist/server/handlers/transcription.d.ts +17 -0
- package/dist/server/handlers/transcription.js +121 -0
- package/dist/server/handlers/video-gen.d.ts +6 -0
- package/dist/server/handlers/video-gen.js +466 -0
- package/dist/server/handlers/voice.d.ts +8 -0
- package/dist/server/handlers/voice.js +1146 -0
- package/dist/server/handlers/workflow-steps.d.ts +86 -0
- package/dist/server/handlers/workflow-steps.js +2349 -0
- package/dist/server/handlers/workflows.d.ts +7 -0
- package/dist/server/handlers/workflows.js +989 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +2427 -0
- package/dist/server/lib/batch-client.d.ts +80 -0
- package/dist/server/lib/batch-client.js +467 -0
- package/dist/server/lib/code-worker-pool.d.ts +31 -0
- package/dist/server/lib/code-worker-pool.js +224 -0
- package/dist/server/lib/code-worker.d.ts +1 -0
- package/dist/server/lib/code-worker.js +188 -0
- package/dist/server/lib/compaction-service.d.ts +32 -0
- package/dist/server/lib/compaction-service.js +162 -0
- package/dist/server/lib/logger.d.ts +19 -0
- package/dist/server/lib/logger.js +46 -0
- package/dist/server/lib/otel.d.ts +38 -0
- package/dist/server/lib/otel.js +126 -0
- package/dist/server/lib/pg-rate-limiter.d.ts +21 -0
- package/dist/server/lib/pg-rate-limiter.js +86 -0
- package/dist/server/lib/prompt-sanitizer.d.ts +37 -0
- package/dist/server/lib/prompt-sanitizer.js +177 -0
- package/dist/server/lib/provider-capabilities.d.ts +85 -0
- package/dist/server/lib/provider-capabilities.js +190 -0
- package/dist/server/lib/provider-failover.d.ts +74 -0
- package/dist/server/lib/provider-failover.js +210 -0
- package/dist/server/lib/rate-limiter.d.ts +39 -0
- package/dist/server/lib/rate-limiter.js +147 -0
- package/dist/server/lib/server-agent-loop.d.ts +107 -0
- package/dist/server/lib/server-agent-loop.js +667 -0
- package/dist/server/lib/server-subagent.d.ts +78 -0
- package/dist/server/lib/server-subagent.js +203 -0
- package/dist/server/lib/session-checkpoint.d.ts +51 -0
- package/dist/server/lib/session-checkpoint.js +145 -0
- package/dist/server/lib/ssrf-guard.d.ts +13 -0
- package/dist/server/lib/ssrf-guard.js +240 -0
- package/dist/server/lib/supabase-client.d.ts +7 -0
- package/dist/server/lib/supabase-client.js +78 -0
- package/dist/server/lib/template-resolver.d.ts +31 -0
- package/dist/server/lib/template-resolver.js +215 -0
- package/dist/server/lib/utils.d.ts +16 -0
- package/dist/server/lib/utils.js +147 -0
- package/dist/server/local-agent-gateway.d.ts +82 -0
- package/dist/server/local-agent-gateway.js +426 -0
- package/dist/server/providers/anthropic.d.ts +20 -0
- package/dist/server/providers/anthropic.js +199 -0
- package/dist/server/providers/bedrock.d.ts +20 -0
- package/dist/server/providers/bedrock.js +194 -0
- package/dist/server/providers/gemini.d.ts +24 -0
- package/dist/server/providers/gemini.js +486 -0
- package/dist/server/providers/openai.d.ts +24 -0
- package/dist/server/providers/openai.js +522 -0
- package/dist/server/providers/registry.d.ts +32 -0
- package/dist/server/providers/registry.js +58 -0
- package/dist/server/providers/shared.d.ts +32 -0
- package/dist/server/providers/shared.js +124 -0
- package/dist/server/providers/types.d.ts +92 -0
- package/dist/server/providers/types.js +12 -0
- package/dist/server/proxy-handlers.d.ts +6 -0
- package/dist/server/proxy-handlers.js +89 -0
- package/dist/server/tool-router.d.ts +149 -0
- package/dist/server/tool-router.js +803 -0
- package/dist/server/validation.d.ts +24 -0
- package/dist/server/validation.js +301 -0
- package/dist/server/worker.d.ts +19 -0
- package/dist/server/worker.js +201 -0
- package/dist/setup.d.ts +8 -0
- package/dist/setup.js +181 -0
- package/dist/shared/agent-core.d.ts +157 -0
- package/dist/shared/agent-core.js +534 -0
- package/dist/shared/anthropic-types.d.ts +105 -0
- package/dist/shared/anthropic-types.js +7 -0
- package/dist/shared/api-client.d.ts +90 -0
- package/dist/shared/api-client.js +379 -0
- package/dist/shared/constants.d.ts +33 -0
- package/dist/shared/constants.js +80 -0
- package/dist/shared/sse-parser.d.ts +26 -0
- package/dist/shared/sse-parser.js +259 -0
- package/dist/shared/tool-dispatch.d.ts +52 -0
- package/dist/shared/tool-dispatch.js +191 -0
- package/dist/shared/types.d.ts +72 -0
- package/dist/shared/types.js +7 -0
- package/dist/updater.d.ts +25 -0
- package/dist/updater.js +140 -0
- package/dist/webchat/widget.d.ts +0 -0
- package/dist/webchat/widget.js +397 -0
- package/package.json +95 -0
- package/src/cli/services/builtin-skills/commit.md +19 -0
- package/src/cli/services/builtin-skills/review-pr.md +21 -0
- package/src/cli/services/builtin-skills/review.md +18 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseAdapter, type OutboundMessage } from "./base.js";
|
|
2
|
+
export interface SlackConfig {
|
|
3
|
+
bot_token: string;
|
|
4
|
+
app_token: string;
|
|
5
|
+
allowed_channels?: string[];
|
|
6
|
+
mention_required?: boolean;
|
|
7
|
+
max_message_length?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare class SlackAdapter extends BaseAdapter {
|
|
10
|
+
readonly type = "slack";
|
|
11
|
+
readonly name: string;
|
|
12
|
+
private config;
|
|
13
|
+
private ws;
|
|
14
|
+
private botUserId;
|
|
15
|
+
private reconnectAttempts;
|
|
16
|
+
private pingTimer;
|
|
17
|
+
constructor(name: string, config: SlackConfig);
|
|
18
|
+
start(): Promise<void>;
|
|
19
|
+
stop(): Promise<void>;
|
|
20
|
+
sendMessage(msg: OutboundMessage): Promise<boolean>;
|
|
21
|
+
private fetchBotIdentity;
|
|
22
|
+
private connectSocketMode;
|
|
23
|
+
private handleSocketMessage;
|
|
24
|
+
private handleEvent;
|
|
25
|
+
private scheduleReconnect;
|
|
26
|
+
}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
const SLACK_API = "https://slack.com/api";
|
|
3
|
+
const MAX_MESSAGE_LENGTH = 4000;
|
|
4
|
+
export class SlackAdapter extends BaseAdapter {
|
|
5
|
+
type = "slack";
|
|
6
|
+
name;
|
|
7
|
+
config;
|
|
8
|
+
ws = null;
|
|
9
|
+
botUserId = null;
|
|
10
|
+
reconnectAttempts = 0;
|
|
11
|
+
pingTimer = null;
|
|
12
|
+
constructor(name, config) {
|
|
13
|
+
super();
|
|
14
|
+
this.name = name;
|
|
15
|
+
this.config = config;
|
|
16
|
+
}
|
|
17
|
+
async start() {
|
|
18
|
+
if (this.running)
|
|
19
|
+
return;
|
|
20
|
+
this.running = true;
|
|
21
|
+
this.reconnectAttempts = 0;
|
|
22
|
+
// Fetch bot user ID for mention filtering
|
|
23
|
+
await this.fetchBotIdentity();
|
|
24
|
+
// Connect via Socket Mode
|
|
25
|
+
console.log(`[slack] Connecting via Socket Mode...`);
|
|
26
|
+
await this.connectSocketMode();
|
|
27
|
+
}
|
|
28
|
+
async stop() {
|
|
29
|
+
this.running = false;
|
|
30
|
+
if (this.pingTimer) {
|
|
31
|
+
clearInterval(this.pingTimer);
|
|
32
|
+
this.pingTimer = null;
|
|
33
|
+
}
|
|
34
|
+
if (this.ws) {
|
|
35
|
+
this.ws.close(1000, "Shutting down");
|
|
36
|
+
this.ws = null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
async sendMessage(msg) {
|
|
40
|
+
try {
|
|
41
|
+
const channelId = msg.metadata?.channel_id || msg.conversation_id;
|
|
42
|
+
if (!channelId) {
|
|
43
|
+
console.error("[slack] No channel_id to send to");
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const maxLen = this.config.max_message_length || MAX_MESSAGE_LENGTH;
|
|
47
|
+
let content = msg.content;
|
|
48
|
+
// Split long messages
|
|
49
|
+
const chunks = [];
|
|
50
|
+
while (content.length > 0) {
|
|
51
|
+
chunks.push(content.slice(0, maxLen));
|
|
52
|
+
content = content.slice(maxLen);
|
|
53
|
+
}
|
|
54
|
+
for (const chunk of chunks) {
|
|
55
|
+
const body = {
|
|
56
|
+
channel: channelId,
|
|
57
|
+
text: chunk,
|
|
58
|
+
};
|
|
59
|
+
// Thread reply if we have a thread_ts
|
|
60
|
+
if (msg.metadata?.thread_ts) {
|
|
61
|
+
body.thread_ts = msg.metadata.thread_ts;
|
|
62
|
+
}
|
|
63
|
+
const res = await fetch(`${SLACK_API}/chat.postMessage`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json; charset=utf-8",
|
|
67
|
+
Authorization: `Bearer ${this.config.bot_token}`,
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify(body),
|
|
70
|
+
});
|
|
71
|
+
const data = await res.json();
|
|
72
|
+
if (!data.ok) {
|
|
73
|
+
console.error(`[slack] Send failed:`, data.error);
|
|
74
|
+
this.stats.errors++;
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
this.stats.messages_out++;
|
|
79
|
+
this.stats.last_message_at = new Date().toISOString();
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
console.error(`[slack] Send error:`, err.message);
|
|
84
|
+
this.stats.errors++;
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async fetchBotIdentity() {
|
|
89
|
+
try {
|
|
90
|
+
const res = await fetch(`${SLACK_API}/auth.test`, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: {
|
|
93
|
+
Authorization: `Bearer ${this.config.bot_token}`,
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
const data = await res.json();
|
|
97
|
+
if (data.ok) {
|
|
98
|
+
this.botUserId = data.user_id;
|
|
99
|
+
console.log(`[slack] Authenticated as ${data.user} (${data.user_id})`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.error(`[slack] Auth failed:`, data.error);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.error(`[slack] Failed to fetch identity:`, err.message);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async connectSocketMode() {
|
|
110
|
+
if (!this.running)
|
|
111
|
+
return;
|
|
112
|
+
try {
|
|
113
|
+
// Request a WebSocket URL via apps.connections.open
|
|
114
|
+
const res = await fetch(`${SLACK_API}/apps.connections.open`, {
|
|
115
|
+
method: "POST",
|
|
116
|
+
headers: {
|
|
117
|
+
Authorization: `Bearer ${this.config.app_token}`,
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
const data = await res.json();
|
|
121
|
+
if (!data.ok) {
|
|
122
|
+
console.error(`[slack] Socket Mode connection failed:`, data.error);
|
|
123
|
+
this.scheduleReconnect();
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const wsUrl = data.url;
|
|
127
|
+
this.ws = new WebSocket(wsUrl);
|
|
128
|
+
this.ws.onopen = () => {
|
|
129
|
+
console.log(`[slack] Socket Mode connected`);
|
|
130
|
+
this.reconnectAttempts = 0;
|
|
131
|
+
// Ping every 30s to keep connection alive
|
|
132
|
+
this.pingTimer = setInterval(() => {
|
|
133
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
134
|
+
this.ws.send(JSON.stringify({ type: "ping" }));
|
|
135
|
+
}
|
|
136
|
+
}, 30_000);
|
|
137
|
+
};
|
|
138
|
+
this.ws.onmessage = (event) => {
|
|
139
|
+
try {
|
|
140
|
+
const data = JSON.parse(String(event.data));
|
|
141
|
+
this.handleSocketMessage(data);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
console.error(`[slack] Failed to parse message:`, err.message);
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
this.ws.onclose = (event) => {
|
|
148
|
+
console.log(`[slack] Socket closed: ${event.code} ${event.reason}`);
|
|
149
|
+
if (this.pingTimer) {
|
|
150
|
+
clearInterval(this.pingTimer);
|
|
151
|
+
this.pingTimer = null;
|
|
152
|
+
}
|
|
153
|
+
if (this.running)
|
|
154
|
+
this.scheduleReconnect();
|
|
155
|
+
};
|
|
156
|
+
this.ws.onerror = () => {
|
|
157
|
+
console.error(`[slack] Socket error`);
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
console.error(`[slack] Connection error:`, err.message);
|
|
162
|
+
this.scheduleReconnect();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
handleSocketMessage(data) {
|
|
166
|
+
// Acknowledge envelope (required for Socket Mode)
|
|
167
|
+
if (data.envelope_id) {
|
|
168
|
+
this.ws?.send(JSON.stringify({ envelope_id: data.envelope_id }));
|
|
169
|
+
}
|
|
170
|
+
switch (data.type) {
|
|
171
|
+
case "hello":
|
|
172
|
+
console.log(`[slack] Socket Mode handshake complete`);
|
|
173
|
+
break;
|
|
174
|
+
case "disconnect":
|
|
175
|
+
console.log(`[slack] Server requested disconnect: ${data.reason}`);
|
|
176
|
+
this.ws?.close(1000, "Server disconnect");
|
|
177
|
+
break;
|
|
178
|
+
case "events_api": {
|
|
179
|
+
const event = data.payload?.event;
|
|
180
|
+
if (event) {
|
|
181
|
+
this.handleEvent(event).catch(err => {
|
|
182
|
+
console.error(`[slack] Error handling event:`, err.message);
|
|
183
|
+
this.stats.errors++;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async handleEvent(event) {
|
|
191
|
+
// Only handle message events
|
|
192
|
+
if (event.type !== "message" && event.type !== "app_mention")
|
|
193
|
+
return;
|
|
194
|
+
// Ignore bot messages and message edits/deletions
|
|
195
|
+
if (event.bot_id || event.subtype)
|
|
196
|
+
return;
|
|
197
|
+
const channelId = event.channel;
|
|
198
|
+
// Filter by allowed channels
|
|
199
|
+
if (this.config.allowed_channels?.length) {
|
|
200
|
+
if (!this.config.allowed_channels.includes(channelId))
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
// For regular messages, check mention requirement
|
|
204
|
+
if (event.type === "message" && this.config.mention_required && this.botUserId) {
|
|
205
|
+
const mentionPattern = `<@${this.botUserId}>`;
|
|
206
|
+
if (!event.text?.includes(mentionPattern))
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
// Clean up content — remove bot mention
|
|
210
|
+
let content = event.text || "";
|
|
211
|
+
if (this.botUserId) {
|
|
212
|
+
content = content.replace(new RegExp(`<@${this.botUserId}>`, "g"), "").trim();
|
|
213
|
+
}
|
|
214
|
+
if (!content)
|
|
215
|
+
return;
|
|
216
|
+
const payload = {
|
|
217
|
+
sender_id: event.user || "unknown",
|
|
218
|
+
content,
|
|
219
|
+
metadata: {
|
|
220
|
+
channel_id: channelId,
|
|
221
|
+
thread_ts: event.thread_ts || event.ts, // Use thread_ts for threading, fallback to message ts
|
|
222
|
+
message_ts: event.ts,
|
|
223
|
+
team_id: event.team,
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
// Fetch user display name
|
|
227
|
+
if (event.user) {
|
|
228
|
+
try {
|
|
229
|
+
const res = await fetch(`${SLACK_API}/users.info?user=${event.user}`, {
|
|
230
|
+
headers: { Authorization: `Bearer ${this.config.bot_token}` },
|
|
231
|
+
});
|
|
232
|
+
const data = await res.json();
|
|
233
|
+
if (data.ok) {
|
|
234
|
+
payload.sender_name = data.user?.profile?.display_name || data.user?.real_name || data.user?.name;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// Non-critical — proceed without name
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
this.stats.messages_in++;
|
|
242
|
+
this.stats.last_message_at = new Date().toISOString();
|
|
243
|
+
if (this.onInboundMessage) {
|
|
244
|
+
await this.onInboundMessage(payload);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
scheduleReconnect() {
|
|
248
|
+
if (!this.running)
|
|
249
|
+
return;
|
|
250
|
+
this.reconnectAttempts++;
|
|
251
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 60_000);
|
|
252
|
+
console.log(`[slack] Reconnecting in ${delay}ms (attempt ${this.reconnectAttempts})...`);
|
|
253
|
+
setTimeout(() => {
|
|
254
|
+
if (!this.running)
|
|
255
|
+
return;
|
|
256
|
+
this.connectSocketMode();
|
|
257
|
+
}, delay);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { BaseAdapter, type OutboundMessage } from "./base.js";
|
|
2
|
+
export interface SmsConfig {
|
|
3
|
+
account_sid: string;
|
|
4
|
+
auth_token: string;
|
|
5
|
+
from_number: string;
|
|
6
|
+
webhook_port?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class SmsAdapter extends BaseAdapter {
|
|
9
|
+
readonly type = "sms";
|
|
10
|
+
readonly name: string;
|
|
11
|
+
private config;
|
|
12
|
+
private server;
|
|
13
|
+
private reconnectAttempts;
|
|
14
|
+
constructor(name: string, config: SmsConfig);
|
|
15
|
+
start(): Promise<void>;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
sendMessage(msg: OutboundMessage): Promise<boolean>;
|
|
18
|
+
private startWebhookServer;
|
|
19
|
+
/** Handle inbound Twilio SMS webhook (POST with URL-encoded form data) */
|
|
20
|
+
private handleIncoming;
|
|
21
|
+
private processWebhookPayload;
|
|
22
|
+
private scheduleRestart;
|
|
23
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
import { BaseAdapter } from "./base.js";
|
|
3
|
+
const DEFAULT_WEBHOOK_PORT = 3101;
|
|
4
|
+
export class SmsAdapter extends BaseAdapter {
|
|
5
|
+
type = "sms";
|
|
6
|
+
name;
|
|
7
|
+
config;
|
|
8
|
+
server = null;
|
|
9
|
+
reconnectAttempts = 0;
|
|
10
|
+
constructor(name, config) {
|
|
11
|
+
super();
|
|
12
|
+
this.name = name;
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
async start() {
|
|
16
|
+
if (this.running)
|
|
17
|
+
return;
|
|
18
|
+
this.running = true;
|
|
19
|
+
this.reconnectAttempts = 0;
|
|
20
|
+
console.log(`[sms] Starting Twilio webhook server...`);
|
|
21
|
+
this.startWebhookServer();
|
|
22
|
+
}
|
|
23
|
+
async stop() {
|
|
24
|
+
this.running = false;
|
|
25
|
+
if (this.server) {
|
|
26
|
+
await new Promise((resolve) => {
|
|
27
|
+
this.server.close(() => resolve());
|
|
28
|
+
});
|
|
29
|
+
this.server = null;
|
|
30
|
+
}
|
|
31
|
+
console.log(`[sms] Webhook server stopped`);
|
|
32
|
+
}
|
|
33
|
+
async sendMessage(msg) {
|
|
34
|
+
try {
|
|
35
|
+
const toNumber = msg.metadata?.from_number || msg.sender_id;
|
|
36
|
+
if (!toNumber) {
|
|
37
|
+
console.error("[sms] No recipient phone number");
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const url = `https://api.twilio.com/2010-04-01/Accounts/${this.config.account_sid}/Messages.json`;
|
|
41
|
+
// Twilio API uses URL-encoded form data with Basic auth
|
|
42
|
+
const body = new URLSearchParams({
|
|
43
|
+
To: toNumber,
|
|
44
|
+
From: this.config.from_number,
|
|
45
|
+
Body: msg.content,
|
|
46
|
+
});
|
|
47
|
+
const credentials = Buffer.from(`${this.config.account_sid}:${this.config.auth_token}`).toString("base64");
|
|
48
|
+
const res = await fetch(url, {
|
|
49
|
+
method: "POST",
|
|
50
|
+
headers: {
|
|
51
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
52
|
+
Authorization: `Basic ${credentials}`,
|
|
53
|
+
},
|
|
54
|
+
body: body.toString(),
|
|
55
|
+
});
|
|
56
|
+
if (res.ok) {
|
|
57
|
+
this.stats.messages_out++;
|
|
58
|
+
this.stats.last_message_at = new Date().toISOString();
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
const err = await res.text();
|
|
62
|
+
console.error(`[sms] Send failed (${res.status}):`, err);
|
|
63
|
+
this.stats.errors++;
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
console.error(`[sms] Send error:`, err.message);
|
|
68
|
+
this.stats.errors++;
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
startWebhookServer() {
|
|
73
|
+
const port = this.config.webhook_port || DEFAULT_WEBHOOK_PORT;
|
|
74
|
+
this.server = createServer((req, res) => {
|
|
75
|
+
if (req.method === "POST") {
|
|
76
|
+
this.handleIncoming(req, res);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
// Health check endpoint
|
|
80
|
+
res.writeHead(200, { "Content-Type": "text/plain" });
|
|
81
|
+
res.end("WhaleNode SMS adapter running");
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
this.server.on("error", (err) => {
|
|
85
|
+
console.error(`[sms] Server error:`, err.message);
|
|
86
|
+
this.stats.errors++;
|
|
87
|
+
if (this.running)
|
|
88
|
+
this.scheduleRestart();
|
|
89
|
+
});
|
|
90
|
+
this.server.listen(port, () => {
|
|
91
|
+
console.log(`[sms] Twilio webhook server listening on port ${port}`);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** Handle inbound Twilio SMS webhook (POST with URL-encoded form data) */
|
|
95
|
+
handleIncoming(req, res) {
|
|
96
|
+
let body = "";
|
|
97
|
+
req.on("data", (chunk) => {
|
|
98
|
+
body += chunk.toString();
|
|
99
|
+
});
|
|
100
|
+
req.on("end", () => {
|
|
101
|
+
// Respond with empty TwiML to acknowledge receipt
|
|
102
|
+
res.writeHead(200, { "Content-Type": "application/xml" });
|
|
103
|
+
res.end("<?xml version=\"1.0\" encoding=\"UTF-8\"?><Response></Response>");
|
|
104
|
+
this.processWebhookPayload(body).catch((err) => {
|
|
105
|
+
console.error(`[sms] Error processing webhook:`, err.message);
|
|
106
|
+
this.stats.errors++;
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
async processWebhookPayload(raw) {
|
|
111
|
+
// Twilio sends URL-encoded form data
|
|
112
|
+
const params = new URLSearchParams(raw);
|
|
113
|
+
const fromNumber = params.get("From");
|
|
114
|
+
const toNumber = params.get("To");
|
|
115
|
+
const messageBody = params.get("Body");
|
|
116
|
+
const messageSid = params.get("MessageSid");
|
|
117
|
+
if (!fromNumber || !messageBody) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const payload = {
|
|
121
|
+
sender_id: fromNumber,
|
|
122
|
+
content: messageBody,
|
|
123
|
+
metadata: {
|
|
124
|
+
from_number: fromNumber,
|
|
125
|
+
to_number: toNumber,
|
|
126
|
+
message_sid: messageSid,
|
|
127
|
+
num_media: params.get("NumMedia"),
|
|
128
|
+
from_city: params.get("FromCity"),
|
|
129
|
+
from_state: params.get("FromState"),
|
|
130
|
+
from_country: params.get("FromCountry"),
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
this.stats.messages_in++;
|
|
134
|
+
this.stats.last_message_at = new Date().toISOString();
|
|
135
|
+
if (this.onInboundMessage) {
|
|
136
|
+
await this.onInboundMessage(payload).catch((err) => {
|
|
137
|
+
console.error(`[sms] Error handling message:`, err.message);
|
|
138
|
+
this.stats.errors++;
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
scheduleRestart() {
|
|
143
|
+
if (!this.running)
|
|
144
|
+
return;
|
|
145
|
+
this.reconnectAttempts++;
|
|
146
|
+
const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts - 1), 60_000);
|
|
147
|
+
console.log(`[sms] Restarting webhook server in ${delay}ms (attempt ${this.reconnectAttempts})...`);
|
|
148
|
+
setTimeout(() => {
|
|
149
|
+
if (!this.running)
|
|
150
|
+
return;
|
|
151
|
+
if (this.server) {
|
|
152
|
+
this.server.close(() => {
|
|
153
|
+
this.startWebhookServer();
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
this.startWebhookServer();
|
|
158
|
+
}
|
|
159
|
+
}, delay);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { BaseAdapter, type OutboundMessage } from "./base.js";
|
|
2
|
+
export interface TelegramConfig {
|
|
3
|
+
bot_token: string;
|
|
4
|
+
allowed_chats?: number[];
|
|
5
|
+
}
|
|
6
|
+
export declare class TelegramAdapter extends BaseAdapter {
|
|
7
|
+
readonly type = "telegram";
|
|
8
|
+
readonly name: string;
|
|
9
|
+
private config;
|
|
10
|
+
private offset;
|
|
11
|
+
private pollTimer;
|
|
12
|
+
constructor(name: string, config: TelegramConfig);
|
|
13
|
+
start(): Promise<void>;
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
sendMessage(msg: OutboundMessage): Promise<boolean>;
|
|
16
|
+
private poll;
|
|
17
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { BaseAdapter } from "./base.js";
|
|
2
|
+
export class TelegramAdapter extends BaseAdapter {
|
|
3
|
+
type = "telegram";
|
|
4
|
+
name;
|
|
5
|
+
config;
|
|
6
|
+
offset = 0;
|
|
7
|
+
pollTimer = null;
|
|
8
|
+
constructor(name, config) {
|
|
9
|
+
super();
|
|
10
|
+
this.name = name;
|
|
11
|
+
this.config = config;
|
|
12
|
+
}
|
|
13
|
+
async start() {
|
|
14
|
+
if (this.running)
|
|
15
|
+
return;
|
|
16
|
+
this.running = true;
|
|
17
|
+
console.log(`[telegram] Starting long-poll for bot...`);
|
|
18
|
+
this.poll();
|
|
19
|
+
}
|
|
20
|
+
async stop() {
|
|
21
|
+
this.running = false;
|
|
22
|
+
if (this.pollTimer) {
|
|
23
|
+
clearTimeout(this.pollTimer);
|
|
24
|
+
this.pollTimer = null;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async sendMessage(msg) {
|
|
28
|
+
try {
|
|
29
|
+
const chatId = msg.metadata?.chat_id || msg.conversation_id;
|
|
30
|
+
if (!chatId)
|
|
31
|
+
return false;
|
|
32
|
+
const res = await fetch(`https://api.telegram.org/bot${this.config.bot_token}/sendMessage`, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: { "Content-Type": "application/json" },
|
|
35
|
+
body: JSON.stringify({
|
|
36
|
+
chat_id: chatId,
|
|
37
|
+
text: msg.content,
|
|
38
|
+
parse_mode: "Markdown",
|
|
39
|
+
}),
|
|
40
|
+
});
|
|
41
|
+
if (res.ok) {
|
|
42
|
+
this.stats.messages_out++;
|
|
43
|
+
this.stats.last_message_at = new Date().toISOString();
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
this.stats.errors++;
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
this.stats.errors++;
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async poll() {
|
|
55
|
+
if (!this.running)
|
|
56
|
+
return;
|
|
57
|
+
try {
|
|
58
|
+
const res = await fetch(`https://api.telegram.org/bot${this.config.bot_token}/getUpdates?offset=${this.offset}&timeout=30`);
|
|
59
|
+
const data = await res.json();
|
|
60
|
+
if (data.ok && data.result?.length) {
|
|
61
|
+
for (const update of data.result) {
|
|
62
|
+
this.offset = update.update_id + 1;
|
|
63
|
+
const message = update.message;
|
|
64
|
+
if (!message?.text)
|
|
65
|
+
continue;
|
|
66
|
+
// Filter by allowed chats
|
|
67
|
+
if (this.config.allowed_chats?.length) {
|
|
68
|
+
if (!this.config.allowed_chats.includes(message.chat.id))
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const payload = {
|
|
72
|
+
sender_id: String(message.from?.id || "unknown"),
|
|
73
|
+
sender_name: [message.from?.first_name, message.from?.last_name].filter(Boolean).join(" "),
|
|
74
|
+
content: message.text,
|
|
75
|
+
metadata: {
|
|
76
|
+
chat_id: message.chat.id,
|
|
77
|
+
chat_type: message.chat.type,
|
|
78
|
+
message_id: message.message_id,
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
this.stats.messages_in++;
|
|
82
|
+
this.stats.last_message_at = new Date().toISOString();
|
|
83
|
+
if (this.onInboundMessage) {
|
|
84
|
+
await this.onInboundMessage(payload).catch(err => {
|
|
85
|
+
console.error(`[telegram] Error handling message:`, err.message);
|
|
86
|
+
this.stats.errors++;
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (err) {
|
|
93
|
+
console.error(`[telegram] Poll error:`, err.message);
|
|
94
|
+
this.stats.errors++;
|
|
95
|
+
}
|
|
96
|
+
// Schedule next poll (backoff on errors)
|
|
97
|
+
if (this.running) {
|
|
98
|
+
this.pollTimer = setTimeout(() => this.poll(), 1000);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseAdapter, type OutboundMessage } from "./base.js";
|
|
2
|
+
export interface WebchatConfig {
|
|
3
|
+
port?: number;
|
|
4
|
+
allowed_origins?: string[];
|
|
5
|
+
max_message_length?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* WebChat adapter — runs a local HTTP server that serves a chat widget API.
|
|
9
|
+
* Customers connect via embedded JS widget on any website.
|
|
10
|
+
*
|
|
11
|
+
* Endpoints:
|
|
12
|
+
* POST /message — send a message (returns agent response)
|
|
13
|
+
* GET /health — health check
|
|
14
|
+
* OPTIONS * — CORS preflight
|
|
15
|
+
*/
|
|
16
|
+
export declare class WebchatAdapter extends BaseAdapter {
|
|
17
|
+
readonly type = "webchat";
|
|
18
|
+
readonly name: string;
|
|
19
|
+
private config;
|
|
20
|
+
private server;
|
|
21
|
+
private port;
|
|
22
|
+
private outboundQueue;
|
|
23
|
+
constructor(name: string, config?: WebchatConfig);
|
|
24
|
+
start(): Promise<void>;
|
|
25
|
+
stop(): Promise<void>;
|
|
26
|
+
sendMessage(msg: OutboundMessage): Promise<boolean>;
|
|
27
|
+
}
|