@producible/cereworker-channels 26.520.1
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/LICENSE +21 -0
- package/dist/adapters/discord.d.ts +21 -0
- package/dist/adapters/discord.d.ts.map +1 -0
- package/dist/adapters/discord.js +183 -0
- package/dist/adapters/discord.js.map +1 -0
- package/dist/adapters/feishu.d.ts +10 -0
- package/dist/adapters/feishu.d.ts.map +1 -0
- package/dist/adapters/feishu.js +114 -0
- package/dist/adapters/feishu.js.map +1 -0
- package/dist/adapters/irc.d.ts +23 -0
- package/dist/adapters/irc.d.ts.map +1 -0
- package/dist/adapters/irc.js +158 -0
- package/dist/adapters/irc.js.map +1 -0
- package/dist/adapters/matrix.d.ts +9 -0
- package/dist/adapters/matrix.d.ts.map +1 -0
- package/dist/adapters/matrix.js +70 -0
- package/dist/adapters/matrix.js.map +1 -0
- package/dist/adapters/signal.d.ts +10 -0
- package/dist/adapters/signal.d.ts.map +1 -0
- package/dist/adapters/signal.js +116 -0
- package/dist/adapters/signal.js.map +1 -0
- package/dist/adapters/slack.d.ts +9 -0
- package/dist/adapters/slack.d.ts.map +1 -0
- package/dist/adapters/slack.js +75 -0
- package/dist/adapters/slack.js.map +1 -0
- package/dist/adapters/telegram.d.ts +7 -0
- package/dist/adapters/telegram.d.ts.map +1 -0
- package/dist/adapters/telegram.js +92 -0
- package/dist/adapters/telegram.js.map +1 -0
- package/dist/adapters/wechat.d.ts +8 -0
- package/dist/adapters/wechat.d.ts.map +1 -0
- package/dist/adapters/wechat.js +107 -0
- package/dist/adapters/wechat.js.map +1 -0
- package/dist/adapters/whatsapp.d.ts +7 -0
- package/dist/adapters/whatsapp.d.ts.map +1 -0
- package/dist/adapters/whatsapp.js +102 -0
- package/dist/adapters/whatsapp.js.map +1 -0
- package/dist/chunking.d.ts +18 -0
- package/dist/chunking.d.ts.map +1 -0
- package/dist/chunking.js +137 -0
- package/dist/chunking.js.map +1 -0
- package/dist/factory.d.ts +5 -0
- package/dist/factory.d.ts.map +1 -0
- package/dist/factory.js +86 -0
- package/dist/factory.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/manager.d.ts +34 -0
- package/dist/manager.d.ts.map +1 -0
- package/dist/manager.js +97 -0
- package/dist/manager.js.map +1 -0
- package/dist/types.d.ts +49 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import sdk from 'matrix-js-sdk';
|
|
2
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
3
|
+
export function createMatrixChannel(config) {
|
|
4
|
+
let client = null;
|
|
5
|
+
let connected = false;
|
|
6
|
+
return {
|
|
7
|
+
id: 'matrix',
|
|
8
|
+
meta: { name: 'Matrix', emoji: 'M' },
|
|
9
|
+
async start(handler) {
|
|
10
|
+
client = sdk.createClient({
|
|
11
|
+
baseUrl: config.homeserver,
|
|
12
|
+
accessToken: config.token,
|
|
13
|
+
userId: config.userId,
|
|
14
|
+
});
|
|
15
|
+
client.on(sdk.RoomEvent.Timeline, async (event, room) => {
|
|
16
|
+
if (!room)
|
|
17
|
+
return;
|
|
18
|
+
if (event.getType() !== 'm.room.message')
|
|
19
|
+
return;
|
|
20
|
+
if (event.getSender() === config.userId)
|
|
21
|
+
return; // ignore own messages
|
|
22
|
+
const content = event.getContent();
|
|
23
|
+
if (content.msgtype !== 'm.text')
|
|
24
|
+
return;
|
|
25
|
+
const senderId = event.getSender() ?? '';
|
|
26
|
+
const inbound = {
|
|
27
|
+
channelId: 'matrix',
|
|
28
|
+
routeTo: room.roomId,
|
|
29
|
+
senderId,
|
|
30
|
+
text: content.body ?? '',
|
|
31
|
+
sessionId: `room:${room.roomId}`,
|
|
32
|
+
threadId: room.roomId,
|
|
33
|
+
timestamp: event.getTs(),
|
|
34
|
+
};
|
|
35
|
+
const response = await handler(inbound);
|
|
36
|
+
if (response) {
|
|
37
|
+
const chunks = chunkMarkdown(response, CHANNEL_LIMITS.matrix);
|
|
38
|
+
for (const chunk of chunks) {
|
|
39
|
+
await client.sendTextMessage(room.roomId, chunk);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
await client.startClient({ initialSyncLimit: 0 });
|
|
44
|
+
connected = true;
|
|
45
|
+
},
|
|
46
|
+
async stop() {
|
|
47
|
+
if (client) {
|
|
48
|
+
client.stopClient();
|
|
49
|
+
connected = false;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
async send(msg) {
|
|
53
|
+
if (!client)
|
|
54
|
+
throw new Error('Matrix not started');
|
|
55
|
+
const chunks = chunkMarkdown(msg.text, CHANNEL_LIMITS.matrix);
|
|
56
|
+
for (const chunk of chunks) {
|
|
57
|
+
await client.sendTextMessage(msg.to, chunk);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
isAllowed(senderId) {
|
|
61
|
+
if (config.allowFrom.length === 0)
|
|
62
|
+
return true;
|
|
63
|
+
return config.allowFrom.includes(senderId);
|
|
64
|
+
},
|
|
65
|
+
isConnected() {
|
|
66
|
+
return connected;
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=matrix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.js","sourceRoot":"","sources":["../../src/adapters/matrix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ChannelPlugin, InboundMessage } from '../types.js';
|
|
2
|
+
/** Parse a signal-cli envelope into an InboundMessage, or null if not a text message. */
|
|
3
|
+
export declare function parseSignalEnvelope(raw: unknown): InboundMessage | null;
|
|
4
|
+
export interface SignalChannelConfig {
|
|
5
|
+
account: string;
|
|
6
|
+
signalCliUrl: string;
|
|
7
|
+
allowFrom: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function createSignalChannel(config: SignalChannelConfig): ChannelPlugin;
|
|
10
|
+
//# sourceMappingURL=signal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.d.ts","sourceRoot":"","sources":["../../src/adapters/signal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAmC,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlG,yFAAyF;AACzF,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAmBvE;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAiG9E"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
2
|
+
/** Parse a signal-cli envelope into an InboundMessage, or null if not a text message. */
|
|
3
|
+
export function parseSignalEnvelope(raw) {
|
|
4
|
+
const envelope = raw.envelope;
|
|
5
|
+
if (!envelope)
|
|
6
|
+
return null;
|
|
7
|
+
const dataMessage = envelope.dataMessage;
|
|
8
|
+
if (!dataMessage?.message)
|
|
9
|
+
return null;
|
|
10
|
+
const source = String(envelope.source ?? '');
|
|
11
|
+
const groupId = dataMessage.groupInfo?.groupId;
|
|
12
|
+
return {
|
|
13
|
+
channelId: 'signal',
|
|
14
|
+
routeTo: groupId ?? source,
|
|
15
|
+
senderId: source,
|
|
16
|
+
text: dataMessage.message,
|
|
17
|
+
sessionId: groupId ? `group:${groupId}` : `dm:${source}`,
|
|
18
|
+
timestamp: Number(envelope.timestamp ?? Date.now()),
|
|
19
|
+
raw,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function createSignalChannel(config) {
|
|
23
|
+
let connected = false;
|
|
24
|
+
let polling = false;
|
|
25
|
+
let pollTimer = null;
|
|
26
|
+
const limit = CHANNEL_LIMITS.signal;
|
|
27
|
+
const baseUrl = config.signalCliUrl.replace(/\/+$/, '');
|
|
28
|
+
async function receive() {
|
|
29
|
+
const url = `${baseUrl}/v1/receive/${encodeURIComponent(config.account)}`;
|
|
30
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(30_000) });
|
|
31
|
+
if (!res.ok)
|
|
32
|
+
throw new Error(`Signal receive: ${res.status}`);
|
|
33
|
+
return (await res.json());
|
|
34
|
+
}
|
|
35
|
+
async function sendMessage(to, text) {
|
|
36
|
+
const res = await fetch(`${baseUrl}/v2/send`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: { 'Content-Type': 'application/json' },
|
|
39
|
+
body: JSON.stringify({
|
|
40
|
+
message: text,
|
|
41
|
+
number: config.account,
|
|
42
|
+
recipients: [to],
|
|
43
|
+
}),
|
|
44
|
+
});
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
throw new Error(`Signal send: ${res.status}`);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
id: 'signal',
|
|
50
|
+
meta: { name: 'Signal', emoji: 'S' },
|
|
51
|
+
async start(handler) {
|
|
52
|
+
// Verify connectivity
|
|
53
|
+
try {
|
|
54
|
+
const res = await fetch(`${baseUrl}/v1/about`, { signal: AbortSignal.timeout(5_000) });
|
|
55
|
+
if (!res.ok)
|
|
56
|
+
throw new Error(`Signal CLI not reachable: ${res.status}`);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
throw new Error(`Cannot connect to signal-cli at ${baseUrl}: ${err instanceof Error ? err.message : String(err)}`);
|
|
60
|
+
}
|
|
61
|
+
connected = true;
|
|
62
|
+
polling = true;
|
|
63
|
+
const poll = async () => {
|
|
64
|
+
if (!polling)
|
|
65
|
+
return;
|
|
66
|
+
try {
|
|
67
|
+
const messages = await receive();
|
|
68
|
+
for (const raw of messages) {
|
|
69
|
+
const inbound = parseSignalEnvelope(raw);
|
|
70
|
+
if (!inbound)
|
|
71
|
+
continue;
|
|
72
|
+
const response = await handler(inbound);
|
|
73
|
+
if (response) {
|
|
74
|
+
const groupId = (raw.envelope?.dataMessage?.groupInfo?.groupId);
|
|
75
|
+
const to = groupId ?? inbound.senderId;
|
|
76
|
+
const chunks = chunkMarkdown(response, limit);
|
|
77
|
+
for (const chunk of chunks) {
|
|
78
|
+
await sendMessage(to, chunk);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Poll failure is non-fatal — retry on next tick
|
|
85
|
+
}
|
|
86
|
+
if (polling) {
|
|
87
|
+
pollTimer = setTimeout(poll, 1000);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
void poll();
|
|
91
|
+
},
|
|
92
|
+
async stop() {
|
|
93
|
+
polling = false;
|
|
94
|
+
connected = false;
|
|
95
|
+
if (pollTimer) {
|
|
96
|
+
clearTimeout(pollTimer);
|
|
97
|
+
pollTimer = null;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
async send(msg) {
|
|
101
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
102
|
+
for (const chunk of chunks) {
|
|
103
|
+
await sendMessage(msg.to, chunk);
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
isAllowed(senderId) {
|
|
107
|
+
if (config.allowFrom.length === 0)
|
|
108
|
+
return true;
|
|
109
|
+
return config.allowFrom.includes(senderId);
|
|
110
|
+
},
|
|
111
|
+
isConnected() {
|
|
112
|
+
return connected;
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=signal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signal.js","sourceRoot":"","sources":["../../src/adapters/signal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
export interface SlackChannelConfig {
|
|
3
|
+
botToken: string;
|
|
4
|
+
appToken: string;
|
|
5
|
+
signingSecret?: string;
|
|
6
|
+
allowFrom: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function createSlackChannel(config: SlackChannelConfig): ChannelPlugin;
|
|
9
|
+
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../src/adapters/slack.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,GAAG,aAAa,CA6E5E"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { App as SlackApp } from '@slack/bolt';
|
|
2
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
3
|
+
export function createSlackChannel(config) {
|
|
4
|
+
let app = null;
|
|
5
|
+
let connected = false;
|
|
6
|
+
const limit = CHANNEL_LIMITS.slack;
|
|
7
|
+
return {
|
|
8
|
+
id: 'slack',
|
|
9
|
+
meta: { name: 'Slack', emoji: '#' },
|
|
10
|
+
async start(handler) {
|
|
11
|
+
app = new SlackApp({
|
|
12
|
+
token: config.botToken,
|
|
13
|
+
appToken: config.appToken,
|
|
14
|
+
socketMode: true,
|
|
15
|
+
...(config.signingSecret ? { signingSecret: config.signingSecret } : {}),
|
|
16
|
+
});
|
|
17
|
+
app.message(async ({ message, say }) => {
|
|
18
|
+
if (message.subtype)
|
|
19
|
+
return; // skip bot messages, edits, etc.
|
|
20
|
+
if (!('text' in message) || !message.text)
|
|
21
|
+
return;
|
|
22
|
+
const inbound = {
|
|
23
|
+
channelId: 'slack',
|
|
24
|
+
routeTo: message.channel,
|
|
25
|
+
senderId: ('user' in message ? message.user : '') ?? '',
|
|
26
|
+
text: message.text,
|
|
27
|
+
sessionId: ('thread_ts' in message && message.thread_ts)
|
|
28
|
+
? `thread:${message.thread_ts}`
|
|
29
|
+
: `channel:${message.channel}`,
|
|
30
|
+
threadId: ('thread_ts' in message ? message.thread_ts : undefined),
|
|
31
|
+
timestamp: parseFloat(message.ts) * 1000,
|
|
32
|
+
};
|
|
33
|
+
const response = await handler(inbound);
|
|
34
|
+
if (response) {
|
|
35
|
+
const chunks = chunkMarkdown(response, limit);
|
|
36
|
+
for (const chunk of chunks) {
|
|
37
|
+
await say({
|
|
38
|
+
text: chunk,
|
|
39
|
+
thread_ts: inbound.threadId ?? message.ts,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
await app.start();
|
|
45
|
+
connected = true;
|
|
46
|
+
},
|
|
47
|
+
async stop() {
|
|
48
|
+
if (app) {
|
|
49
|
+
await app.stop();
|
|
50
|
+
connected = false;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
async send(msg) {
|
|
54
|
+
if (!app)
|
|
55
|
+
throw new Error('Slack not started');
|
|
56
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
57
|
+
for (const chunk of chunks) {
|
|
58
|
+
await app.client.chat.postMessage({
|
|
59
|
+
channel: msg.to,
|
|
60
|
+
text: chunk,
|
|
61
|
+
thread_ts: msg.threadId,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
isAllowed(senderId) {
|
|
66
|
+
if (config.allowFrom.length === 0)
|
|
67
|
+
return true;
|
|
68
|
+
return config.allowFrom.includes(senderId);
|
|
69
|
+
},
|
|
70
|
+
isConnected() {
|
|
71
|
+
return connected;
|
|
72
|
+
},
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=slack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/adapters/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
export interface TelegramChannelConfig {
|
|
3
|
+
token: string;
|
|
4
|
+
allowFrom: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function createTelegramChannel(config: TelegramChannelConfig): ChannelPlugin;
|
|
7
|
+
//# sourceMappingURL=telegram.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/adapters/telegram.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,aAAa,CAiGlF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Telegraf } from 'telegraf';
|
|
2
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
3
|
+
export function createTelegramChannel(config) {
|
|
4
|
+
let bot = null;
|
|
5
|
+
let connected = false;
|
|
6
|
+
const limit = CHANNEL_LIMITS.telegram;
|
|
7
|
+
return {
|
|
8
|
+
id: 'telegram',
|
|
9
|
+
meta: { name: 'Telegram', emoji: 'T' },
|
|
10
|
+
async start(handler) {
|
|
11
|
+
bot = new Telegraf(config.token);
|
|
12
|
+
bot.on('text', async (ctx) => {
|
|
13
|
+
const message = ctx.message;
|
|
14
|
+
if (!message || !('text' in message))
|
|
15
|
+
return;
|
|
16
|
+
const senderId = String(message.from?.id ?? '');
|
|
17
|
+
const inbound = {
|
|
18
|
+
channelId: 'telegram',
|
|
19
|
+
routeTo: String(message.chat.id),
|
|
20
|
+
senderId,
|
|
21
|
+
senderName: message.from?.username ?? message.from?.first_name,
|
|
22
|
+
text: message.text,
|
|
23
|
+
sessionId: message.message_thread_id
|
|
24
|
+
? `thread:${message.message_thread_id}`
|
|
25
|
+
: `chat:${message.chat.id}`,
|
|
26
|
+
threadId: message.message_thread_id ? String(message.message_thread_id) : undefined,
|
|
27
|
+
replyToId: message.reply_to_message ? String(message.reply_to_message.message_id) : undefined,
|
|
28
|
+
timestamp: message.date * 1000,
|
|
29
|
+
};
|
|
30
|
+
const response = await handler(inbound);
|
|
31
|
+
if (response) {
|
|
32
|
+
const chunks = chunkMarkdown(response, limit);
|
|
33
|
+
for (const chunk of chunks) {
|
|
34
|
+
await ctx.reply(chunk, {
|
|
35
|
+
reply_parameters: { message_id: message.message_id },
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
// Register slash commands with Telegram for autocomplete
|
|
41
|
+
await bot.telegram.setMyCommands([
|
|
42
|
+
{ command: 'help', description: 'Show help' },
|
|
43
|
+
{ command: 'model', description: 'Show or switch model' },
|
|
44
|
+
{ command: 'provider', description: 'Show or switch provider' },
|
|
45
|
+
{ command: 'config', description: 'Show config' },
|
|
46
|
+
{ command: 'auto', description: 'Toggle auto mode' },
|
|
47
|
+
{ command: 'memory', description: 'Show memory' },
|
|
48
|
+
{ command: 'skills', description: 'List skills' },
|
|
49
|
+
{ command: 'agents', description: 'List sub-agents' },
|
|
50
|
+
{ command: 'channels', description: 'List channels' },
|
|
51
|
+
{ command: 'nodes', description: 'Gateway nodes' },
|
|
52
|
+
{ command: 'finetune', description: 'Fine-tune controls' },
|
|
53
|
+
{ command: 'task', description: 'Run or list tasks' },
|
|
54
|
+
{ command: 'conversations', description: 'List conversations' },
|
|
55
|
+
{ command: 'stop', description: 'Emergency stop' },
|
|
56
|
+
]).catch(() => { });
|
|
57
|
+
// Use polling (simpler than webhooks for dev)
|
|
58
|
+
await bot.launch();
|
|
59
|
+
connected = true;
|
|
60
|
+
// Graceful shutdown
|
|
61
|
+
process.once('SIGINT', () => bot?.stop('SIGINT'));
|
|
62
|
+
process.once('SIGTERM', () => bot?.stop('SIGTERM'));
|
|
63
|
+
},
|
|
64
|
+
async stop() {
|
|
65
|
+
if (bot) {
|
|
66
|
+
bot.stop();
|
|
67
|
+
connected = false;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
async send(msg) {
|
|
71
|
+
if (!bot)
|
|
72
|
+
throw new Error('Telegram not started');
|
|
73
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
74
|
+
for (const chunk of chunks) {
|
|
75
|
+
await bot.telegram.sendMessage(msg.to, chunk, {
|
|
76
|
+
reply_parameters: msg.replyToId
|
|
77
|
+
? { message_id: parseInt(msg.replyToId, 10) }
|
|
78
|
+
: undefined,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
isAllowed(senderId) {
|
|
83
|
+
if (config.allowFrom.length === 0)
|
|
84
|
+
return true;
|
|
85
|
+
return config.allowFrom.includes(senderId);
|
|
86
|
+
},
|
|
87
|
+
isConnected() {
|
|
88
|
+
return connected;
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/adapters/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
export interface WeChatChannelConfig {
|
|
3
|
+
puppet: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
allowFrom: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function createWeChatChannel(config: WeChatChannelConfig): ChannelPlugin;
|
|
8
|
+
//# sourceMappingURL=wechat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wechat.d.ts","sourceRoot":"","sources":["../../src/adapters/wechat.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAuH9E"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
2
|
+
export function createWeChatChannel(config) {
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
let bot = null;
|
|
5
|
+
let connected = false;
|
|
6
|
+
const limit = CHANNEL_LIMITS.wechat;
|
|
7
|
+
return {
|
|
8
|
+
id: 'wechat',
|
|
9
|
+
meta: { name: 'WeChat', emoji: 'W' },
|
|
10
|
+
async start(handler) {
|
|
11
|
+
const mod = 'wechaty';
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
13
|
+
const wechaty = await import(mod).catch(() => null);
|
|
14
|
+
if (!wechaty) {
|
|
15
|
+
throw new Error('WeChat requires the wechaty package. Install it:\n npm install -g wechaty wechaty-puppet-wechat4u');
|
|
16
|
+
}
|
|
17
|
+
bot = wechaty.WechatyBuilder.build({
|
|
18
|
+
name: 'cereworker',
|
|
19
|
+
puppet: config.puppet,
|
|
20
|
+
puppetOptions: config.token ? { token: config.token } : undefined,
|
|
21
|
+
});
|
|
22
|
+
bot.on('message', async (message) => {
|
|
23
|
+
if (message.self())
|
|
24
|
+
return;
|
|
25
|
+
if (message.type() !== bot.Message.Type.Text)
|
|
26
|
+
return;
|
|
27
|
+
const text = message.text();
|
|
28
|
+
if (!text)
|
|
29
|
+
return;
|
|
30
|
+
const talker = message.talker();
|
|
31
|
+
const senderId = talker.id;
|
|
32
|
+
const room = message.room();
|
|
33
|
+
const inbound = {
|
|
34
|
+
channelId: 'wechat',
|
|
35
|
+
routeTo: room ? room.id : talker.id,
|
|
36
|
+
senderId,
|
|
37
|
+
senderName: talker.name(),
|
|
38
|
+
text,
|
|
39
|
+
sessionId: room ? `room:${room.id}` : `dm:${talker.id}`,
|
|
40
|
+
threadId: room ? room.id : undefined,
|
|
41
|
+
timestamp: message.date().getTime(),
|
|
42
|
+
};
|
|
43
|
+
const response = await handler(inbound);
|
|
44
|
+
if (response) {
|
|
45
|
+
const chunks = chunkMarkdown(response, limit);
|
|
46
|
+
for (const chunk of chunks) {
|
|
47
|
+
if (room) {
|
|
48
|
+
await room.say(chunk);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
await talker.say(chunk);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
bot.on('login', (user) => {
|
|
57
|
+
console.log(`[WeChat] Logged in as ${user.name()}`);
|
|
58
|
+
connected = true;
|
|
59
|
+
});
|
|
60
|
+
bot.on('logout', () => {
|
|
61
|
+
console.log('[WeChat] Logged out');
|
|
62
|
+
connected = false;
|
|
63
|
+
});
|
|
64
|
+
bot.on('error', (error) => {
|
|
65
|
+
console.error('[WeChat] Error:', error);
|
|
66
|
+
});
|
|
67
|
+
await bot.start();
|
|
68
|
+
},
|
|
69
|
+
async stop() {
|
|
70
|
+
if (bot) {
|
|
71
|
+
await bot.stop();
|
|
72
|
+
connected = false;
|
|
73
|
+
bot = null;
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
async send(msg) {
|
|
77
|
+
if (!bot)
|
|
78
|
+
throw new Error('WeChat not started');
|
|
79
|
+
const contact = await bot.Contact.find({ id: msg.to });
|
|
80
|
+
if (contact) {
|
|
81
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
82
|
+
for (const chunk of chunks) {
|
|
83
|
+
await contact.say(chunk);
|
|
84
|
+
}
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const room = await bot.Room.find({ id: msg.to });
|
|
88
|
+
if (room) {
|
|
89
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
90
|
+
for (const chunk of chunks) {
|
|
91
|
+
await room.say(chunk);
|
|
92
|
+
}
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
throw new Error(`WeChat contact/room not found: ${msg.to}`);
|
|
96
|
+
},
|
|
97
|
+
isAllowed(senderId) {
|
|
98
|
+
if (config.allowFrom.length === 0)
|
|
99
|
+
return true;
|
|
100
|
+
return config.allowFrom.includes(senderId);
|
|
101
|
+
},
|
|
102
|
+
isConnected() {
|
|
103
|
+
return connected;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=wechat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wechat.js","sourceRoot":"","sources":["../../src/adapters/wechat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
export interface WhatsAppChannelConfig {
|
|
3
|
+
allowFrom: string[];
|
|
4
|
+
authDir?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function createWhatsAppChannel(config: WhatsAppChannelConfig): ChannelPlugin;
|
|
7
|
+
//# sourceMappingURL=whatsapp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../src/adapters/whatsapp.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,qBAAqB,GAAG,aAAa,CA2GlF"}
|