Skip to content

Commit d01881e

Browse files
authored
Merge pull request #3608 from elizaOS/tcm/fix-discord
fix: discord actions
2 parents ae51d2f + cb0b9e8 commit d01881e

File tree

8 files changed

+145
-133
lines changed

8 files changed

+145
-133
lines changed

packages/plugin-discord/src/actions/chatWithAttachments.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,10 @@ ${currentSummary.trim()}
220220
`;
221221
await callback(callbackData);
222222
} else if (currentSummary.trim()) {
223-
const summaryFilename = `content/summary_${Date.now()}.md`;
224-
223+
const summaryDir = "content";
224+
const summaryFilename = `${summaryDir}/summary_${Date.now()}.md`;
225225
try {
226+
await fs.promises.mkdir(summaryDir, { recursive: true });
226227
// Debug: Log before file operations
227228
console.log("Creating summary file:", {
228229
filename: summaryFilename,

packages/plugin-discord/src/actions/dm.ts

+21-8
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const dmAction: Action = {
2424
state: State
2525
): Promise<boolean> => {
2626
const discordMessage = state.discordMessage as Message;
27-
if (!discordMessage.guild?.id) {
27+
if (!discordMessage?.guild?.id && !discordMessage?.guildId) {
2828
return false;
2929
}
3030

@@ -55,8 +55,9 @@ const dmAction: Action = {
5555
const discordMessage = state.discordMessage as Message;
5656

5757
try {
58+
const discordClient = runtime.getClient("discord");
5859
// Get mentioned user
59-
const mentionedUser = discordMessage?.mentions?.users?.first();
60+
const mentionedUser = discordMessage?.mentions?.users?.filter(user => user.id !== discordClient.client.user.id)?.first();
6061
if (!mentionedUser) {
6162
await callback({
6263
text: "Please mention the user you want me to DM.",
@@ -84,19 +85,31 @@ const dmAction: Action = {
8485
try {
8586
// Send message to DM channel
8687
await dmChannel.send(content);
87-
88-
// Create memory of the DM
89-
await runtime.messageManager.createMemory({
88+
89+
const dmRoomId = stringToUuid(dmChannel.id + "-" + runtime.agentId)
90+
const userIdUUID = stringToUuid(runtime.agentId);
91+
await runtime.ensureConnection(
92+
userIdUUID,
93+
dmRoomId,
94+
mentionedUser.username,
95+
mentionedUser.username,
96+
"discord-dm"
97+
);
98+
const memory: Memory = {
99+
id: stringToUuid(dmMessage.id + "-" + runtime.agentId),
90100
userId: runtime.agentId,
91101
agentId: runtime.agentId,
92-
roomId: stringToUuid(dmChannel.id),
102+
roomId: dmRoomId,
93103
content: {
94104
text: content,
95105
action: "DM",
96106
source: "discord"
97107
},
98-
createdAt: Date.now()
99-
});
108+
createdAt: Date.now(),
109+
};
110+
111+
// Create memory of the DM
112+
await runtime.messageManager.createMemory(memory);
100113

101114
// Send confirmation in original channel
102115
await callback({

packages/plugin-discord/src/actions/joinvoice.ts

+22-40
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import {
1919
type Guild,
2020
type GuildMember,
2121
} from "discord.js";
22-
import { joinVoiceChannel } from "@discordjs/voice";
22+
23+
import { DiscordClient } from "../index.ts";
2324

2425
export default {
2526
name: "JOIN_VOICE",
@@ -82,6 +83,7 @@ export default {
8283
): Promise<boolean> => {
8384
if (!state) {
8485
console.error("State is not available.");
86+
return false;
8587
}
8688

8789
for (const response of responses) {
@@ -95,15 +97,20 @@ export default {
9597
if (!discordMessage.content) {
9698
discordMessage.content = message.content.text;
9799
}
98-
100+
const discordClient = runtime.getClient("discord") as DiscordClient;
101+
const voiceManager = discordClient?.voiceManager;
102+
if (!voiceManager) {
103+
console.error("voiceManager is not available.");
104+
return false;
105+
}
99106
const id = (discordMessage as DiscordMessage).guild?.id as string;
100107
const client = state.discordClient as Client;
101108
const voiceChannels = (
102109
client.guilds.cache.get(id) as Guild
103110
).channels.cache.filter(
104111
(channel: Channel) => channel.type === ChannelType.GuildVoice
105112
);
106-
113+
107114
const messageContent = discordMessage.content;
108115

109116
const targetChannel = voiceChannels.find((channel) => {
@@ -121,30 +128,13 @@ export default {
121128
});
122129

123130
if (targetChannel) {
124-
joinVoiceChannel({
125-
channelId: targetChannel.id,
126-
guildId: (discordMessage as DiscordMessage).guild?.id as string,
127-
adapterCreator: (client.guilds.cache.get(id) as Guild)
128-
.voiceAdapterCreator,
129-
selfDeaf: false,
130-
selfMute: false,
131-
group: client.user.id,
132-
});
131+
await voiceManager.joinChannel(targetChannel);
133132
return true;
134133
} else {
135134
const member = (discordMessage as DiscordMessage)
136135
.member as GuildMember;
137136
if (member?.voice?.channel) {
138-
joinVoiceChannel({
139-
channelId: member.voice.channel.id,
140-
guildId: (discordMessage as DiscordMessage).guild
141-
?.id as string,
142-
adapterCreator: (client.guilds.cache.get(id) as Guild)
143-
.voiceAdapterCreator,
144-
selfDeaf: false,
145-
selfMute: false,
146-
group: client.user.id,
147-
});
137+
await voiceManager.joinChannel(member?.voice?.channel);
148138
return true;
149139
}
150140

@@ -172,20 +162,21 @@ You should only respond with the name of the voice channel or none, no commentar
172162
state: guessState as unknown as State,
173163
});
174164

175-
const _datestr = new Date().toUTCString().replace(/:/g, "-");
176-
177165
const responseContent = await generateText({
178166
runtime,
179167
context,
180168
modelClass: ModelClass.TEXT_SMALL,
181169
});
182170

183-
runtime.databaseAdapter.log({
184-
body: { message, context, response: responseContent },
185-
userId: stringToUuid(message.userId),
186-
roomId: message.roomId,
187-
type: "joinVoice",
188-
});
171+
// FIXME: App crashes due to a missing import for `stringToUuid`.
172+
// However, even after importing it, the crash still occurs.
173+
// Temporarily commenting out this logging code until the root cause is investigated.
174+
// runtime.databaseAdapter.log({
175+
// body: { message, context, response: responseContent },
176+
// userId: stringToUuid(message.userId),
177+
// roomId: message.roomId,
178+
// type: "joinVoice",
179+
// });
189180

190181
if (responseContent && responseContent.trim().length > 0) {
191182
// join the voice channel
@@ -208,16 +199,7 @@ You should only respond with the name of the voice channel or none, no commentar
208199
});
209200

210201
if (targetChannel) {
211-
joinVoiceChannel({
212-
channelId: targetChannel.id,
213-
guildId: (discordMessage as DiscordMessage).guild
214-
?.id as string,
215-
adapterCreator: (client.guilds.cache.get(id) as Guild)
216-
.voiceAdapterCreator,
217-
selfDeaf: false,
218-
selfMute: false,
219-
group: client.user.id,
220-
});
202+
await voiceManager.joinChannel(targetChannel);
221203
return true;
222204
}
223205
}

packages/plugin-discord/src/actions/leavevoice.ts

+30-21
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// src/actions/leaveVoice
2-
import { getVoiceConnection } from "@discordjs/voice";
32
import {
4-
type Channel,
5-
ChannelType,
63
type Client,
7-
type Message as DiscordMessage,
4+
BaseGuildVoiceChannel,
85
} from "discord.js";
96
import type {
107
Action,
@@ -15,6 +12,8 @@ import type {
1512
State,
1613
} from "@elizaos/core";
1714

15+
import { DiscordClient } from "../index.ts";
16+
1817
export default {
1918
name: "LEAVE_VOICE",
2019
similes: [
@@ -86,26 +85,36 @@ export default {
8685
await callback(response.content);
8786
}
8887

89-
const discordMessage = (state.discordMessage ||
90-
state.discordChannel) as DiscordMessage;
88+
const discordClient = runtime.getClient("discord") as DiscordClient;
89+
const voiceManager = discordClient?.voiceManager;
90+
if (!voiceManager) {
91+
console.error("voiceManager is not available.");
92+
return false;
93+
}
94+
95+
const guild = state.discordClient.guilds.cache.find(
96+
(g) => g.members.me?.voice.channelId
97+
);
98+
99+
if (!guild) {
100+
console.warn("Bot is not in any voice channel.");
101+
return false;
102+
}
103+
104+
const voiceChannel = guild.members.me?.voice.channel;
105+
if (!voiceChannel || !(voiceChannel instanceof BaseGuildVoiceChannel)) {
106+
console.warn("Could not retrieve the voice channel.");
107+
return false;
108+
}
91109

92-
if (!discordMessage) {
93-
throw new Error("Discord message is not available in the state.");
110+
const connection = voiceManager.getVoiceConnection(guild.id);
111+
if (!connection) {
112+
console.warn("No active voice connection found for the bot.");
113+
return false;
94114
}
95-
const voiceChannels = (state.discordClient as Client)?.guilds.cache
96-
.get((discordMessage as DiscordMessage).guild?.id as string)
97-
?.channels.cache.filter(
98-
(channel: Channel) => channel.type === ChannelType.GuildVoice
99-
);
100115

101-
voiceChannels?.forEach((_channel: Channel) => {
102-
const connection = getVoiceConnection(
103-
(discordMessage as DiscordMessage).guild?.id as string
104-
);
105-
if (connection) {
106-
connection.destroy();
107-
}
108-
});
116+
voiceManager.leaveChannel(voiceChannel);
117+
109118
return true;
110119
},
111120
examples: [

packages/plugin-discord/src/actions/summarizeConversation.ts

+10-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
ModelClass,
1414
type State,
1515
} from "@elizaos/core";
16+
import * as fs from "fs";
1617
export const summarizationTemplate = `# Summarized so far (we are adding to this)
1718
{{currentSummary}}
1819
@@ -303,8 +304,16 @@ ${currentSummary.trim()}
303304
`;
304305
await callback(callbackData);
305306
} else if (currentSummary.trim()) {
306-
const summaryFilename = `content/conversation_summary_${Date.now()}`;
307+
const summaryDir = "content";
308+
const summaryFilename = `${summaryDir}/conversation_summary_${Date.now()}`;
307309
await runtime.cacheManager.set(summaryFilename, currentSummary);
310+
await fs.promises.mkdir(summaryDir, { recursive: true });
311+
312+
await fs.promises.writeFile(
313+
summaryFilename,
314+
currentSummary,
315+
"utf8"
316+
);
308317
// save the summary to a file
309318
await callback(
310319
{

packages/plugin-discord/src/index.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ import {
1818
} from "discord.js";
1919
import { EventEmitter } from "events";
2020
import chatWithAttachments from "./actions/chatWithAttachments.ts";
21-
import downloadMedia from "./actions/downloadMedia.ts";
21+
// import downloadMedia from "./actions/downloadMedia.ts";
2222
import joinVoice from "./actions/joinVoice.ts";
2323
import leaveVoice from "./actions/leaveVoice.ts";
2424
import reply from "./actions/reply.ts";
2525
import summarize from "./actions/summarizeConversation.ts";
2626
import transcribe_media from "./actions/transcribeMedia.ts";
27+
import dmAction from "./actions/dm.ts";
2728
import { DISCORD_CLIENT_NAME } from "./constants.ts";
2829
import { MessageManager } from "./messages.ts";
2930
import channelStateProvider from "./providers/channelState.ts";
@@ -410,11 +411,12 @@ const discordPlugin: Plugin = {
410411
actions: [
411412
reply,
412413
chatWithAttachments,
413-
downloadMedia,
414+
// downloadMedia,
414415
joinVoice,
415416
leaveVoice,
416417
summarize,
417418
transcribe_media,
419+
dmAction
418420
],
419421
providers: [channelStateProvider, voiceStateProvider],
420422
tests: [new DiscordTestSuite()],

0 commit comments

Comments
 (0)