Skip to content

Commit

Permalink
fix: chat history not working
Browse files Browse the repository at this point in the history
  • Loading branch information
perzeuss committed Mar 9, 2024
1 parent 49d70ad commit 9be84f7
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ Set it to `user` if you want the bot to enable an own chat history for every use
### History per channel
Set it to `channel` if you want the bot to enable a history for channels. The assistant will remember every message in the channe regardless from which user it came. You should use the dify variable "username" to allow the bot recognize the author of messages, otherwise the assistant will think all messages come from the same user.

Hint: If you use this, the userId of messages will no longer be the user but the server id, since dify does store conversations per user - if you share conversations accross users, you cannot pass the userid since dify would still create a unique conversation per user.


## Contributing 🤝

Expand Down
48 changes: 35 additions & 13 deletions src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class DiscordBot {
private client: Client;
private difyClient: DifyChatClient;
private readonly TOKEN: string;
private readonly CACHE_MODE: string;
private readonly HISTORY_MODE: string;
private readonly MAX_MESSAGE_LENGTH: number;

constructor() {
this.TOKEN = process.env.DISCORD_BOT_TOKEN || '';
this.CACHE_MODE = process.env.CACHE_MODE || '';
this.HISTORY_MODE = process.env.HISTORY_MODE || '';
this.MAX_MESSAGE_LENGTH = Number(process.env.MAX_MESSAGE_LENGTH) || 2000;
if (!this.TOKEN) {
throw new Error('DISCORD_BOT_TOKEN must be provided in the .env file');
Expand Down Expand Up @@ -49,7 +49,7 @@ class DiscordBot {
if (interaction.commandName === 'chat') {
await this.handleChatCommand(interaction);
} else if (interaction.commandName === 'new-conversation') {
const cacheId = this.CACHE_MODE && this.CACHE_MODE === 'user' ? interaction.user.id : interaction.channelId;
const cacheId = this.HISTORY_MODE && this.HISTORY_MODE === 'user' ? interaction.user.id : interaction.channelId;
conversationCache.delete(cacheId);
await interaction.reply('New conversation started!');
}
Expand Down Expand Up @@ -100,21 +100,21 @@ class DiscordBot {
await interaction.deferReply({ ephemeral: true });

const message = interaction.options.get('message', true);
const cacheId = this.CACHE_MODE && this.CACHE_MODE === 'user' ? interaction.user.id : interaction.channelId;
const cacheKey = this.getCacheKey(interaction.user.id, interaction.channel?.id);

try {
const difyResponse = await this.difyClient.createChatMessage({ inputs: { username: interaction.user.globalName || interaction.user.username }, query: message.value! as string, response_mode: 'blocking', conversation_id: cacheId && conversationCache.get(cacheId) || '', user: interaction.user.id });
const difyResponse = await this.difyClient.createChatMessage({ inputs: { username: interaction.user.globalName || interaction.user.username }, query: message.value! as string, response_mode: 'blocking', conversation_id: cacheKey && conversationCache.get(cacheKey) || '', user: this.getUserId(interaction.user.id, interaction.guild?.id) });

if (cacheId) {
conversationCache.set(cacheId, difyResponse.conversation_id);
if (cacheKey) {
conversationCache.set(cacheKey, difyResponse.conversation_id);
}

const messages = this.splitMessage(difyResponse.answer, { maxLength: this.MAX_MESSAGE_LENGTH });
for (const [index, m] of messages.entries()) {
if (index === 0) {
await interaction.editReply({ content: m });
} else {
await interaction.followUp({ content: m, ephemeral: true});
await interaction.followUp({ content: m, ephemeral: true });
}
}
} catch (error) {
Expand All @@ -124,26 +124,48 @@ class DiscordBot {
}

private async handleChatMessage(message: Message) {
const cacheId = this.CACHE_MODE && this.CACHE_MODE === 'user' ? message.author.id : message.channelId;
const cacheKey = this.getCacheKey(message.author.id, message.channelId);

try {
message.channel.sendTyping().catch(console.error);
const difyResponse = await this.difyClient.createChatMessage({ inputs: { username: message.author.globalName || message.author.username }, query: message.content.replace(`<@${this.client.user?.id}>`, ''), response_mode: 'blocking', conversation_id: cacheId && conversationCache.get(cacheId) || '', user: message.author.id });
const difyResponse = await this.difyClient.createChatMessage({ inputs: { username: message.author.globalName || message.author.username }, query: message.content.replace(`<@${this.client.user?.id}>`, ''), response_mode: 'blocking', conversation_id: cacheKey && conversationCache.get(cacheKey) || '', user: this.getUserId(message.author.id, message.guild?.id) });

if (cacheId) {
conversationCache.set(cacheId, difyResponse.conversation_id);
if (cacheKey) {
conversationCache.set(cacheKey, difyResponse.conversation_id);
}

const messages = this.splitMessage(difyResponse.answer, { maxLength: this.MAX_MESSAGE_LENGTH });
for (const m of messages) {
await message.reply(m);
}
} catch (error) {
} catch (error: any) {
console.error('Error sending message to Dify:', error);
await message.reply('Sorry, something went wrong while generating the answer.');
}
}

private getCacheKey(userId: string | undefined, channelId: string | undefined) {
switch (this.HISTORY_MODE) {
case 'user':
return userId || ''
case 'channel':
return channelId || ''
default:
return ''
}
}

private getUserId(userId: string | undefined, serverId: string | undefined) {
switch (this.HISTORY_MODE) {
case 'user':
return userId || ''
case 'channel':
return serverId || ''
default:
return ''
}
}

splitMessage(message: string, options: { maxLength?: number, char?: string, prepend?: string, append?: string } = {}): string[] {
const { maxLength = 2000, char = '\n', prepend = '', append = '' } = options;
if (message.length <= maxLength) return [message];
Expand Down

0 comments on commit 9be84f7

Please sign in to comment.