@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
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Producible
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { GatewayIntentBits, Partials } from 'discord.js';
|
|
2
|
+
import type { ChannelPlugin, CommandDef } from '../types.js';
|
|
3
|
+
export interface DiscordChannelConfig {
|
|
4
|
+
token: string;
|
|
5
|
+
applicationId?: string;
|
|
6
|
+
allowFrom: string[];
|
|
7
|
+
channelIds: string[];
|
|
8
|
+
commands?: CommandDef[];
|
|
9
|
+
}
|
|
10
|
+
export declare function getDiscordClientOptions(): {
|
|
11
|
+
intents: GatewayIntentBits[];
|
|
12
|
+
partials: Partials[];
|
|
13
|
+
};
|
|
14
|
+
export declare function shouldHandleDiscordMessage(params: {
|
|
15
|
+
isDM: boolean;
|
|
16
|
+
isMentioned: boolean;
|
|
17
|
+
routeIds: string[];
|
|
18
|
+
channelIds: string[];
|
|
19
|
+
}): boolean;
|
|
20
|
+
export declare function createDiscordChannel(config: DiscordChannelConfig): ChannelPlugin;
|
|
21
|
+
//# sourceMappingURL=discord.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.d.ts","sourceRoot":"","sources":["../../src/adapters/discord.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EAEjB,QAAQ,EAMT,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,aAAa,EAAmD,UAAU,EAAE,MAAM,aAAa,CAAC;AAG9G,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;CACzB;AAED,wBAAgB,uBAAuB;;;EAUtC;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB,GAAG,OAAO,CAKV;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,aAAa,CAmLhF"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { Client, GatewayIntentBits, Events, Partials, REST, Routes, SlashCommandBuilder, } from 'discord.js';
|
|
2
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
3
|
+
export function getDiscordClientOptions() {
|
|
4
|
+
return {
|
|
5
|
+
intents: [
|
|
6
|
+
GatewayIntentBits.Guilds,
|
|
7
|
+
GatewayIntentBits.GuildMessages,
|
|
8
|
+
GatewayIntentBits.MessageContent,
|
|
9
|
+
GatewayIntentBits.DirectMessages,
|
|
10
|
+
],
|
|
11
|
+
partials: [Partials.Channel],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export function shouldHandleDiscordMessage(params) {
|
|
15
|
+
if (params.isDM)
|
|
16
|
+
return true;
|
|
17
|
+
if (params.isMentioned)
|
|
18
|
+
return true;
|
|
19
|
+
if (params.channelIds.length === 0)
|
|
20
|
+
return false;
|
|
21
|
+
return params.routeIds.some((id) => params.channelIds.includes(id));
|
|
22
|
+
}
|
|
23
|
+
export function createDiscordChannel(config) {
|
|
24
|
+
let client = null;
|
|
25
|
+
let connected = false;
|
|
26
|
+
const limit = CHANNEL_LIMITS.discord;
|
|
27
|
+
async function registerSlashCommands() {
|
|
28
|
+
if (!config.applicationId || !config.commands?.length)
|
|
29
|
+
return;
|
|
30
|
+
try {
|
|
31
|
+
const rest = new REST({ version: '10' }).setToken(config.token);
|
|
32
|
+
const commands = config.commands.map((cmd) => {
|
|
33
|
+
const builder = new SlashCommandBuilder()
|
|
34
|
+
.setName(cmd.name)
|
|
35
|
+
.setDescription(cmd.description);
|
|
36
|
+
if (cmd.hasArgs) {
|
|
37
|
+
builder.addStringOption((opt) => opt.setName('args').setDescription('Arguments').setRequired(false));
|
|
38
|
+
}
|
|
39
|
+
return builder.toJSON();
|
|
40
|
+
});
|
|
41
|
+
await rest.put(Routes.applicationCommands(config.applicationId), { body: commands });
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Non-critical — bot works without slash commands
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
id: 'discord',
|
|
49
|
+
meta: { name: 'Discord', emoji: 'D' },
|
|
50
|
+
async start(handler) {
|
|
51
|
+
client = new Client(getDiscordClientOptions());
|
|
52
|
+
client.on(Events.MessageCreate, async (message) => {
|
|
53
|
+
// Ignore bot's own messages
|
|
54
|
+
if (message.author.bot)
|
|
55
|
+
return;
|
|
56
|
+
// Reply in DMs, on mentions, or in explicitly configured server channels.
|
|
57
|
+
const isDM = !message.inGuild();
|
|
58
|
+
const isMentioned = client?.user && message.mentions.has(client.user);
|
|
59
|
+
const routeIds = [message.channelId];
|
|
60
|
+
if (message.channel.isThread() && message.channel.parentId) {
|
|
61
|
+
routeIds.push(message.channel.parentId);
|
|
62
|
+
}
|
|
63
|
+
if (!shouldHandleDiscordMessage({ isDM, isMentioned: Boolean(isMentioned), routeIds, channelIds: config.channelIds })) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
// Strip mention from text
|
|
67
|
+
let text = message.content;
|
|
68
|
+
if (client?.user) {
|
|
69
|
+
text = text.replace(new RegExp(`<@!?${client.user.id}>`, 'g'), '').trim();
|
|
70
|
+
}
|
|
71
|
+
if (!text)
|
|
72
|
+
return;
|
|
73
|
+
const inbound = {
|
|
74
|
+
channelId: 'discord',
|
|
75
|
+
routeTo: message.channelId,
|
|
76
|
+
senderId: message.author.id,
|
|
77
|
+
senderName: message.author.username,
|
|
78
|
+
text,
|
|
79
|
+
sessionId: isDM
|
|
80
|
+
? `dm:${message.channelId}`
|
|
81
|
+
: message.channel.isThread()
|
|
82
|
+
? `thread:${message.channel.id}`
|
|
83
|
+
: `channel:${message.channelId}`,
|
|
84
|
+
threadId: message.channel.isThread() ? message.channel.id : undefined,
|
|
85
|
+
timestamp: message.createdTimestamp,
|
|
86
|
+
};
|
|
87
|
+
const response = await handler(inbound);
|
|
88
|
+
if (response) {
|
|
89
|
+
const chunks = chunkMarkdown(response, limit);
|
|
90
|
+
for (const chunk of chunks) {
|
|
91
|
+
await message.reply(chunk);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Handle slash command interactions
|
|
96
|
+
client.on(Events.InteractionCreate, async (interaction) => {
|
|
97
|
+
if (!interaction.isChatInputCommand())
|
|
98
|
+
return;
|
|
99
|
+
const cmd = interaction;
|
|
100
|
+
if (!this.isAllowed(cmd.user.id)) {
|
|
101
|
+
await cmd.reply({ content: 'Not authorized.', ephemeral: true });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
// Enforce same channel routing as text messages:
|
|
105
|
+
// DMs always allowed; guild messages require mention OR configured channel
|
|
106
|
+
const isDM = !cmd.inGuild();
|
|
107
|
+
const isThread = cmd.channel?.isThread?.() ?? false;
|
|
108
|
+
const parentId = isThread ? cmd.channel.parentId ?? '' : '';
|
|
109
|
+
if (!isDM) {
|
|
110
|
+
const routeIds = [cmd.channelId ?? ''];
|
|
111
|
+
if (parentId)
|
|
112
|
+
routeIds.push(parentId);
|
|
113
|
+
if (!shouldHandleDiscordMessage({ isDM: false, isMentioned: false, routeIds, channelIds: config.channelIds })) {
|
|
114
|
+
await cmd.reply({ content: 'Not available in this channel.', ephemeral: true });
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Read arguments for commands that accept them
|
|
119
|
+
const args = cmd.options.getString('args') ?? '';
|
|
120
|
+
const text = args ? `/${cmd.commandName} ${args}` : `/${cmd.commandName}`;
|
|
121
|
+
// Match session IDs with text message logic
|
|
122
|
+
const sessionId = isDM
|
|
123
|
+
? `dm:${cmd.channelId}`
|
|
124
|
+
: isThread
|
|
125
|
+
? `thread:${cmd.channelId}`
|
|
126
|
+
: `channel:${cmd.channelId}`;
|
|
127
|
+
const inbound = {
|
|
128
|
+
channelId: 'discord',
|
|
129
|
+
routeTo: cmd.channelId ?? undefined,
|
|
130
|
+
senderId: cmd.user.id,
|
|
131
|
+
senderName: cmd.user.username,
|
|
132
|
+
text,
|
|
133
|
+
sessionId,
|
|
134
|
+
threadId: isThread ? cmd.channelId ?? undefined : undefined,
|
|
135
|
+
timestamp: cmd.createdTimestamp,
|
|
136
|
+
};
|
|
137
|
+
// All slash command replies are ephemeral (only visible to invoking user)
|
|
138
|
+
await cmd.deferReply({ ephemeral: true });
|
|
139
|
+
const response = await handler(inbound);
|
|
140
|
+
if (response) {
|
|
141
|
+
const chunks = chunkMarkdown(response, limit);
|
|
142
|
+
await cmd.editReply(chunks[0]);
|
|
143
|
+
for (let i = 1; i < chunks.length; i++) {
|
|
144
|
+
await cmd.followUp({ content: chunks[i], ephemeral: true });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
await cmd.editReply('Done.');
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
await client.login(config.token);
|
|
152
|
+
connected = true;
|
|
153
|
+
// Register slash commands after login
|
|
154
|
+
await registerSlashCommands();
|
|
155
|
+
},
|
|
156
|
+
async stop() {
|
|
157
|
+
if (client) {
|
|
158
|
+
await client.destroy();
|
|
159
|
+
connected = false;
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
async send(msg) {
|
|
163
|
+
if (!client)
|
|
164
|
+
throw new Error('Discord not started');
|
|
165
|
+
const channel = await client.channels.fetch(msg.to);
|
|
166
|
+
if (channel && 'send' in channel) {
|
|
167
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
168
|
+
for (const chunk of chunks) {
|
|
169
|
+
await channel.send(chunk);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
isAllowed(senderId) {
|
|
174
|
+
if (config.allowFrom.length === 0)
|
|
175
|
+
return true;
|
|
176
|
+
return config.allowFrom.includes(senderId);
|
|
177
|
+
},
|
|
178
|
+
isConnected() {
|
|
179
|
+
return connected;
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=discord.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/adapters/discord.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
export interface FeishuChannelConfig {
|
|
3
|
+
appId: string;
|
|
4
|
+
appSecret: string;
|
|
5
|
+
verificationToken?: string;
|
|
6
|
+
encryptKey?: string;
|
|
7
|
+
allowFrom: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare function createFeishuChannel(config: FeishuChannelConfig): ChannelPlugin;
|
|
10
|
+
//# sourceMappingURL=feishu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu.d.ts","sourceRoot":"","sources":["../../src/adapters/feishu.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAyH9E"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import * as lark from '@larksuiteoapi/node-sdk';
|
|
2
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
3
|
+
export function createFeishuChannel(config) {
|
|
4
|
+
let client = null;
|
|
5
|
+
let eventDispatcher = null;
|
|
6
|
+
let wsClient = null;
|
|
7
|
+
let connected = false;
|
|
8
|
+
let messageHandler = null;
|
|
9
|
+
return {
|
|
10
|
+
id: 'feishu',
|
|
11
|
+
meta: { name: 'Feishu', emoji: 'F' },
|
|
12
|
+
async start(handler) {
|
|
13
|
+
messageHandler = handler;
|
|
14
|
+
client = new lark.Client({
|
|
15
|
+
appId: config.appId,
|
|
16
|
+
appSecret: config.appSecret,
|
|
17
|
+
appType: lark.AppType.SelfBuild,
|
|
18
|
+
});
|
|
19
|
+
eventDispatcher = new lark.EventDispatcher({
|
|
20
|
+
verificationToken: config.verificationToken,
|
|
21
|
+
encryptKey: config.encryptKey,
|
|
22
|
+
});
|
|
23
|
+
// Listen for messages
|
|
24
|
+
eventDispatcher.register({
|
|
25
|
+
'im.message.receive_v1': async (data) => {
|
|
26
|
+
if (!messageHandler)
|
|
27
|
+
return;
|
|
28
|
+
const message = data.message;
|
|
29
|
+
if (!message)
|
|
30
|
+
return;
|
|
31
|
+
const msgType = message.message_type;
|
|
32
|
+
if (msgType !== 'text')
|
|
33
|
+
return;
|
|
34
|
+
let text = '';
|
|
35
|
+
try {
|
|
36
|
+
const content = JSON.parse(message.content);
|
|
37
|
+
text = content.text ?? '';
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!text)
|
|
43
|
+
return;
|
|
44
|
+
const sender = data.sender;
|
|
45
|
+
const senderId = sender?.sender_id?.open_id ?? '';
|
|
46
|
+
const inbound = {
|
|
47
|
+
channelId: 'feishu',
|
|
48
|
+
routeTo: message.chat_id,
|
|
49
|
+
senderId,
|
|
50
|
+
text,
|
|
51
|
+
sessionId: message.root_id
|
|
52
|
+
? `thread:${message.root_id}`
|
|
53
|
+
: `chat:${message.chat_id}`,
|
|
54
|
+
threadId: message.root_id,
|
|
55
|
+
timestamp: Number(message.create_time ?? Date.now()),
|
|
56
|
+
};
|
|
57
|
+
const response = await messageHandler(inbound);
|
|
58
|
+
if (response && client) {
|
|
59
|
+
const chatId = message.chat_id;
|
|
60
|
+
const chunks = chunkMarkdown(response, CHANNEL_LIMITS.feishu);
|
|
61
|
+
for (const chunk of chunks) {
|
|
62
|
+
await client.im.message.create({
|
|
63
|
+
params: { receive_id_type: 'chat_id' },
|
|
64
|
+
data: {
|
|
65
|
+
receive_id: chatId,
|
|
66
|
+
msg_type: 'text',
|
|
67
|
+
content: JSON.stringify({ text: chunk }),
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
});
|
|
74
|
+
// Use WebSocket client for real-time events
|
|
75
|
+
wsClient = new lark.WSClient({
|
|
76
|
+
appId: config.appId,
|
|
77
|
+
appSecret: config.appSecret,
|
|
78
|
+
loggerLevel: lark.LoggerLevel.warn,
|
|
79
|
+
});
|
|
80
|
+
await wsClient.start({ eventDispatcher });
|
|
81
|
+
connected = true;
|
|
82
|
+
},
|
|
83
|
+
async stop() {
|
|
84
|
+
connected = false;
|
|
85
|
+
wsClient = null;
|
|
86
|
+
eventDispatcher = null;
|
|
87
|
+
client = null;
|
|
88
|
+
},
|
|
89
|
+
async send(msg) {
|
|
90
|
+
if (!client)
|
|
91
|
+
throw new Error('Feishu not started');
|
|
92
|
+
const chunks = chunkMarkdown(msg.text, CHANNEL_LIMITS.feishu);
|
|
93
|
+
for (const chunk of chunks) {
|
|
94
|
+
await client.im.message.create({
|
|
95
|
+
params: { receive_id_type: 'chat_id' },
|
|
96
|
+
data: {
|
|
97
|
+
receive_id: msg.to,
|
|
98
|
+
msg_type: 'text',
|
|
99
|
+
content: JSON.stringify({ text: chunk }),
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
isAllowed(senderId) {
|
|
105
|
+
if (config.allowFrom.length === 0)
|
|
106
|
+
return true;
|
|
107
|
+
return config.allowFrom.includes(senderId);
|
|
108
|
+
},
|
|
109
|
+
isConnected() {
|
|
110
|
+
return connected;
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=feishu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feishu.js","sourceRoot":"","sources":["../../src/adapters/feishu.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,yBAAyB,CAAC;AAEhD,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAU/D,MAAM,UAAU,mBAAmB,CAAC,MAA2B;IAC7D,IAAI,MAAM,GAAuB,IAAI,CAAC;IACtC,IAAI,eAAe,GAAgC,IAAI,CAAC;IACxD,IAAI,QAAQ,GAAmB,IAAI,CAAC;IACpC,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,IAAI,cAAc,GAA0B,IAAI,CAAC;IAEjD,OAAO;QACL,EAAE,EAAE,QAAQ;QACZ,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;QAEpC,KAAK,CAAC,KAAK,CAAC,OAAuB;YACjC,cAAc,GAAG,OAAO,CAAC;YAEzB,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC;gBACvB,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;aAChC,CAAC,CAAC;YAEH,eAAe,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC;gBACzC,iBAAiB,EAAE,MAAM,CAAC,iBAAiB;gBAC3C,UAAU,EAAE,MAAM,CAAC,UAAU;aAC9B,CAAC,CAAC;YAEH,sBAAsB;YACtB,eAAe,CAAC,QAAQ,CAAC;gBACvB,uBAAuB,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;oBAC/D,IAAI,CAAC,cAAc;wBAAE,OAAO;oBAE5B,MAAM,OAAO,GAAG,IAAI,CAAC,OAA8C,CAAC;oBACpE,IAAI,CAAC,OAAO;wBAAE,OAAO;oBAErB,MAAM,OAAO,GAAG,OAAO,CAAC,YAAsB,CAAC;oBAC/C,IAAI,OAAO,KAAK,MAAM;wBAAE,OAAO;oBAE/B,IAAI,IAAI,GAAG,EAAE,CAAC;oBACd,IAAI,CAAC;wBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAiB,CAAC,CAAC;wBACtD,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;oBAC5B,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO;oBACT,CAAC;oBAED,IAAI,CAAC,IAAI;wBAAE,OAAO;oBAElB,MAAM,MAAM,GAAG,IAAI,CAAC,MAA6C,CAAC;oBAClE,MAAM,QAAQ,GAAI,MAAM,EAAE,SAAqC,EAAE,OAAiB,IAAI,EAAE,CAAC;oBAEzF,MAAM,OAAO,GAAmB;wBAC9B,SAAS,EAAE,QAAQ;wBACnB,OAAO,EAAE,OAAO,CAAC,OAAiB;wBAClC,QAAQ;wBACR,IAAI;wBACJ,SAAS,EAAE,OAAO,CAAC,OAAO;4BACxB,CAAC,CAAC,UAAU,OAAO,CAAC,OAAiB,EAAE;4BACvC,CAAC,CAAC,QAAQ,OAAO,CAAC,OAAiB,EAAE;wBACvC,QAAQ,EAAE,OAAO,CAAC,OAA6B;wBAC/C,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;qBACrD,CAAC;oBAEF,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;oBAC/C,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;wBACvB,MAAM,MAAM,GAAG,OAAO,CAAC,OAAiB,CAAC;wBACzC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;wBAC9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;4BAC3B,MAAM,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;gCAC7B,MAAM,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE;gCACtC,IAAI,EAAE;oCACJ,UAAU,EAAE,MAAM;oCAClB,QAAQ,EAAE,MAAM;oCAChB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;iCACzC;6BACF,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;gBACH,CAAC;aACF,CAAC,CAAC;YAEH,4CAA4C;YAC5C,QAAQ,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC;gBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;aACnC,CAAC,CAAC;YAEH,MAAO,QAA0B,CAAC,KAAK,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC;YAC7D,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;QAED,KAAK,CAAC,IAAI;YACR,SAAS,GAAG,KAAK,CAAC;YAClB,QAAQ,GAAG,IAAI,CAAC;YAChB,eAAe,GAAG,IAAI,CAAC;YACvB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,GAAoB;YAC7B,IAAI,CAAC,MAAM;gBAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,MAAM,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC;oBAC7B,MAAM,EAAE,EAAE,eAAe,EAAE,SAAS,EAAE;oBACtC,IAAI,EAAE;wBACJ,UAAU,EAAE,GAAG,CAAC,EAAE;wBAClB,QAAQ,EAAE,MAAM;wBAChB,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;qBACzC;iBACF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,SAAS,CAAC,QAAgB;YACxB,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC/C,OAAO,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAC7C,CAAC;QAED,WAAW;YACT,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
/** Split a text chunk into individual IRC-safe PRIVMSG lines.
|
|
3
|
+
* Empty lines are sent as a single space to preserve formatting. */
|
|
4
|
+
export declare function splitIrcLines(text: string): string[];
|
|
5
|
+
export interface IrcChannelConfig {
|
|
6
|
+
host: string;
|
|
7
|
+
port: number;
|
|
8
|
+
tls: boolean;
|
|
9
|
+
nick: string;
|
|
10
|
+
password?: string;
|
|
11
|
+
channels: string[];
|
|
12
|
+
allowFrom: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Parse a raw IRC protocol line into prefix, command, and params. */
|
|
15
|
+
export declare function parseIrcLine(line: string): {
|
|
16
|
+
prefix?: string;
|
|
17
|
+
command: string;
|
|
18
|
+
params: string[];
|
|
19
|
+
};
|
|
20
|
+
/** Extract the nickname from an IRC prefix (nick!user@host). */
|
|
21
|
+
export declare function extractIrcNick(prefix: string): string;
|
|
22
|
+
export declare function createIrcChannel(config: IrcChannelConfig): ChannelPlugin;
|
|
23
|
+
//# sourceMappingURL=irc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irc.d.ts","sourceRoot":"","sources":["../../src/adapters/irc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG;oEACoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEpD;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBjG;AAED,gEAAgE;AAChE,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,aAAa,CAuIxE"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import * as net from 'node:net';
|
|
2
|
+
import * as tls from 'node:tls';
|
|
3
|
+
import { chunkMarkdown, CHANNEL_LIMITS } from '../chunking.js';
|
|
4
|
+
/** Split a text chunk into individual IRC-safe PRIVMSG lines.
|
|
5
|
+
* Empty lines are sent as a single space to preserve formatting. */
|
|
6
|
+
export function splitIrcLines(text) {
|
|
7
|
+
return text.replace(/\r/g, '').split('\n').map((line) => line || ' ');
|
|
8
|
+
}
|
|
9
|
+
/** Parse a raw IRC protocol line into prefix, command, and params. */
|
|
10
|
+
export function parseIrcLine(line) {
|
|
11
|
+
let prefix;
|
|
12
|
+
let rest = line;
|
|
13
|
+
if (rest.startsWith(':')) {
|
|
14
|
+
const idx = rest.indexOf(' ');
|
|
15
|
+
prefix = rest.slice(1, idx);
|
|
16
|
+
rest = rest.slice(idx + 1);
|
|
17
|
+
}
|
|
18
|
+
const trailingIdx = rest.indexOf(' :');
|
|
19
|
+
let trailing;
|
|
20
|
+
if (trailingIdx !== -1) {
|
|
21
|
+
trailing = rest.slice(trailingIdx + 2);
|
|
22
|
+
rest = rest.slice(0, trailingIdx);
|
|
23
|
+
}
|
|
24
|
+
const parts = rest.split(' ').filter(Boolean);
|
|
25
|
+
const command = parts[0];
|
|
26
|
+
const params = parts.slice(1);
|
|
27
|
+
if (trailing !== undefined)
|
|
28
|
+
params.push(trailing);
|
|
29
|
+
return { prefix, command, params };
|
|
30
|
+
}
|
|
31
|
+
/** Extract the nickname from an IRC prefix (nick!user@host). */
|
|
32
|
+
export function extractIrcNick(prefix) {
|
|
33
|
+
const idx = prefix.indexOf('!');
|
|
34
|
+
return idx !== -1 ? prefix.slice(0, idx) : prefix;
|
|
35
|
+
}
|
|
36
|
+
export function createIrcChannel(config) {
|
|
37
|
+
let socket = null;
|
|
38
|
+
let connected = false;
|
|
39
|
+
let handler = null;
|
|
40
|
+
let buffer = '';
|
|
41
|
+
const limit = CHANNEL_LIMITS.irc;
|
|
42
|
+
function send(line) {
|
|
43
|
+
socket?.write(`${line}\r\n`);
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
id: 'irc',
|
|
47
|
+
meta: { name: 'IRC', emoji: '#' },
|
|
48
|
+
async start(h) {
|
|
49
|
+
handler = h;
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
const onConnect = () => {
|
|
52
|
+
if (config.password)
|
|
53
|
+
send(`PASS ${config.password}`);
|
|
54
|
+
send(`NICK ${config.nick}`);
|
|
55
|
+
send(`USER ${config.nick} 0 * :CereWorker`);
|
|
56
|
+
};
|
|
57
|
+
if (config.tls) {
|
|
58
|
+
socket = tls.connect({ host: config.host, port: config.port }, onConnect);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
socket = net.connect({ host: config.host, port: config.port }, onConnect);
|
|
62
|
+
}
|
|
63
|
+
socket.setEncoding('utf-8');
|
|
64
|
+
socket.on('data', (data) => {
|
|
65
|
+
buffer += data;
|
|
66
|
+
const lines = buffer.split('\r\n');
|
|
67
|
+
buffer = lines.pop() ?? '';
|
|
68
|
+
for (const line of lines) {
|
|
69
|
+
if (!line)
|
|
70
|
+
continue;
|
|
71
|
+
void handleLine(line);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
socket.on('error', (err) => {
|
|
75
|
+
if (!connected)
|
|
76
|
+
reject(err);
|
|
77
|
+
});
|
|
78
|
+
socket.on('close', () => {
|
|
79
|
+
connected = false;
|
|
80
|
+
});
|
|
81
|
+
async function handleLine(line) {
|
|
82
|
+
const parsed = parseIrcLine(line);
|
|
83
|
+
if (parsed.command === 'PING') {
|
|
84
|
+
send(`PONG :${parsed.params[0] ?? ''}`);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// RPL_WELCOME — we're registered
|
|
88
|
+
if (parsed.command === '001') {
|
|
89
|
+
connected = true;
|
|
90
|
+
// Identify with NickServ if password set
|
|
91
|
+
if (config.password) {
|
|
92
|
+
send(`PRIVMSG NickServ :IDENTIFY ${config.password}`);
|
|
93
|
+
}
|
|
94
|
+
// Join channels
|
|
95
|
+
for (const ch of config.channels) {
|
|
96
|
+
send(`JOIN ${ch}`);
|
|
97
|
+
}
|
|
98
|
+
resolve();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (parsed.command === 'PRIVMSG' && parsed.prefix && handler) {
|
|
102
|
+
const nick = extractIrcNick(parsed.prefix);
|
|
103
|
+
if (nick === config.nick)
|
|
104
|
+
return; // skip own messages
|
|
105
|
+
const target = parsed.params[0]; // channel or nick
|
|
106
|
+
const text = parsed.params[1] ?? '';
|
|
107
|
+
const inbound = {
|
|
108
|
+
channelId: 'irc',
|
|
109
|
+
routeTo: target.startsWith('#') ? target : nick,
|
|
110
|
+
senderId: nick,
|
|
111
|
+
senderName: nick,
|
|
112
|
+
text,
|
|
113
|
+
sessionId: target.startsWith('#') ? `channel:${target}` : `dm:${nick}`,
|
|
114
|
+
timestamp: Date.now(),
|
|
115
|
+
};
|
|
116
|
+
const response = await handler(inbound);
|
|
117
|
+
if (response) {
|
|
118
|
+
const replyTarget = target.startsWith('#') ? target : nick;
|
|
119
|
+
const chunks = chunkMarkdown(response, limit);
|
|
120
|
+
for (const chunk of chunks) {
|
|
121
|
+
for (const line of splitIrcLines(chunk)) {
|
|
122
|
+
send(`PRIVMSG ${replyTarget} :${line}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
async stop() {
|
|
131
|
+
if (socket) {
|
|
132
|
+
send('QUIT :CereWorker shutting down');
|
|
133
|
+
socket.destroy();
|
|
134
|
+
socket = null;
|
|
135
|
+
connected = false;
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
async send(msg) {
|
|
139
|
+
if (!socket)
|
|
140
|
+
throw new Error('IRC not started');
|
|
141
|
+
const chunks = chunkMarkdown(msg.text, limit);
|
|
142
|
+
for (const chunk of chunks) {
|
|
143
|
+
for (const line of splitIrcLines(chunk)) {
|
|
144
|
+
send(`PRIVMSG ${msg.to} :${line}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
isAllowed(senderId) {
|
|
149
|
+
if (config.allowFrom.length === 0)
|
|
150
|
+
return true;
|
|
151
|
+
return config.allowFrom.includes(senderId);
|
|
152
|
+
},
|
|
153
|
+
isConnected() {
|
|
154
|
+
return connected;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=irc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"irc.js","sourceRoot":"","sources":["../../src/adapters/irc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChannelPlugin } from '../types.js';
|
|
2
|
+
export interface MatrixChannelConfig {
|
|
3
|
+
homeserver: string;
|
|
4
|
+
token: string;
|
|
5
|
+
userId: string;
|
|
6
|
+
allowFrom: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function createMatrixChannel(config: MatrixChannelConfig): ChannelPlugin;
|
|
9
|
+
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../../src/adapters/matrix.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAmD,MAAM,aAAa,CAAC;AAGlG,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAuE9E"}
|