pi-courier 0.1.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 +363 -0
- package/README.zh-CN.md +362 -0
- package/deploy/pi-msg-bridge.service +26 -0
- package/deploy/pi-msg-bridge.user.service +37 -0
- package/dist/auth/challenge-auth.d.ts +76 -0
- package/dist/auth/challenge-auth.d.ts.map +1 -0
- package/dist/auth/challenge-auth.js +337 -0
- package/dist/auth/challenge-auth.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +265 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +49 -0
- package/dist/config.js.map +1 -0
- package/dist/formatting.d.ts +22 -0
- package/dist/formatting.d.ts.map +1 -0
- package/dist/formatting.js +74 -0
- package/dist/formatting.js.map +1 -0
- package/dist/lock.d.ts +3 -0
- package/dist/lock.d.ts.map +1 -0
- package/dist/lock.js +75 -0
- package/dist/lock.js.map +1 -0
- package/dist/rpc/command-map.d.ts +19 -0
- package/dist/rpc/command-map.d.ts.map +1 -0
- package/dist/rpc/command-map.js +191 -0
- package/dist/rpc/command-map.js.map +1 -0
- package/dist/rpc/message-router.d.ts +30 -0
- package/dist/rpc/message-router.d.ts.map +1 -0
- package/dist/rpc/message-router.js +110 -0
- package/dist/rpc/message-router.js.map +1 -0
- package/dist/rpc/pi-rpc.d.ts +79 -0
- package/dist/rpc/pi-rpc.d.ts.map +1 -0
- package/dist/rpc/pi-rpc.js +199 -0
- package/dist/rpc/pi-rpc.js.map +1 -0
- package/dist/setup.d.ts +10 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +159 -0
- package/dist/setup.js.map +1 -0
- package/dist/standalone.d.ts +13 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/standalone.js +184 -0
- package/dist/standalone.js.map +1 -0
- package/dist/transports/discord.d.ts +33 -0
- package/dist/transports/discord.d.ts.map +1 -0
- package/dist/transports/discord.js +216 -0
- package/dist/transports/discord.js.map +1 -0
- package/dist/transports/interface.d.ts +42 -0
- package/dist/transports/interface.d.ts.map +1 -0
- package/dist/transports/interface.js +2 -0
- package/dist/transports/interface.js.map +1 -0
- package/dist/transports/manager.d.ts +54 -0
- package/dist/transports/manager.d.ts.map +1 -0
- package/dist/transports/manager.js +98 -0
- package/dist/transports/manager.js.map +1 -0
- package/dist/transports/matrix-utils.d.ts +31 -0
- package/dist/transports/matrix-utils.d.ts.map +1 -0
- package/dist/transports/matrix-utils.js +99 -0
- package/dist/transports/matrix-utils.js.map +1 -0
- package/dist/transports/matrix-utils.test.d.ts +2 -0
- package/dist/transports/matrix-utils.test.d.ts.map +1 -0
- package/dist/transports/matrix-utils.test.js +246 -0
- package/dist/transports/matrix-utils.test.js.map +1 -0
- package/dist/transports/matrix.d.ts +34 -0
- package/dist/transports/matrix.d.ts.map +1 -0
- package/dist/transports/matrix.js +240 -0
- package/dist/transports/matrix.js.map +1 -0
- package/dist/transports/slack.d.ts +31 -0
- package/dist/transports/slack.d.ts.map +1 -0
- package/dist/transports/slack.js +203 -0
- package/dist/transports/slack.js.map +1 -0
- package/dist/transports/telegram.d.ts +38 -0
- package/dist/transports/telegram.d.ts.map +1 -0
- package/dist/transports/telegram.js +167 -0
- package/dist/transports/telegram.js.map +1 -0
- package/dist/transports/whatsapp.d.ts +31 -0
- package/dist/transports/whatsapp.d.ts.map +1 -0
- package/dist/transports/whatsapp.js +235 -0
- package/dist/transports/whatsapp.js.map +1 -0
- package/dist/types.d.ts +69 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/extensions/index.ts +42 -0
- package/package.json +71 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standalone entry — runs the bridge as its own process (systemd-friendly),
|
|
3
|
+
* talking to pi over RPC mode instead of living inside pi as an extension.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* node dist/standalone.js [--workdir <dir>] [--pi-cli <path>] [--session-dir <dir>] [--debug]
|
|
7
|
+
*
|
|
8
|
+
* Architecture:
|
|
9
|
+
* Messenger (Matrix/Telegram/...) ──> bridge ──> pi --mode rpc (JSONL over stdio)
|
|
10
|
+
* Messenger <── replies <────────── bridge <── agent events (stdout JSONL)
|
|
11
|
+
*/
|
|
12
|
+
import { pathToFileURL } from "node:url";
|
|
13
|
+
import { ChallengeAuth } from "./auth/challenge-auth.js";
|
|
14
|
+
import { loadConfig, saveConfig } from "./config.js";
|
|
15
|
+
import { acquireLock, releaseLock } from "./lock.js";
|
|
16
|
+
import { createMessageRouter } from "./rpc/message-router.js";
|
|
17
|
+
import { PiRpc } from "./rpc/pi-rpc.js";
|
|
18
|
+
import { TransportManager } from "./transports/manager.js";
|
|
19
|
+
import { MatrixProvider } from "./transports/matrix.js";
|
|
20
|
+
// Suppress the known `util._extend` deprecation warning emitted by some
|
|
21
|
+
// transport dependencies at load time — it pollutes interactive output.
|
|
22
|
+
{
|
|
23
|
+
const orig = process.emitWarning;
|
|
24
|
+
process.emitWarning = ((warning, ...rest) => {
|
|
25
|
+
const msg = typeof warning === "string" ? warning : warning?.message ?? "";
|
|
26
|
+
if (msg.includes("util._extend"))
|
|
27
|
+
return;
|
|
28
|
+
orig.call(process, warning, ...rest);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function parseArgs(argv) {
|
|
32
|
+
const result = {};
|
|
33
|
+
for (let i = 0; i < argv.length; i++) {
|
|
34
|
+
const arg = argv[i];
|
|
35
|
+
switch (arg) {
|
|
36
|
+
case "--workdir":
|
|
37
|
+
result.workdir = argv[++i];
|
|
38
|
+
break;
|
|
39
|
+
case "--setup":
|
|
40
|
+
case "--configure":
|
|
41
|
+
console.warn("⚠️ 旧参数已废弃,请用 `pi-remote setup`");
|
|
42
|
+
break;
|
|
43
|
+
case "--pi-cli":
|
|
44
|
+
console.warn("⚠️ 旧参数已废弃,请在 ~/.pi/msg-bridge.json 配置 cliPath,或设 PI_CLI_PATH");
|
|
45
|
+
i++;
|
|
46
|
+
break;
|
|
47
|
+
case "--session-dir":
|
|
48
|
+
console.warn("⚠️ 旧参数已废弃,请在 ~/.pi/msg-bridge.json 配置 sessionDir");
|
|
49
|
+
i++;
|
|
50
|
+
break;
|
|
51
|
+
case "--debug":
|
|
52
|
+
console.warn("⚠️ 旧参数已废弃,请在 ~/.pi/msg-bridge.json 配置 debug: true");
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
console.warn(`[bridge] ignoring unknown argument: ${arg}`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
function log(...args) {
|
|
61
|
+
console.log(`[${new Date().toISOString()}]`, ...args);
|
|
62
|
+
}
|
|
63
|
+
export async function main(argv = process.argv.slice(2)) {
|
|
64
|
+
const args = parseArgs(argv);
|
|
65
|
+
// Single-instance guard (same lock file as the extension mode)
|
|
66
|
+
if (!acquireLock()) {
|
|
67
|
+
console.error("[bridge] another msg-bridge instance is already running — exiting");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
const config = loadConfig();
|
|
71
|
+
const debug = config.debug === true;
|
|
72
|
+
const workdir = args.workdir ?? config.workdir;
|
|
73
|
+
const sessionDir = config.sessionDir;
|
|
74
|
+
const cliPath = config.cliPath;
|
|
75
|
+
const auth = new ChallengeAuth((code, username) => log(`🔐 Challenge code for @${username}: ${code}`), (message, level) => log(`[auth:${level ?? "info"}] ${message}`), async (_chatId, _message) => {
|
|
76
|
+
// Challenge prompts are sent via the transport's sendMessage
|
|
77
|
+
}, () => {
|
|
78
|
+
const cfg = loadConfig();
|
|
79
|
+
cfg.auth = auth.exportConfig();
|
|
80
|
+
saveConfig(cfg);
|
|
81
|
+
});
|
|
82
|
+
if (config.auth) {
|
|
83
|
+
auth.loadFromConfig(config.auth);
|
|
84
|
+
}
|
|
85
|
+
const transportManager = new TransportManager();
|
|
86
|
+
const addTransport = (transport) => {
|
|
87
|
+
transportManager.addTransport(transport);
|
|
88
|
+
};
|
|
89
|
+
if (config.matrix?.homeserverUrl && config.matrix?.accessToken) {
|
|
90
|
+
addTransport(new MatrixProvider(config.matrix, auth));
|
|
91
|
+
}
|
|
92
|
+
if (transportManager.getAllTransports().length === 0) {
|
|
93
|
+
console.error("[bridge] no transports configured. Configure ~/.pi/msg-bridge.json or set PI_* env vars (see README).");
|
|
94
|
+
releaseLock();
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
// ---- pi RPC -------------------------------------------------------------
|
|
98
|
+
// --continue: resume the most recent session on restart (same as `pi -c`),
|
|
99
|
+
// so bridge/service restarts and /reload keep the conversation context.
|
|
100
|
+
const rpcArgs = ["--continue"];
|
|
101
|
+
if (sessionDir) {
|
|
102
|
+
rpcArgs.push("--session-dir", sessionDir);
|
|
103
|
+
}
|
|
104
|
+
const rpc = new PiRpc({
|
|
105
|
+
cliPath,
|
|
106
|
+
cwd: workdir,
|
|
107
|
+
args: rpcArgs,
|
|
108
|
+
});
|
|
109
|
+
// ---- message routing ------------------------------------------------------
|
|
110
|
+
const sendReply = async (chatId, transport, text) => {
|
|
111
|
+
try {
|
|
112
|
+
await transportManager.sendMessage(chatId, transport, text);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
log(`⚠️ failed to send reply via ${transport}:`, err.message);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
const router = createMessageRouter({
|
|
119
|
+
rpc,
|
|
120
|
+
auth,
|
|
121
|
+
transportManager,
|
|
122
|
+
sendReply,
|
|
123
|
+
log,
|
|
124
|
+
debug,
|
|
125
|
+
});
|
|
126
|
+
transportManager.onMessage((msg) => {
|
|
127
|
+
router.handleIncoming(msg).catch((err) => {
|
|
128
|
+
log("❌ message handling error:", err.message);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
transportManager.onError((err, transport) => {
|
|
132
|
+
log(`❌ ${transport} error:`, err.message);
|
|
133
|
+
});
|
|
134
|
+
// ---- agent events → replies ------------------------------------------------
|
|
135
|
+
rpc.onEvent((event) => {
|
|
136
|
+
router.handleEvent(event);
|
|
137
|
+
});
|
|
138
|
+
// ---- startup ----------------------------------------------------------------
|
|
139
|
+
try {
|
|
140
|
+
await transportManager.connectAll();
|
|
141
|
+
log(`✅ transports connected: ${transportManager
|
|
142
|
+
.getStatus()
|
|
143
|
+
.map((s) => `${s.type}=${s.connected ? "up" : "down"}`)
|
|
144
|
+
.join(", ")}`);
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
log("⚠️ some transports failed to connect:", err.message);
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
await rpc.start();
|
|
151
|
+
const state = await rpc.getState();
|
|
152
|
+
log(`✅ pi RPC connected (model: ${state.model?.id ?? "unknown"}, session: ${state.sessionId ?? "?"})`);
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
console.error("[bridge] failed to start pi RPC:", err.message);
|
|
156
|
+
await transportManager.disconnectAll();
|
|
157
|
+
releaseLock();
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
// ---- shutdown ----------------------------------------------------------------
|
|
161
|
+
let shuttingDown = false;
|
|
162
|
+
const shutdown = async (signal) => {
|
|
163
|
+
if (shuttingDown)
|
|
164
|
+
return;
|
|
165
|
+
shuttingDown = true;
|
|
166
|
+
log(`🛑 ${signal} received — shutting down`);
|
|
167
|
+
await rpc.stop().catch(() => { });
|
|
168
|
+
await transportManager.disconnectAll();
|
|
169
|
+
releaseLock();
|
|
170
|
+
process.exit(0);
|
|
171
|
+
};
|
|
172
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
173
|
+
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
174
|
+
log("🚀 msg-bridge standalone ready. Waiting for messages...");
|
|
175
|
+
}
|
|
176
|
+
// Direct execution: `node dist/standalone.js [--workdir ...]`
|
|
177
|
+
if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
|
|
178
|
+
main().catch((err) => {
|
|
179
|
+
console.error("[bridge] fatal:", err);
|
|
180
|
+
releaseLock();
|
|
181
|
+
process.exit(1);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=standalone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"standalone.js","sourceRoot":"","sources":["../src/standalone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ChallengeAuth } from "../auth/challenge-auth.js";
|
|
2
|
+
import type { ExternalMessage } from "../types.js";
|
|
3
|
+
import type { ITransportProvider } from "./interface.js";
|
|
4
|
+
/**
|
|
5
|
+
* Discord transport provider using discord.js
|
|
6
|
+
*/
|
|
7
|
+
export declare class DiscordProvider implements ITransportProvider {
|
|
8
|
+
private config;
|
|
9
|
+
private auth;
|
|
10
|
+
readonly type = "discord";
|
|
11
|
+
private client;
|
|
12
|
+
private _isConnected;
|
|
13
|
+
private botUserId;
|
|
14
|
+
private messageHandler?;
|
|
15
|
+
private errorHandler?;
|
|
16
|
+
private lastProcessedMessageId;
|
|
17
|
+
constructor(config: {
|
|
18
|
+
token: string;
|
|
19
|
+
}, auth: ChallengeAuth);
|
|
20
|
+
get isConnected(): boolean;
|
|
21
|
+
connect(): Promise<void>;
|
|
22
|
+
disconnect(): Promise<void>;
|
|
23
|
+
sendMessage(chatId: string, text: string): Promise<void>;
|
|
24
|
+
sendTyping(chatId: string): Promise<void>;
|
|
25
|
+
onMessage(handler: (message: ExternalMessage) => void): void;
|
|
26
|
+
onError(handler: (error: Error) => void): void;
|
|
27
|
+
/**
|
|
28
|
+
* Split a message into chunks that fit Discord's 2000 char limit.
|
|
29
|
+
* Tries to split at newlines or spaces when possible.
|
|
30
|
+
*/
|
|
31
|
+
private splitMessage;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=discord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../../src/transports/discord.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAWzD;;GAEG;AACH,qBAAa,eAAgB,YAAW,kBAAkB;IAUtD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAVd,QAAQ,CAAC,IAAI,aAAa;IAC1B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,cAAc,CAAC,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAyB;IAC9C,OAAO,CAAC,sBAAsB,CAAM;gBAG1B,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,EACzB,IAAI,EAAE,aAAa;IAG7B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8IxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBxD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAe/C,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAI5D,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI;IAI9C;;;OAGG;IACH,OAAO,CAAC,YAAY;CA+BrB"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
async function loadDiscordJS() {
|
|
2
|
+
const discord = await import("discord.js");
|
|
3
|
+
return discord;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Discord transport provider using discord.js
|
|
7
|
+
*/
|
|
8
|
+
export class DiscordProvider {
|
|
9
|
+
config;
|
|
10
|
+
auth;
|
|
11
|
+
type = "discord";
|
|
12
|
+
client = null;
|
|
13
|
+
_isConnected = false;
|
|
14
|
+
botUserId = "";
|
|
15
|
+
messageHandler;
|
|
16
|
+
errorHandler;
|
|
17
|
+
lastProcessedMessageId = "";
|
|
18
|
+
constructor(config, auth) {
|
|
19
|
+
this.config = config;
|
|
20
|
+
this.auth = auth;
|
|
21
|
+
}
|
|
22
|
+
get isConnected() {
|
|
23
|
+
return this._isConnected;
|
|
24
|
+
}
|
|
25
|
+
async connect() {
|
|
26
|
+
if (this._isConnected)
|
|
27
|
+
return;
|
|
28
|
+
const { token } = this.config;
|
|
29
|
+
if (!token) {
|
|
30
|
+
throw new Error("Discord bot token required");
|
|
31
|
+
}
|
|
32
|
+
const discord = await loadDiscordJS();
|
|
33
|
+
this.client = new discord.Client({
|
|
34
|
+
intents: [
|
|
35
|
+
discord.GatewayIntentBits.Guilds,
|
|
36
|
+
discord.GatewayIntentBits.GuildMessages,
|
|
37
|
+
discord.GatewayIntentBits.DirectMessages,
|
|
38
|
+
discord.GatewayIntentBits.MessageContent, // Privileged intent - must enable in Discord Developer Portal
|
|
39
|
+
],
|
|
40
|
+
partials: [
|
|
41
|
+
discord.Partials.Channel,
|
|
42
|
+
discord.Partials.Message,
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
// Handle incoming messages
|
|
46
|
+
this.client.on(discord.Events.MessageCreate, async (message) => {
|
|
47
|
+
// Ignore bot's own messages
|
|
48
|
+
if (message.author.bot) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
// Skip empty messages (attachments only, etc.)
|
|
52
|
+
if (!message.content) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// Filter out duplicate messages
|
|
56
|
+
if (message.id === this.lastProcessedMessageId) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
this.lastProcessedMessageId = message.id;
|
|
60
|
+
// Detect if this is a DM
|
|
61
|
+
const isDM = message.channel.type === discord.ChannelType.DM;
|
|
62
|
+
// Detect bot mention: <@BOT_USER_ID> or <@!BOT_USER_ID> (nickname mention)
|
|
63
|
+
const wasMentioned = this.botUserId
|
|
64
|
+
? message.content.includes(`<@${this.botUserId}>`) ||
|
|
65
|
+
message.content.includes(`<@!${this.botUserId}>`) ||
|
|
66
|
+
message.mentions.users.has(this.botUserId)
|
|
67
|
+
: false;
|
|
68
|
+
const userId = message.author.id;
|
|
69
|
+
const chatId = message.channelId;
|
|
70
|
+
const username = message.author.username;
|
|
71
|
+
const text = message.content.trim();
|
|
72
|
+
const isGroupChat = !isDM;
|
|
73
|
+
// Check authorization
|
|
74
|
+
const sendMessageToUser = async (cId, text) => {
|
|
75
|
+
if (this.client) {
|
|
76
|
+
const channel = await this.client.channels.fetch(cId);
|
|
77
|
+
if (channel && "send" in channel) {
|
|
78
|
+
await channel.send(text);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const isAuthorized = await this.auth.checkAuthorization(userId, chatId, username, isGroupChat, wasMentioned, sendMessageToUser, this.type);
|
|
83
|
+
// Handle admin commands and challenge codes in DM
|
|
84
|
+
if (!isGroupChat && (text.startsWith("/") || text.match(/^\d{6}$/))) {
|
|
85
|
+
const handled = await this.auth.handleAdminCommand(text, chatId, userId, async (text) => await this.sendMessage(chatId, text), this.type);
|
|
86
|
+
if (handled) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (!isAuthorized) {
|
|
91
|
+
return; // Auth handler already sent challenge/error messages
|
|
92
|
+
}
|
|
93
|
+
// Forward to message handler
|
|
94
|
+
if (this.messageHandler) {
|
|
95
|
+
const externalMessage = {
|
|
96
|
+
chatId,
|
|
97
|
+
transport: this.type,
|
|
98
|
+
content: text,
|
|
99
|
+
username: username,
|
|
100
|
+
userId: userId,
|
|
101
|
+
timestamp: message.createdAt,
|
|
102
|
+
messageId: message.id,
|
|
103
|
+
isGroupChat,
|
|
104
|
+
wasMentioned,
|
|
105
|
+
};
|
|
106
|
+
this.messageHandler(externalMessage);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
// Handle ready event
|
|
110
|
+
this.client.once(discord.Events.ClientReady, (readyClient) => {
|
|
111
|
+
this.botUserId = readyClient.user.id;
|
|
112
|
+
console.log(`✅ Discord logged in as ${readyClient.user.tag} (ID: ${this.botUserId})`);
|
|
113
|
+
this._isConnected = true;
|
|
114
|
+
});
|
|
115
|
+
// Handle errors
|
|
116
|
+
this.client.on(discord.Events.Error, (error) => {
|
|
117
|
+
console.error("[Discord] Error:", error);
|
|
118
|
+
if (this.errorHandler) {
|
|
119
|
+
this.errorHandler(error);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
// Handle disconnection
|
|
123
|
+
this.client.on(discord.Events.ShardDisconnect, () => {
|
|
124
|
+
console.log("[Discord] Disconnected");
|
|
125
|
+
this._isConnected = false;
|
|
126
|
+
});
|
|
127
|
+
try {
|
|
128
|
+
await this.client.login(token);
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw new Error(`Discord login failed: ${error.message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async disconnect() {
|
|
135
|
+
if (this.client) {
|
|
136
|
+
this.client.destroy();
|
|
137
|
+
this.client = null;
|
|
138
|
+
}
|
|
139
|
+
this._isConnected = false;
|
|
140
|
+
console.log("[Discord] Disconnected");
|
|
141
|
+
}
|
|
142
|
+
async sendMessage(chatId, text) {
|
|
143
|
+
if (!this.client) {
|
|
144
|
+
throw new Error("Discord not connected");
|
|
145
|
+
}
|
|
146
|
+
if (!text?.trim())
|
|
147
|
+
return;
|
|
148
|
+
try {
|
|
149
|
+
const channel = await this.client.channels.fetch(chatId);
|
|
150
|
+
if (!channel?.isTextBased()) {
|
|
151
|
+
throw new Error(`Cannot send to channel ${chatId}`);
|
|
152
|
+
}
|
|
153
|
+
// Discord has 2000 char limit - split long messages
|
|
154
|
+
const chunks = this.splitMessage(text, 2000);
|
|
155
|
+
for (const chunk of chunks) {
|
|
156
|
+
if ("send" in channel) {
|
|
157
|
+
await channel.send(chunk);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
throw new Error(`Discord send failed: ${error.message}`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async sendTyping(chatId) {
|
|
166
|
+
if (!this.client) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const channel = await this.client.channels.fetch(chatId);
|
|
171
|
+
if (channel && "sendTyping" in channel) {
|
|
172
|
+
await channel.sendTyping();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
console.warn("[Discord] Failed to send typing:", error);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
onMessage(handler) {
|
|
180
|
+
this.messageHandler = handler;
|
|
181
|
+
}
|
|
182
|
+
onError(handler) {
|
|
183
|
+
this.errorHandler = handler;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Split a message into chunks that fit Discord's 2000 char limit.
|
|
187
|
+
* Tries to split at newlines or spaces when possible.
|
|
188
|
+
*/
|
|
189
|
+
splitMessage(text, limit) {
|
|
190
|
+
if (text.length <= limit) {
|
|
191
|
+
return [text];
|
|
192
|
+
}
|
|
193
|
+
const chunks = [];
|
|
194
|
+
let remaining = text;
|
|
195
|
+
while (remaining.length > 0) {
|
|
196
|
+
if (remaining.length <= limit) {
|
|
197
|
+
chunks.push(remaining);
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
// Try to find a good split point (newline or space)
|
|
201
|
+
let splitAt = limit;
|
|
202
|
+
const newlineIdx = remaining.lastIndexOf("\n", limit);
|
|
203
|
+
const spaceIdx = remaining.lastIndexOf(" ", limit);
|
|
204
|
+
if (newlineIdx > limit * 0.5) {
|
|
205
|
+
splitAt = newlineIdx + 1;
|
|
206
|
+
}
|
|
207
|
+
else if (spaceIdx > limit * 0.5) {
|
|
208
|
+
splitAt = spaceIdx + 1;
|
|
209
|
+
}
|
|
210
|
+
chunks.push(remaining.substring(0, splitAt).trimEnd());
|
|
211
|
+
remaining = remaining.substring(splitAt).trimStart();
|
|
212
|
+
}
|
|
213
|
+
return chunks;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=discord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/transports/discord.ts"],"names":[],"mappings":"AAQA,KAAK,UAAU,aAAa;IAC1B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAC3C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,eAAe;IAUhB;IACA;IAVD,IAAI,GAAG,SAAS,CAAC;IAClB,MAAM,GAAkB,IAAI,CAAC;IAC7B,YAAY,GAAG,KAAK,CAAC;IACrB,SAAS,GAAW,EAAE,CAAC;IACvB,cAAc,CAAsC;IACpD,YAAY,CAA0B;IACtC,sBAAsB,GAAG,EAAE,CAAC;IAEpC,YACU,MAAyB,EACzB,IAAmB;QADnB,WAAM,GAAN,MAAM,CAAmB;QACzB,SAAI,GAAJ,IAAI,CAAe;IAC1B,CAAC;IAEJ,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO;QAE9B,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAE9B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QAChD,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;QAEtC,IAAI,CAAC,MAAM,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;YAC/B,OAAO,EAAE;gBACP,OAAO,CAAC,iBAAiB,CAAC,MAAM;gBAChC,OAAO,CAAC,iBAAiB,CAAC,aAAa;gBACvC,OAAO,CAAC,iBAAiB,CAAC,cAAc;gBACxC,OAAO,CAAC,iBAAiB,CAAC,cAAc,EAAE,8DAA8D;aACzG;YACD,QAAQ,EAAE;gBACR,OAAO,CAAC,QAAQ,CAAC,OAAO;gBACxB,OAAO,CAAC,QAAQ,CAAC,OAAO;aACzB;SACF,CAAC,CAAC;QAEH,2BAA2B;QAC3B,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,EAAE,OAAgB,EAAE,EAAE;YACtE,4BAA4B;YAC5B,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;gBACvB,OAAO;YACT,CAAC;YAED,+CAA+C;YAC/C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrB,OAAO;YACT,CAAC;YAED,gCAAgC;YAChC,IAAI,OAAO,CAAC,EAAE,KAAK,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC/C,OAAO;YACT,CAAC;YACD,IAAI,CAAC,sBAAsB,GAAG,OAAO,CAAC,EAAE,CAAC;YAEzC,yBAAyB;YACzB,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAE7D,2EAA2E;YAC3E,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS;gBACjC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,GAAG,CAAC;oBAChD,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,SAAS,GAAG,CAAC;oBACjD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBAC5C,CAAC,CAAC,KAAK,CAAC;YAEV,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACjC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;YACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;YACzC,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpC,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC;YAE1B,sBAAsB;YACtB,MAAM,iBAAiB,GAAG,KAAK,EAAE,GAAW,EAAE,IAAY,EAAE,EAAE;gBAC5D,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;oBAChB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACtD,IAAI,OAAO,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;wBACjC,MAAO,OAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC;YACH,CAAC,CAAC;YAEF,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CACrD,MAAM,EACN,MAAM,EACN,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,iBAAiB,EACjB,IAAI,CAAC,IAAI,CACV,CAAC;YAEF,kDAAkD;YAClD,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;gBACpE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAChD,IAAI,EACJ,MAAM,EACN,MAAM,EACN,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,EACpD,IAAI,CAAC,IAAI,CACV,CAAC;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;YACH,CAAC;YAED,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,CAAC,qDAAqD;YAC/D,CAAC;YAED,6BAA6B;YAC7B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBACxB,MAAM,eAAe,GAAoB;oBACvC,MAAM;oBACN,SAAS,EAAE,IAAI,CAAC,IAAI;oBACpB,OAAO,EAAE,IAAI;oBACb,QAAQ,EAAE,QAAQ;oBAClB,MAAM,EAAE,MAAM;oBACd,SAAS,EAAE,OAAO,CAAC,SAAS;oBAC5B,SAAS,EAAE,OAAO,CAAC,EAAE;oBACrB,WAAW;oBACX,YAAY;iBACb,CAAC;gBAEF,IAAI,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;YACvC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,qBAAqB;QACrB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,WAAgB,EAAE,EAAE;YAChE,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,GAAG,CAAC,0BAA0B,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;YACtF,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC,CAAC,CAAC;QAEH,gBAAgB;QAChB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,KAAY,EAAE,EAAE;YACpD,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uBAAuB;QACvB,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,EAAE,GAAG,EAAE;YAClD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YACtC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,yBAA0B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,CAAC;QACD,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,IAAY;QAC5C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE;YAAE,OAAO;QAE1B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzD,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;gBAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;YACtD,CAAC;YAED,oDAAoD;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC7C,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,MAAM,IAAI,OAAO,EAAE,CAAC;oBACtB,MAAO,OAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wBAAyB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACzD,IAAI,OAAO,IAAI,YAAY,IAAI,OAAO,EAAE,CAAC;gBACvC,MAAO,OAAe,CAAC,UAAU,EAAE,CAAC;YACtC,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED,SAAS,CAAC,OAA2C;QACnD,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,OAA+B;QACrC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;IAC9B,CAAC;IAED;;;OAGG;IACK,YAAY,CAAC,IAAY,EAAE,KAAa;QAC9C,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,SAAS,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC;gBAC9B,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvB,MAAM;YACR,CAAC;YAED,oDAAoD;YACpD,IAAI,OAAO,GAAG,KAAK,CAAC;YACpB,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAEnD,IAAI,UAAU,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;gBAC7B,OAAO,GAAG,UAAU,GAAG,CAAC,CAAC;YAC3B,CAAC;iBAAM,IAAI,QAAQ,GAAG,KAAK,GAAG,GAAG,EAAE,CAAC;gBAClC,OAAO,GAAG,QAAQ,GAAG,CAAC,CAAC;YACzB,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YACvD,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC;QACvD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ExternalMessage } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Transport provider interface
|
|
4
|
+
* Adapts different messenger platforms (Telegram, WhatsApp, Slack, Discord)
|
|
5
|
+
*/
|
|
6
|
+
export interface ITransportProvider {
|
|
7
|
+
/** Transport type identifier */
|
|
8
|
+
readonly type: string;
|
|
9
|
+
/** Is the transport currently connected? */
|
|
10
|
+
readonly isConnected: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Connect to the messenger service
|
|
13
|
+
* @throws Error if connection fails
|
|
14
|
+
*/
|
|
15
|
+
connect(): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Disconnect from the messenger service
|
|
18
|
+
*/
|
|
19
|
+
disconnect(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Send a text message to a chat
|
|
22
|
+
* @param chatId - Chat/channel identifier
|
|
23
|
+
* @param text - Message content
|
|
24
|
+
*/
|
|
25
|
+
sendMessage(chatId: string, text: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Send typing indicator to a chat
|
|
28
|
+
* @param chatId - Chat/channel identifier
|
|
29
|
+
*/
|
|
30
|
+
sendTyping(chatId: string): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Register callback for incoming messages
|
|
33
|
+
* @param handler - Message handler function
|
|
34
|
+
*/
|
|
35
|
+
onMessage(handler: (message: ExternalMessage) => void): void;
|
|
36
|
+
/**
|
|
37
|
+
* Register callback for errors
|
|
38
|
+
* @param handler - Error handler function
|
|
39
|
+
*/
|
|
40
|
+
onError(handler: (error: Error) => void): void;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/transports/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAE9B;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzB;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1C;;;OAGG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI,CAAC;IAE7D;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;CAChD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/transports/interface.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { ExternalMessage } from "../types.js";
|
|
2
|
+
import type { ITransportProvider } from "./interface.js";
|
|
3
|
+
/**
|
|
4
|
+
* Manages multiple transport providers and routes messages
|
|
5
|
+
*/
|
|
6
|
+
export declare class TransportManager {
|
|
7
|
+
private transports;
|
|
8
|
+
private messageHandler?;
|
|
9
|
+
private errorHandler?;
|
|
10
|
+
/**
|
|
11
|
+
* Register a transport provider
|
|
12
|
+
*/
|
|
13
|
+
addTransport(transport: ITransportProvider): void;
|
|
14
|
+
/**
|
|
15
|
+
* Get a specific transport by type
|
|
16
|
+
*/
|
|
17
|
+
getTransport(type: string): ITransportProvider | undefined;
|
|
18
|
+
/**
|
|
19
|
+
* Get all registered transports
|
|
20
|
+
*/
|
|
21
|
+
getAllTransports(): ITransportProvider[];
|
|
22
|
+
/**
|
|
23
|
+
* Connect all registered transports
|
|
24
|
+
*/
|
|
25
|
+
connectAll(): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Disconnect all transports
|
|
28
|
+
*/
|
|
29
|
+
disconnectAll(): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Send a message to a specific chat via a specific transport
|
|
32
|
+
*/
|
|
33
|
+
sendMessage(chatId: string, transportType: string, text: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Send typing indicator to a chat via a specific transport
|
|
36
|
+
*/
|
|
37
|
+
sendTyping(chatId: string, transportType: string): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Register handler for incoming messages from all transports
|
|
40
|
+
*/
|
|
41
|
+
onMessage(handler: (message: ExternalMessage) => void): void;
|
|
42
|
+
/**
|
|
43
|
+
* Register handler for errors from all transports
|
|
44
|
+
*/
|
|
45
|
+
onError(handler: (error: Error, transport: string) => void): void;
|
|
46
|
+
/**
|
|
47
|
+
* Get connection status for all transports
|
|
48
|
+
*/
|
|
49
|
+
getStatus(): Array<{
|
|
50
|
+
type: string;
|
|
51
|
+
connected: boolean;
|
|
52
|
+
}>;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/transports/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzD;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAyC;IAC3D,OAAO,CAAC,cAAc,CAAC,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAA4C;IAEjE;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,kBAAkB,GAAG,IAAI;IAkBjD;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAI1D;;OAEG;IACH,gBAAgB,IAAI,kBAAkB,EAAE;IAIxC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAOpC;;OAEG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC;IAWhB;;OAEG;IACG,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOtE;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,GAAG,IAAI;IAI5D;;OAEG;IACH,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIjE;;OAEG;IACH,SAAS,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,CAAC;CAMzD"}
|