@saccolabs/tars 1.19.4 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Client, GatewayIntentBits,
|
|
1
|
+
import { Client, GatewayIntentBits, Partials } from 'discord.js';
|
|
2
2
|
import { Config } from '../../config/config.js';
|
|
3
3
|
import logger from '../../utils/logger.js';
|
|
4
4
|
import { MessageFormatter } from './message-formatter.js';
|
|
@@ -23,7 +23,7 @@ export class DiscordChannel {
|
|
|
23
23
|
GatewayIntentBits.MessageContent,
|
|
24
24
|
GatewayIntentBits.DirectMessages
|
|
25
25
|
],
|
|
26
|
-
partials: [Partials.Channel, Partials.Message]
|
|
26
|
+
partials: [Partials.Channel, Partials.Message, Partials.User]
|
|
27
27
|
});
|
|
28
28
|
this.setupEventHandlers();
|
|
29
29
|
}
|
|
@@ -101,94 +101,130 @@ export class DiscordChannel {
|
|
|
101
101
|
}
|
|
102
102
|
});
|
|
103
103
|
this.client.on('messageCreate', this.handleIncomingMessage.bind(this));
|
|
104
|
+
// --- DM Rescue Fallback ---
|
|
105
|
+
// discord.js v14 silently drops DMs if the user/channel has no prior cache history
|
|
106
|
+
// on the current instance runtime. We intercept raw packets to rescue them.
|
|
107
|
+
this.client.on('raw', async (packet) => {
|
|
108
|
+
if (packet.t !== 'MESSAGE_CREATE')
|
|
109
|
+
return;
|
|
110
|
+
const data = packet.d;
|
|
111
|
+
// Only rescue DMs (they lack a guild_id) from real users
|
|
112
|
+
if (data.guild_id || data.author?.bot)
|
|
113
|
+
return;
|
|
114
|
+
// If the channel IS cached, discord.js will successfully emit the standard
|
|
115
|
+
// 'messageCreate' event. We step entirely out of the way.
|
|
116
|
+
const isCached = this.client.channels.cache.has(data.channel_id);
|
|
117
|
+
if (isCached)
|
|
118
|
+
return;
|
|
119
|
+
// Channel is uncached. discord.js will drop this. Rescue it manually.
|
|
120
|
+
try {
|
|
121
|
+
logger.debug(`[DM Rescue] Intercepted dropped payload from ${data.author.username}. Hydrating...`);
|
|
122
|
+
const channel = await this.client.channels.fetch(data.channel_id);
|
|
123
|
+
if (channel && channel.isTextBased()) {
|
|
124
|
+
const message = await channel.messages.fetch(data.id);
|
|
125
|
+
logger.info(`[DM Rescue] Successfully hydrated message. Forwarding to bot logic.`);
|
|
126
|
+
await this.handleIncomingMessage(message);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
logger.error(`❌ [DM Rescue] Failed to hydrate dropped message: ${err.message}`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
104
133
|
}
|
|
105
134
|
/**
|
|
106
135
|
* Internal handler for Discord-specific messages
|
|
107
136
|
*/
|
|
108
137
|
async handleIncomingMessage(message) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
try {
|
|
139
|
+
logger.debug(`📥 Received Discord message: "${message.content.substring(0, 50)}${message.content.length > 50 ? '...' : ''}" from ${message.author?.tag || 'Unknown'} (Guild: ${message.guildId || 'DM'})`);
|
|
140
|
+
// Guard against partial messages with missing author data
|
|
141
|
+
if (!message.author || message.author.bot || !this.messageHandler)
|
|
142
|
+
return;
|
|
143
|
+
const userPrompt = this.extractPrompt(message);
|
|
144
|
+
if (userPrompt === null)
|
|
145
|
+
return;
|
|
146
|
+
// Auto-Bind on first interaction if not set
|
|
147
|
+
const wasAutoBound = !this.config.discordOwnerId;
|
|
148
|
+
if (wasAutoBound) {
|
|
149
|
+
this.config.discordOwnerId = message.author.id;
|
|
150
|
+
if (this.config.channels.discord) {
|
|
151
|
+
this.config.channels.discord.ownerId = message.author.id;
|
|
152
|
+
}
|
|
153
|
+
this.config.saveSettings();
|
|
154
|
+
logger.info(`🔒 Automatically bound Primary Contact to Discord user: ${message.author.id} (Channel: ${message.channelId})`);
|
|
120
155
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
if (!userPrompt && message.attachments.size === 0)
|
|
157
|
+
return;
|
|
158
|
+
// Handle Attachments
|
|
159
|
+
const attachments = [];
|
|
160
|
+
if (message.attachments.size > 0) {
|
|
161
|
+
for (const [id, attachment] of message.attachments) {
|
|
162
|
+
try {
|
|
163
|
+
const filePath = await this.processor.download(attachment);
|
|
164
|
+
if (attachment.contentType) {
|
|
165
|
+
attachments.push({
|
|
166
|
+
path: filePath,
|
|
167
|
+
mimeType: attachment.contentType
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
logger.error(`Failed to download Discord attachment: ${err.message}`);
|
|
137
173
|
}
|
|
138
|
-
}
|
|
139
|
-
catch (err) {
|
|
140
|
-
logger.error(`Failed to download Discord attachment: ${err.message}`);
|
|
141
174
|
}
|
|
142
175
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
const filePath = this.processor.saveResponse(response, 'md');
|
|
156
|
-
await message.reply({
|
|
157
|
-
content: `📄 **Response too long** (${formatted.length} chars). See attached file:`,
|
|
158
|
-
files: [filePath, ...(outAttachments || [])]
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
else {
|
|
162
|
-
const chunks = MessageFormatter.split(formatted);
|
|
163
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
176
|
+
// Map to common ChannelMessage
|
|
177
|
+
const channelMessage = {
|
|
178
|
+
content: userPrompt,
|
|
179
|
+
senderId: message.author.id,
|
|
180
|
+
senderName: message.author.username,
|
|
181
|
+
channelId: message.channelId,
|
|
182
|
+
attachments,
|
|
183
|
+
metadata: { wasAutoBound },
|
|
184
|
+
reply: async (response, outAttachments) => {
|
|
185
|
+
const formatted = MessageFormatter.format(response);
|
|
186
|
+
if (formatted.length > 8000) {
|
|
187
|
+
const filePath = this.processor.saveResponse(response, 'md');
|
|
164
188
|
await message.reply({
|
|
165
|
-
content:
|
|
166
|
-
files:
|
|
189
|
+
content: `📄 **Response too long** (${formatted.length} chars). See attached file:`,
|
|
190
|
+
files: [filePath, ...(outAttachments || [])]
|
|
167
191
|
});
|
|
168
192
|
}
|
|
193
|
+
else {
|
|
194
|
+
const chunks = MessageFormatter.split(formatted);
|
|
195
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
196
|
+
await message.reply({
|
|
197
|
+
content: chunks[i],
|
|
198
|
+
files: i === chunks.length - 1 ? outAttachments || [] : []
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
startTyping: () => {
|
|
204
|
+
const channelId = message.channelId;
|
|
205
|
+
if (this.typingIntervals.has(channelId))
|
|
206
|
+
return;
|
|
207
|
+
// Send first one immediately
|
|
208
|
+
if ('sendTyping' in message.channel) {
|
|
209
|
+
message.channel.sendTyping().catch(() => { });
|
|
210
|
+
const interval = setInterval(() => {
|
|
211
|
+
message.channel.sendTyping().catch(() => {
|
|
212
|
+
this.stopTypingInternal(channelId);
|
|
213
|
+
});
|
|
214
|
+
}, 5000); // Discord typing state lasts ~10s, we refresh every 5s
|
|
215
|
+
this.typingIntervals.set(channelId, interval);
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
stopTyping: () => {
|
|
219
|
+
this.stopTypingInternal(message.channelId);
|
|
169
220
|
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
message.channel.sendTyping().catch(() => { });
|
|
178
|
-
const interval = setInterval(() => {
|
|
179
|
-
message.channel.sendTyping().catch(() => {
|
|
180
|
-
this.stopTypingInternal(channelId);
|
|
181
|
-
});
|
|
182
|
-
}, 5000); // Discord typing state lasts ~10s, we refresh every 5s
|
|
183
|
-
this.typingIntervals.set(channelId, interval);
|
|
184
|
-
}
|
|
185
|
-
},
|
|
186
|
-
stopTyping: () => {
|
|
187
|
-
this.stopTypingInternal(message.channelId);
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
// Forward to the registered handler (Supervisor via ChannelManager)
|
|
191
|
-
await this.messageHandler(channelMessage);
|
|
221
|
+
};
|
|
222
|
+
// Forward to the registered handler (Supervisor via ChannelManager)
|
|
223
|
+
await this.messageHandler(channelMessage);
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
logger.error(`❌ Discord message handler error: ${error.message}`);
|
|
227
|
+
}
|
|
192
228
|
}
|
|
193
229
|
stopTypingInternal(channelId) {
|
|
194
230
|
const interval = this.typingIntervals.get(channelId);
|
|
@@ -201,7 +237,7 @@ export class DiscordChannel {
|
|
|
201
237
|
* Extract prompt and handle prefix
|
|
202
238
|
*/
|
|
203
239
|
extractPrompt(message) {
|
|
204
|
-
const isDM = message.
|
|
240
|
+
const isDM = !message.guildId;
|
|
205
241
|
const isMentioned = this.client.user && message.mentions.has(this.client.user);
|
|
206
242
|
const customPrefix = `!${this.config.assistantName.toLowerCase()}`;
|
|
207
243
|
const hasCustomCommand = message.content.toLowerCase().startsWith(customPrefix);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discord-channel.js","sourceRoot":"","sources":["../../../src/channels/discord/discord-channel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"discord-channel.js","sourceRoot":"","sources":["../../../src/channels/discord/discord-channel.ts"],"names":[],"mappings":"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"}
|