pi-courier 0.1.7 → 0.1.8
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/dist/cli.js +0 -0
- package/package.json +2 -2
- package/dist/transports/discord.d.ts +0 -33
- package/dist/transports/discord.d.ts.map +0 -1
- package/dist/transports/discord.js +0 -216
- package/dist/transports/discord.js.map +0 -1
- package/dist/transports/slack.d.ts +0 -31
- package/dist/transports/slack.d.ts.map +0 -1
- package/dist/transports/slack.js +0 -203
- package/dist/transports/slack.js.map +0 -1
- package/dist/transports/telegram.d.ts +0 -38
- package/dist/transports/telegram.d.ts.map +0 -1
- package/dist/transports/telegram.js +0 -167
- package/dist/transports/telegram.js.map +0 -1
- package/dist/transports/whatsapp.d.ts +0 -31
- package/dist/transports/whatsapp.d.ts.map +0 -1
- package/dist/transports/whatsapp.js +0 -235
- package/dist/transports/whatsapp.js.map +0 -1
package/dist/cli.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-courier",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "Run pi coding agent from Matrix. Slash commands, skills and prompts fully work from messengers via the RPC protocol.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/standalone.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"README.zh-CN.md"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "tsc",
|
|
18
|
+
"build": "rm -rf dist && tsc",
|
|
19
19
|
"prepare": "npm run build",
|
|
20
20
|
"watch": "tsc --watch",
|
|
21
21
|
"clean": "rm -rf dist",
|
|
@@ -1,33 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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"}
|
|
@@ -1,216 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discord.js","sourceRoot":"","sources":["../../src/transports/discord.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +0,0 @@
|
|
|
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
|
-
* Slack transport provider using @slack/bolt
|
|
6
|
-
*/
|
|
7
|
-
export declare class SlackProvider implements ITransportProvider {
|
|
8
|
-
private config;
|
|
9
|
-
private auth;
|
|
10
|
-
readonly type = "slack";
|
|
11
|
-
private app;
|
|
12
|
-
private _isConnected;
|
|
13
|
-
private botUserId;
|
|
14
|
-
private messageHandler?;
|
|
15
|
-
private errorHandler?;
|
|
16
|
-
private lastProcessedMessageId;
|
|
17
|
-
private userCache;
|
|
18
|
-
private channelCache;
|
|
19
|
-
constructor(config: {
|
|
20
|
-
botToken: string;
|
|
21
|
-
appToken: string;
|
|
22
|
-
}, auth: ChallengeAuth);
|
|
23
|
-
get isConnected(): boolean;
|
|
24
|
-
connect(): Promise<void>;
|
|
25
|
-
disconnect(): Promise<void>;
|
|
26
|
-
sendMessage(chatId: string, text: string): Promise<void>;
|
|
27
|
-
sendTyping(_chatId: string): Promise<void>;
|
|
28
|
-
onMessage(handler: (message: ExternalMessage) => void): void;
|
|
29
|
-
onError(handler: (error: Error) => void): void;
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=slack.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../src/transports/slack.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;AAUzD;;GAEG;AACH,qBAAa,aAAc,YAAW,kBAAkB;IAepD,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,IAAI;IAfd,QAAQ,CAAC,IAAI,WAAW;IACxB,OAAO,CAAC,GAAG,CAAoB;IAC/B,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;IAGpC,OAAO,CAAC,SAAS,CAAkC;IAEnD,OAAO,CAAC,YAAY,CAA4D;gBAGtE,MAAM,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAC9C,IAAI,EAAE,aAAa;IAG7B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkKxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,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;CAG/C"}
|
package/dist/transports/slack.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
async function loadSlackBolt() {
|
|
2
|
-
const slack = await import("@slack/bolt");
|
|
3
|
-
return slack;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Slack transport provider using @slack/bolt
|
|
7
|
-
*/
|
|
8
|
-
export class SlackProvider {
|
|
9
|
-
config;
|
|
10
|
-
auth;
|
|
11
|
-
type = "slack";
|
|
12
|
-
app = null;
|
|
13
|
-
_isConnected = false;
|
|
14
|
-
botUserId = "";
|
|
15
|
-
messageHandler;
|
|
16
|
-
errorHandler;
|
|
17
|
-
lastProcessedMessageId = "";
|
|
18
|
-
// Cache user info to avoid repeated API calls
|
|
19
|
-
userCache = new Map();
|
|
20
|
-
// Cache channel info to detect DMs vs channels
|
|
21
|
-
channelCache = new Map();
|
|
22
|
-
constructor(config, auth) {
|
|
23
|
-
this.config = config;
|
|
24
|
-
this.auth = auth;
|
|
25
|
-
}
|
|
26
|
-
get isConnected() {
|
|
27
|
-
return this._isConnected;
|
|
28
|
-
}
|
|
29
|
-
async connect() {
|
|
30
|
-
if (this._isConnected)
|
|
31
|
-
return;
|
|
32
|
-
const { botToken, appToken } = this.config;
|
|
33
|
-
if (!botToken || !appToken) {
|
|
34
|
-
throw new Error("Slack requires both botToken (xoxb-...) and appToken (xapp-...)");
|
|
35
|
-
}
|
|
36
|
-
const slack = await loadSlackBolt();
|
|
37
|
-
this.app = new slack.App({
|
|
38
|
-
token: botToken,
|
|
39
|
-
appToken: appToken,
|
|
40
|
-
socketMode: true,
|
|
41
|
-
logLevel: slack.LogLevel.WARN,
|
|
42
|
-
});
|
|
43
|
-
// Get bot's own user ID for mention detection
|
|
44
|
-
try {
|
|
45
|
-
const authResult = await this.app.client.auth.test();
|
|
46
|
-
this.botUserId = authResult.user_id || "";
|
|
47
|
-
console.log(`[Slack] Bot user ID: ${this.botUserId}`);
|
|
48
|
-
}
|
|
49
|
-
catch (e) {
|
|
50
|
-
console.warn("[Slack] Could not get bot info:", e);
|
|
51
|
-
}
|
|
52
|
-
// Listen for all messages
|
|
53
|
-
this.app.message(async ({ message, client }) => {
|
|
54
|
-
// Skip bot messages, message edits, deletes, etc.
|
|
55
|
-
if (message.subtype) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
// TypeScript type guard for regular messages
|
|
59
|
-
if (!("user" in message) || !("text" in message) || !message.text) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
const userId = message.user;
|
|
63
|
-
const channelId = message.channel;
|
|
64
|
-
const text = message.text;
|
|
65
|
-
const ts = message.ts;
|
|
66
|
-
// Filter out duplicate messages
|
|
67
|
-
if (ts === this.lastProcessedMessageId) {
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
this.lastProcessedMessageId = ts;
|
|
71
|
-
// Get username from cache or fetch
|
|
72
|
-
let username = this.userCache.get(userId) || userId;
|
|
73
|
-
if (!this.userCache.has(userId)) {
|
|
74
|
-
try {
|
|
75
|
-
const userInfo = await client.users.info({ user: userId });
|
|
76
|
-
const fetchedName = userInfo.user?.real_name || userInfo.user?.name;
|
|
77
|
-
if (fetchedName) {
|
|
78
|
-
username = fetchedName;
|
|
79
|
-
this.userCache.set(userId, username);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
username = userId;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// Get channel info from cache or fetch (to detect DM vs channel)
|
|
87
|
-
let channelInfo = this.channelCache.get(channelId);
|
|
88
|
-
if (!channelInfo) {
|
|
89
|
-
try {
|
|
90
|
-
const convInfo = await client.conversations.info({ channel: channelId });
|
|
91
|
-
const conv = convInfo.channel;
|
|
92
|
-
// is_im = direct message, is_mpim = multi-party DM
|
|
93
|
-
const isDM = conv?.is_im === true || conv?.is_mpim === true;
|
|
94
|
-
const name = conv?.name || (isDM ? "DM" : channelId);
|
|
95
|
-
channelInfo = { isDM, name };
|
|
96
|
-
this.channelCache.set(channelId, channelInfo);
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// Default to assuming it's a DM if we can't fetch info
|
|
100
|
-
channelInfo = { isDM: true };
|
|
101
|
-
this.channelCache.set(channelId, channelInfo);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
// Detect bot mention: <@BOT_USER_ID>
|
|
105
|
-
const wasMentioned = this.botUserId
|
|
106
|
-
? text.includes(`<@${this.botUserId}>`)
|
|
107
|
-
: false;
|
|
108
|
-
const isGroupChat = !channelInfo.isDM;
|
|
109
|
-
// Check authorization
|
|
110
|
-
const sendMessageToUser = async (cId, text) => {
|
|
111
|
-
if (this.app) {
|
|
112
|
-
await this.app.client.chat.postMessage({
|
|
113
|
-
channel: cId,
|
|
114
|
-
text: text,
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
const isAuthorized = await this.auth.checkAuthorization(userId, channelId, username, isGroupChat, wasMentioned, sendMessageToUser, this.type);
|
|
119
|
-
// Handle admin commands and challenge codes in DM
|
|
120
|
-
if (!isGroupChat && (text.startsWith("/") || text.match(/^\d{6}$/))) {
|
|
121
|
-
const handled = await this.auth.handleAdminCommand(text, channelId, userId, async (text) => await this.sendMessage(channelId, text), this.type);
|
|
122
|
-
if (handled) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
if (!isAuthorized) {
|
|
127
|
-
return; // Auth handler already sent challenge/error messages
|
|
128
|
-
}
|
|
129
|
-
// Forward to message handler
|
|
130
|
-
if (this.messageHandler) {
|
|
131
|
-
const externalMessage = {
|
|
132
|
-
chatId: channelId,
|
|
133
|
-
transport: this.type,
|
|
134
|
-
content: text.trim(),
|
|
135
|
-
username: username,
|
|
136
|
-
userId: userId,
|
|
137
|
-
timestamp: new Date(parseFloat(ts) * 1000),
|
|
138
|
-
messageId: ts,
|
|
139
|
-
isGroupChat,
|
|
140
|
-
wasMentioned,
|
|
141
|
-
};
|
|
142
|
-
this.messageHandler(externalMessage);
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
// Handle errors
|
|
146
|
-
this.app.error(async (error) => {
|
|
147
|
-
console.error("[Slack] Error:", error);
|
|
148
|
-
if (this.errorHandler) {
|
|
149
|
-
this.errorHandler(new Error(String(error)));
|
|
150
|
-
}
|
|
151
|
-
});
|
|
152
|
-
try {
|
|
153
|
-
await this.app.start();
|
|
154
|
-
this._isConnected = true;
|
|
155
|
-
}
|
|
156
|
-
catch (error) {
|
|
157
|
-
throw new Error(`Slack connection failed: ${error.message}`);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
async disconnect() {
|
|
161
|
-
if (this.app) {
|
|
162
|
-
try {
|
|
163
|
-
await this.app.stop();
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
// Ignore stop errors
|
|
167
|
-
}
|
|
168
|
-
this.app = null;
|
|
169
|
-
}
|
|
170
|
-
this._isConnected = false;
|
|
171
|
-
this.userCache.clear();
|
|
172
|
-
this.channelCache.clear();
|
|
173
|
-
console.log("[Slack] Disconnected");
|
|
174
|
-
}
|
|
175
|
-
async sendMessage(chatId, text) {
|
|
176
|
-
if (!this.app) {
|
|
177
|
-
throw new Error("Slack not connected");
|
|
178
|
-
}
|
|
179
|
-
if (!text?.trim())
|
|
180
|
-
return;
|
|
181
|
-
try {
|
|
182
|
-
await this.app.client.chat.postMessage({
|
|
183
|
-
channel: chatId,
|
|
184
|
-
text: text,
|
|
185
|
-
});
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
throw new Error(`Slack send failed: ${error.message}`);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
async sendTyping(_chatId) {
|
|
192
|
-
// Slack doesn't support typing indicators for bots
|
|
193
|
-
// We could potentially add a reaction or use a "thinking" message
|
|
194
|
-
// but for now we'll just skip it
|
|
195
|
-
}
|
|
196
|
-
onMessage(handler) {
|
|
197
|
-
this.messageHandler = handler;
|
|
198
|
-
}
|
|
199
|
-
onError(handler) {
|
|
200
|
-
this.errorHandler = handler;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
//# sourceMappingURL=slack.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/transports/slack.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,38 +0,0 @@
|
|
|
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
|
-
* Telegram transport provider using node-telegram-bot-api
|
|
6
|
-
*/
|
|
7
|
-
export declare class TelegramProvider implements ITransportProvider {
|
|
8
|
-
private token;
|
|
9
|
-
private auth;
|
|
10
|
-
readonly type = "telegram";
|
|
11
|
-
private bot?;
|
|
12
|
-
private _isConnected;
|
|
13
|
-
private messageHandler?;
|
|
14
|
-
private errorHandler?;
|
|
15
|
-
private lastProcessedMessageId;
|
|
16
|
-
constructor(token: string, auth: ChallengeAuth);
|
|
17
|
-
get isConnected(): boolean;
|
|
18
|
-
/**
|
|
19
|
-
* Convert standard markdown to Telegram MarkdownV1 format.
|
|
20
|
-
*
|
|
21
|
-
* Telegram MarkdownV1 syntax: *bold*, _italic_, `code`, ```pre```, [text](url).
|
|
22
|
-
* Per docs, only `_ * [ \`` need backslash-escaping when literal — otherwise
|
|
23
|
-
* a stray `_` (e.g. in a snake_case tool name like `hud_canvas`) is parsed
|
|
24
|
-
* as an opening italic marker with no close, returning HTTP 400.
|
|
25
|
-
*
|
|
26
|
-
* Strategy: lift valid markdown patterns into NUL-sentinel placeholders,
|
|
27
|
-
* escape the remaining specials, then restore the placeholders.
|
|
28
|
-
*/
|
|
29
|
-
private formatForTelegram;
|
|
30
|
-
connect(): Promise<void>;
|
|
31
|
-
disconnect(): Promise<void>;
|
|
32
|
-
sendMessage(chatId: string, text: string): Promise<void>;
|
|
33
|
-
sendTyping(chatId: string): Promise<void>;
|
|
34
|
-
onMessage(handler: (message: ExternalMessage) => void): void;
|
|
35
|
-
onError(handler: (error: Error) => void): void;
|
|
36
|
-
private handleMessage;
|
|
37
|
-
}
|
|
38
|
-
//# sourceMappingURL=telegram.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/transports/telegram.ts"],"names":[],"mappings":"AACA,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;AAEzD;;GAEG;AACH,qBAAa,gBAAiB,YAAW,kBAAkB;IASvD,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,IAAI;IATd,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,GAAG,CAAC,CAAc;IAC1B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAC,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAyB;IAC9C,OAAO,CAAC,sBAAsB,CAAK;gBAGzB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,aAAa;IAG7B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,iBAAiB;IAiBnB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAgCxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ3B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/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;YAIhC,aAAa;CA4F5B"}
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import TelegramBot from "node-telegram-bot-api";
|
|
2
|
-
/**
|
|
3
|
-
* Telegram transport provider using node-telegram-bot-api
|
|
4
|
-
*/
|
|
5
|
-
export class TelegramProvider {
|
|
6
|
-
token;
|
|
7
|
-
auth;
|
|
8
|
-
type = "telegram";
|
|
9
|
-
bot;
|
|
10
|
-
_isConnected = false;
|
|
11
|
-
messageHandler;
|
|
12
|
-
errorHandler;
|
|
13
|
-
lastProcessedMessageId = 0;
|
|
14
|
-
constructor(token, auth) {
|
|
15
|
-
this.token = token;
|
|
16
|
-
this.auth = auth;
|
|
17
|
-
}
|
|
18
|
-
get isConnected() {
|
|
19
|
-
return this._isConnected;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Convert standard markdown to Telegram MarkdownV1 format.
|
|
23
|
-
*
|
|
24
|
-
* Telegram MarkdownV1 syntax: *bold*, _italic_, `code`, ```pre```, [text](url).
|
|
25
|
-
* Per docs, only `_ * [ \`` need backslash-escaping when literal — otherwise
|
|
26
|
-
* a stray `_` (e.g. in a snake_case tool name like `hud_canvas`) is parsed
|
|
27
|
-
* as an opening italic marker with no close, returning HTTP 400.
|
|
28
|
-
*
|
|
29
|
-
* Strategy: lift valid markdown patterns into NUL-sentinel placeholders,
|
|
30
|
-
* escape the remaining specials, then restore the placeholders.
|
|
31
|
-
*/
|
|
32
|
-
formatForTelegram(text) {
|
|
33
|
-
const lifted = [];
|
|
34
|
-
const lift = (s) => `\x00${lifted.push(s) - 1}\x00`;
|
|
35
|
-
// Lift valid markdown patterns in priority order — they bypass the escape step below.
|
|
36
|
-
text = text.replace(/```[\s\S]*?```/g, lift); // code blocks
|
|
37
|
-
text = text.replace(/`[^`]+`/g, lift); // inline code
|
|
38
|
-
text = text.replace(/\*\*([^*]+?)\*\*/g, (_, c) => lift(`*${c}*`)); // **bold** → *bold*
|
|
39
|
-
text = text.replace(/(?<!\*)\*(?!\*)([^*]+?)(?<!\*)\*(?!\*)/g, (_, c) => lift(`_${c}_`)); // *italic* → _italic_
|
|
40
|
-
text = text.replace(/\[[^\]]+\]\([^)]+\)/g, lift); // [text](url)
|
|
41
|
-
// Escape literal markdown specials so Telegram treats them as text.
|
|
42
|
-
text = text.replace(/[_*[`]/g, "\\$&");
|
|
43
|
-
return text.replace(/\x00(\d+)\x00/g, (_, i) => lifted[parseInt(i, 10)]);
|
|
44
|
-
}
|
|
45
|
-
async connect() {
|
|
46
|
-
if (this._isConnected)
|
|
47
|
-
return;
|
|
48
|
-
this.bot = new TelegramBot(this.token, {
|
|
49
|
-
polling: {
|
|
50
|
-
interval: 300,
|
|
51
|
-
autoStart: false,
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
// Handle incoming messages
|
|
55
|
-
this.bot.on("message", async (msg) => {
|
|
56
|
-
try {
|
|
57
|
-
await this.handleMessage(msg);
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
if (this.errorHandler) {
|
|
61
|
-
this.errorHandler(err);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
// Handle polling errors
|
|
66
|
-
this.bot.on("polling_error", (err) => {
|
|
67
|
-
if (this.errorHandler) {
|
|
68
|
-
this.errorHandler(err);
|
|
69
|
-
}
|
|
70
|
-
});
|
|
71
|
-
await this.bot.startPolling();
|
|
72
|
-
this._isConnected = true;
|
|
73
|
-
}
|
|
74
|
-
async disconnect() {
|
|
75
|
-
if (!this._isConnected || !this.bot)
|
|
76
|
-
return;
|
|
77
|
-
await this.bot.stopPolling();
|
|
78
|
-
this._isConnected = false;
|
|
79
|
-
this.bot = undefined;
|
|
80
|
-
}
|
|
81
|
-
async sendMessage(chatId, text) {
|
|
82
|
-
if (!this.bot) {
|
|
83
|
-
throw new Error("Telegram bot not connected");
|
|
84
|
-
}
|
|
85
|
-
if (!text?.trim())
|
|
86
|
-
return;
|
|
87
|
-
const formattedText = this.formatForTelegram(text);
|
|
88
|
-
await this.bot.sendMessage(chatId, formattedText, { parse_mode: "Markdown" });
|
|
89
|
-
}
|
|
90
|
-
async sendTyping(chatId) {
|
|
91
|
-
if (!this.bot)
|
|
92
|
-
return;
|
|
93
|
-
await this.bot.sendChatAction(chatId, "typing");
|
|
94
|
-
}
|
|
95
|
-
onMessage(handler) {
|
|
96
|
-
this.messageHandler = handler;
|
|
97
|
-
}
|
|
98
|
-
onError(handler) {
|
|
99
|
-
this.errorHandler = handler;
|
|
100
|
-
}
|
|
101
|
-
async handleMessage(msg) {
|
|
102
|
-
// Filter out old messages (prevent stale message processing on reconnect)
|
|
103
|
-
if (msg.message_id <= this.lastProcessedMessageId) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
this.lastProcessedMessageId = msg.message_id;
|
|
107
|
-
// Only process text messages
|
|
108
|
-
if (!msg.text || !msg.from) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
const chatId = msg.chat.id.toString();
|
|
112
|
-
const userId = msg.from.id.toString();
|
|
113
|
-
const username = msg.from.username || msg.from.first_name || "unknown";
|
|
114
|
-
const isGroupChat = msg.chat.type !== "private";
|
|
115
|
-
// Check if bot was mentioned in group chat
|
|
116
|
-
let wasMentioned = false;
|
|
117
|
-
if (isGroupChat && this.bot) {
|
|
118
|
-
const botInfo = await this.bot.getMe();
|
|
119
|
-
const botUsername = botInfo.username;
|
|
120
|
-
wasMentioned =
|
|
121
|
-
msg.text.includes(`@${botUsername}`) ||
|
|
122
|
-
(msg.entities?.some((entity) => entity.type === "mention" &&
|
|
123
|
-
msg.text.substring(entity.offset, entity.offset + entity.length) ===
|
|
124
|
-
`@${botUsername}`) ?? false);
|
|
125
|
-
}
|
|
126
|
-
// Check authorization (with sendMessage callback for challenge notifications)
|
|
127
|
-
const sendMessageToUser = async (cId, text) => {
|
|
128
|
-
if (this.bot) {
|
|
129
|
-
await this.bot.sendMessage(cId, text, { parse_mode: "Markdown" });
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
const isAuthorized = await this.auth.checkAuthorization(userId, chatId, username, isGroupChat, wasMentioned, sendMessageToUser, this.type);
|
|
133
|
-
// Handle admin commands and challenge codes in DM (before auth check!)
|
|
134
|
-
if (!isGroupChat && (msg.text.startsWith("/") || msg.text.match(/^\d{6}$/))) {
|
|
135
|
-
const handled = await this.auth.handleAdminCommand(msg.text, chatId, userId, async (text) => await this.sendMessage(chatId, text), this.type);
|
|
136
|
-
if (handled) {
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
if (!isAuthorized) {
|
|
141
|
-
return; // Auth handler already sent challenge/error messages
|
|
142
|
-
}
|
|
143
|
-
// Strip bot mention from message if present
|
|
144
|
-
let content = msg.text;
|
|
145
|
-
if (wasMentioned && this.bot) {
|
|
146
|
-
const botInfo = await this.bot.getMe();
|
|
147
|
-
const botUsername = botInfo.username;
|
|
148
|
-
content = content.replace(new RegExp(`@${botUsername}\\s*`, "g"), "").trim();
|
|
149
|
-
}
|
|
150
|
-
// Forward to message handler
|
|
151
|
-
if (this.messageHandler && content) {
|
|
152
|
-
const externalMessage = {
|
|
153
|
-
chatId,
|
|
154
|
-
transport: this.type,
|
|
155
|
-
content,
|
|
156
|
-
username,
|
|
157
|
-
userId,
|
|
158
|
-
timestamp: new Date((msg.date || 0) * 1000),
|
|
159
|
-
messageId: msg.message_id.toString(),
|
|
160
|
-
isGroupChat,
|
|
161
|
-
wasMentioned,
|
|
162
|
-
};
|
|
163
|
-
this.messageHandler(externalMessage);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
//# sourceMappingURL=telegram.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/transports/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,31 +0,0 @@
|
|
|
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
|
-
* WhatsApp transport provider using @whiskeysockets/baileys
|
|
6
|
-
*/
|
|
7
|
-
export declare class WhatsAppProvider implements ITransportProvider {
|
|
8
|
-
private auth;
|
|
9
|
-
readonly type = "whatsapp";
|
|
10
|
-
private socket;
|
|
11
|
-
private _isConnected;
|
|
12
|
-
private authPath;
|
|
13
|
-
private messageHandler?;
|
|
14
|
-
private errorHandler?;
|
|
15
|
-
private lastProcessedMessageId;
|
|
16
|
-
private debug;
|
|
17
|
-
private isManualConnect;
|
|
18
|
-
constructor(config: {
|
|
19
|
-
authPath?: string;
|
|
20
|
-
debug?: boolean;
|
|
21
|
-
}, auth: ChallengeAuth);
|
|
22
|
-
get isConnected(): boolean;
|
|
23
|
-
connect(manual?: boolean): Promise<void>;
|
|
24
|
-
disconnect(): Promise<void>;
|
|
25
|
-
sendMessage(chatId: string, text: string): Promise<void>;
|
|
26
|
-
sendTyping(chatId: string): Promise<void>;
|
|
27
|
-
onMessage(handler: (message: ExternalMessage) => void): void;
|
|
28
|
-
onError(handler: (error: Error) => void): void;
|
|
29
|
-
private handleMessage;
|
|
30
|
-
}
|
|
31
|
-
//# sourceMappingURL=whatsapp.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp.d.ts","sourceRoot":"","sources":["../../src/transports/whatsapp.ts"],"names":[],"mappings":"AAGA,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;AAUzD;;GAEG;AACH,qBAAa,gBAAiB,YAAW,kBAAkB;IAYvD,OAAO,CAAC,IAAI;IAXd,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,cAAc,CAAC,CAAqC;IAC5D,OAAO,CAAC,YAAY,CAAC,CAAyB;IAC9C,OAAO,CAAC,sBAAsB,CAAM;IACpC,OAAO,CAAC,KAAK,CAAU;IACvB,OAAO,CAAC,eAAe,CAAS;gBAEpB,MAAM,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,EAChD,IAAI,EAAE,aAAa;IAW7B,IAAI,WAAW,IAAI,OAAO,CAEzB;IAEK,OAAO,CAAC,MAAM,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA4G/C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB/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;YAIhC,aAAa;CA0F5B"}
|
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import * as qrcode from "qrcode-terminal";
|
|
4
|
-
async function loadBaileys() {
|
|
5
|
-
const baileys = await import("@whiskeysockets/baileys");
|
|
6
|
-
return baileys;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* WhatsApp transport provider using @whiskeysockets/baileys
|
|
10
|
-
*/
|
|
11
|
-
export class WhatsAppProvider {
|
|
12
|
-
auth;
|
|
13
|
-
type = "whatsapp";
|
|
14
|
-
socket = null;
|
|
15
|
-
_isConnected = false;
|
|
16
|
-
authPath;
|
|
17
|
-
messageHandler;
|
|
18
|
-
errorHandler;
|
|
19
|
-
lastProcessedMessageId = "";
|
|
20
|
-
debug;
|
|
21
|
-
isManualConnect = false;
|
|
22
|
-
constructor(config, auth) {
|
|
23
|
-
this.auth = auth;
|
|
24
|
-
// Default auth path to ~/.pi/msg-bridge-whatsapp-auth
|
|
25
|
-
this.authPath = config.authPath || path.join(process.env.HOME || process.env.USERPROFILE || ".", ".pi", "msg-bridge-whatsapp-auth");
|
|
26
|
-
this.debug = config.debug || false;
|
|
27
|
-
}
|
|
28
|
-
get isConnected() {
|
|
29
|
-
return this._isConnected;
|
|
30
|
-
}
|
|
31
|
-
async connect(manual = false) {
|
|
32
|
-
if (this._isConnected)
|
|
33
|
-
return;
|
|
34
|
-
this.isManualConnect = manual;
|
|
35
|
-
// Ensure auth directory exists
|
|
36
|
-
if (!fs.existsSync(this.authPath)) {
|
|
37
|
-
fs.mkdirSync(this.authPath, { recursive: true, mode: 0o700 });
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
// Ensure existing directory has secure permissions
|
|
41
|
-
try {
|
|
42
|
-
fs.chmodSync(this.authPath, 0o700);
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
console.warn("Failed to set auth directory permissions:", err);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
const baileys = await loadBaileys();
|
|
49
|
-
const { state, saveCreds } = await baileys.useMultiFileAuthState(this.authPath);
|
|
50
|
-
// Suppress Baileys logger unless debug mode
|
|
51
|
-
const silentLogger = {
|
|
52
|
-
level: 'silent',
|
|
53
|
-
child: () => silentLogger,
|
|
54
|
-
trace: () => { },
|
|
55
|
-
debug: () => { },
|
|
56
|
-
info: () => { },
|
|
57
|
-
warn: () => { },
|
|
58
|
-
error: () => { },
|
|
59
|
-
fatal: () => { },
|
|
60
|
-
};
|
|
61
|
-
this.socket = baileys.default({
|
|
62
|
-
auth: state,
|
|
63
|
-
printQRInTerminal: false, // We'll handle QR display ourselves
|
|
64
|
-
logger: this.debug ? undefined : silentLogger,
|
|
65
|
-
});
|
|
66
|
-
// Handle connection updates - set up IMMEDIATELY after socket creation
|
|
67
|
-
this.socket.ev.on("connection.update", async (update) => {
|
|
68
|
-
const { connection, lastDisconnect, qr } = update;
|
|
69
|
-
if (this.debug) {
|
|
70
|
-
console.log("[WhatsApp] connection.update event received:", JSON.stringify(update, null, 2));
|
|
71
|
-
}
|
|
72
|
-
if (qr && this.isManualConnect) {
|
|
73
|
-
console.log("\n📱 Scan this QR code with WhatsApp to authenticate:\n");
|
|
74
|
-
qrcode.generate(qr, { small: true });
|
|
75
|
-
console.log("\n");
|
|
76
|
-
}
|
|
77
|
-
if (connection === "close") {
|
|
78
|
-
const statusCode = lastDisconnect?.error?.output?.statusCode;
|
|
79
|
-
const shouldReconnect = statusCode !== baileys.DisconnectReason.loggedOut;
|
|
80
|
-
if (this.debug) {
|
|
81
|
-
console.log(`[WhatsApp] Connection closed. Status: ${statusCode}, Reconnect: ${shouldReconnect}`);
|
|
82
|
-
}
|
|
83
|
-
this._isConnected = false;
|
|
84
|
-
if (this.errorHandler && statusCode !== baileys.DisconnectReason.loggedOut) {
|
|
85
|
-
this.errorHandler(new Error(`connection closed (status ${statusCode})`));
|
|
86
|
-
}
|
|
87
|
-
// If unauthorized (401), clear invalid auth
|
|
88
|
-
if (statusCode === 401) {
|
|
89
|
-
try {
|
|
90
|
-
if (fs.existsSync(this.authPath)) {
|
|
91
|
-
fs.rmSync(this.authPath, { recursive: true, force: true });
|
|
92
|
-
if (this.isManualConnect) {
|
|
93
|
-
console.log("🔄 WhatsApp session expired. Cleared credentials. Reconnecting with QR code...");
|
|
94
|
-
// Reconnect after clearing auth to get fresh QR (manual configure only)
|
|
95
|
-
setTimeout(() => this.connect(true), 1000);
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
console.log("🔄 WhatsApp session expired. Cleared credentials. Run /msg-bridge configure whatsapp to reconnect.");
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
catch (err) {
|
|
103
|
-
console.error("Failed to clear auth:", err);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
else if (shouldReconnect) {
|
|
107
|
-
// Reconnect after 3 seconds
|
|
108
|
-
setTimeout(() => this.connect(), 3000);
|
|
109
|
-
}
|
|
110
|
-
else if (this.debug) {
|
|
111
|
-
console.warn("⚠️ WhatsApp logged out. Run /msg-bridge configure whatsapp to reconnect.");
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
else if (connection === "open") {
|
|
115
|
-
this._isConnected = true;
|
|
116
|
-
console.log("✅ WhatsApp connected!");
|
|
117
|
-
}
|
|
118
|
-
});
|
|
119
|
-
// Save credentials when updated
|
|
120
|
-
this.socket.ev.on("creds.update", saveCreds);
|
|
121
|
-
// Handle incoming messages
|
|
122
|
-
this.socket.ev.on("messages.upsert", async ({ messages, type }) => {
|
|
123
|
-
if (type !== "notify") {
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
for (const msg of messages) {
|
|
127
|
-
await this.handleMessage(msg);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
async disconnect() {
|
|
132
|
-
if (!this._isConnected || !this.socket)
|
|
133
|
-
return;
|
|
134
|
-
this.socket.end(undefined);
|
|
135
|
-
this.socket = null;
|
|
136
|
-
this._isConnected = false;
|
|
137
|
-
console.log("[WhatsApp] Disconnected");
|
|
138
|
-
}
|
|
139
|
-
async sendMessage(chatId, text) {
|
|
140
|
-
if (!this.socket) {
|
|
141
|
-
throw new Error("WhatsApp not connected");
|
|
142
|
-
}
|
|
143
|
-
if (!text?.trim())
|
|
144
|
-
return;
|
|
145
|
-
await this.socket.sendMessage(chatId, { text });
|
|
146
|
-
}
|
|
147
|
-
async sendTyping(chatId) {
|
|
148
|
-
if (!this.socket)
|
|
149
|
-
return;
|
|
150
|
-
try {
|
|
151
|
-
await this.socket.sendPresenceUpdate("composing", chatId);
|
|
152
|
-
// Auto-stop composing after 3 seconds
|
|
153
|
-
setTimeout(async () => {
|
|
154
|
-
try {
|
|
155
|
-
await this.socket?.sendPresenceUpdate("paused", chatId);
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
// Ignore
|
|
159
|
-
}
|
|
160
|
-
}, 3000);
|
|
161
|
-
}
|
|
162
|
-
catch (error) {
|
|
163
|
-
console.warn("[WhatsApp] Failed to send typing:", error);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
onMessage(handler) {
|
|
167
|
-
this.messageHandler = handler;
|
|
168
|
-
}
|
|
169
|
-
onError(handler) {
|
|
170
|
-
this.errorHandler = handler;
|
|
171
|
-
}
|
|
172
|
-
async handleMessage(msg) {
|
|
173
|
-
// Debug: log message structure
|
|
174
|
-
if (this.debug) {
|
|
175
|
-
console.log("[WhatsApp] Message received:", JSON.stringify(msg, null, 2));
|
|
176
|
-
}
|
|
177
|
-
// Skip non-text messages
|
|
178
|
-
const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text;
|
|
179
|
-
if (!text) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const messageId = msg.key.id || String(Date.now());
|
|
183
|
-
// Filter out old/duplicate messages
|
|
184
|
-
if (messageId === this.lastProcessedMessageId) {
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
this.lastProcessedMessageId = messageId;
|
|
188
|
-
const chatId = msg.key.remoteJid || "";
|
|
189
|
-
// Try multiple fields for username
|
|
190
|
-
const pushName = msg.pushName || msg.verifiedBizName || msg.key.fromMe ? "You" : "Unknown";
|
|
191
|
-
// Skip status broadcasts
|
|
192
|
-
if (chatId === "status@broadcast") {
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
// Detect if DM or group
|
|
196
|
-
// Group JIDs end with @g.us, individual JIDs end with @s.whatsapp.net
|
|
197
|
-
const isGroupChat = chatId.endsWith("@g.us");
|
|
198
|
-
const userId = chatId.split("@")[0]; // Phone number
|
|
199
|
-
// For WhatsApp, mentions work differently - we'll consider it as not mentioned for now
|
|
200
|
-
const wasMentioned = false;
|
|
201
|
-
// Check authorization
|
|
202
|
-
const sendMessageToUser = async (cId, text) => {
|
|
203
|
-
if (this.socket) {
|
|
204
|
-
await this.socket.sendMessage(cId, { text });
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
const isAuthorized = await this.auth.checkAuthorization(userId, chatId, pushName, isGroupChat, wasMentioned, sendMessageToUser, this.type);
|
|
208
|
-
// Handle admin commands and challenge codes in DM
|
|
209
|
-
if (!isGroupChat && (text.startsWith("/") || text.match(/^\d{6}$/))) {
|
|
210
|
-
const handled = await this.auth.handleAdminCommand(text, chatId, userId, async (text) => await this.sendMessage(chatId, text), this.type);
|
|
211
|
-
if (handled) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
if (!isAuthorized) {
|
|
216
|
-
return; // Auth handler already sent challenge/error messages
|
|
217
|
-
}
|
|
218
|
-
// Forward to message handler
|
|
219
|
-
if (this.messageHandler) {
|
|
220
|
-
const externalMessage = {
|
|
221
|
-
chatId,
|
|
222
|
-
transport: this.type,
|
|
223
|
-
content: text.trim(),
|
|
224
|
-
username: pushName,
|
|
225
|
-
userId,
|
|
226
|
-
timestamp: new Date(Number(msg.messageTimestamp) * 1000),
|
|
227
|
-
messageId,
|
|
228
|
-
isGroupChat,
|
|
229
|
-
wasMentioned,
|
|
230
|
-
};
|
|
231
|
-
this.messageHandler(externalMessage);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
//# sourceMappingURL=whatsapp.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"whatsapp.js","sourceRoot":"","sources":["../../src/transports/whatsapp.ts"],"names":[],"mappings":"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"}
|