Skip to content

Commit

Permalink
Add translation feature to message context menu (#810)
Browse files Browse the repository at this point in the history
* feat(translate): Adds translate feature

* cleanup(translate): cleaned up code and comments

---------

Co-authored-by: LunaUrsa <[email protected]>
  • Loading branch information
theimperious1 and LunaUrsa authored Aug 5, 2024
1 parent a930dd4 commit ff30576
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/discord/commands/global/m.translate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import {
ContextMenuCommandBuilder,
Colors,
} from 'discord.js';
import {
ApplicationCommandType,
} from 'discord-api-types/v10';
import OpenAI from 'openai';
import { MessageCommand } from '../../@types/commandDef';
import { embedTemplate } from '../../utils/embedTemplate';
import { aiTranslate } from '../../../global/commands/g.ai';

const F = f(__filename);

export const mTranslate: MessageCommand = {
data: new ContextMenuCommandBuilder()
.setName('Translate')
.setType(ApplicationCommandType.Message),
async execute(interaction) {
if (!interaction.guild) return false;
log.info(F, await commandContext(interaction));
await interaction.deferReply({ ephemeral: true });

const targetMessage = interaction.targetMessage.content;

const messageList = [{
role: 'user',
content: targetMessage,
}] as OpenAI.Chat.ChatCompletionMessageParam[];

// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { response, promptTokens, completionTokens } = await aiTranslate('English', messageList);
await interaction.editReply({
embeds: [embedTemplate()
.setTitle('Here\'s your translation!')
.setDescription(response)
.setColor(Colors.Blurple)],
});
return true;
},
};

export default mTranslate;
57 changes: 57 additions & 0 deletions src/global/commands/g.ai.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1022,3 +1022,60 @@ export async function aiModerate(

return moderationAlerts;
}

export async function aiTranslate(
target_language: string,
messages: OpenAI.Chat.ChatCompletionMessageParam [],
):Promise<{
response: string,
promptTokens: number,
completionTokens: number,
}> {
let response = '';
let promptTokens = 0;
let completionTokens = 0;
if (!env.OPENAI_API_ORG || !env.OPENAI_API_KEY) return { response, promptTokens, completionTokens };

const model = 'gpt-3.5-turbo-1106';
const chatCompletionMessages = [{
role: 'system',
content: `You will translate whatever the user sends to their desired language. Their desired language or language code is: ${target_language}.`,
}] as OpenAI.Chat.ChatCompletionMessageParam[];
chatCompletionMessages.push(...messages);

const payload = {
model,
messages: chatCompletionMessages,
} as OpenAI.Chat.ChatCompletionCreateParamsNonStreaming;

// log.debug(F, `payload: ${JSON.stringify(payload, null, 2)}`);
let responseMessage = {} as OpenAI.Chat.ChatCompletionMessageParam;

const chatCompletion = await openAi.chat.completions
.create(payload)
.catch(err => {
if (err instanceof OpenAI.APIError) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
log.error(F, `${err.name} - ${err.status} - ${err.type} - ${(err.error as any).message} `); // 400
// log.error (F, `${JSON.stringify(err.headers, null, 2)}`); // {server: 'nginx', ...}
// log.error(F, `${JSON.stringify(err, null, 2)}`); // {server: 'nginx', ...}
} else {
throw err;
}
});
// log.debug(F, `chatCompletion: ${JSON.stringify(chatCompletion, null, 2)}`);

if (chatCompletion?.choices[0].message) {
responseMessage = chatCompletion.choices[0].message;

// Sum up the existing tokens
promptTokens = chatCompletion.usage?.prompt_tokens ?? 0;
completionTokens = chatCompletion.usage?.completion_tokens ?? 0;

response = responseMessage.content ?? 'Sorry, I\'m not sure how to respond to that.';
}

// log.debug(F, `response: ${response}`);

return { response, promptTokens, completionTokens };
}

0 comments on commit ff30576

Please sign in to comment.