Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ By selecting quick replies instead of typing manually, agents/users can respond
- **`/quick ai`**: Use AI to generate replies
- **`/quick help`**: Get help with Quick Reply
- **`/qs <reply name>`**: Quickly search and send a reply by name
- **`/quick grammar <text>`**: Correct grammar using AI

### Using Placeholders:

Expand Down
20 changes: 8 additions & 12 deletions src/commands/CommandUtility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,21 +65,14 @@ export class CommandUtility implements ICommandUtility {
triggerId: this.triggerId,
threadId: this.threadId,
language,
params: this.params,
});

switch (this.params.length) {
case 0: {
await handler.sendDefault();
break;
}
case 1: {
await this.handleSingleParam(handler);
break;
}
default: {
await handler.sendDefault();
}
if (this.params.length === 0) {
await handler.sendDefault();
return;
}
await this.handleSingleParam(handler);
}

private async handleSingleParam(handler: Handler): Promise<void> {
Expand All @@ -101,6 +94,9 @@ export class CommandUtility implements ICommandUtility {
case CommandParam.AI:
await handler.replyUsingAI();
break;
case CommandParam.GRAMMAR:
await handler.CorrectGrammarUsingAI();
break;
default: {
await handler.sendDefault();
break;
Expand Down
1 change: 1 addition & 0 deletions src/definition/handlers/IHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export interface IHandler extends Omit<ICommandUtilityParams, 'params'> {

export type IHanderParams = Omit<ICommandUtilityParams, 'params'> & {
language: Language;
params?: string[]
};
1 change: 1 addition & 0 deletions src/enum/CommandParam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export enum CommandParam {
AI = 'ai',
DELETE = 'delete',
EDIT = 'edit',
GRAMMAR = 'grammar',
SEND = 'send',
}
85 changes: 41 additions & 44 deletions src/handlers/AIHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
IHttp,
IHttpResponse,
} from '@rocket.chat/apps-engine/definition/accessors';
import { IUser } from '@rocket.chat/apps-engine/definition/users';
import { QuickRepliesApp } from '../../QuickRepliesApp';
import { SettingEnum } from '../config/settings';
import {
Expand All @@ -21,55 +20,57 @@ class AIHandler {
private language = this.userPreference.language;

public async handleResponse(
user: IUser,
message: string,
prompt: string,
correctGrammar?: boolean,
): Promise<string> {
let aiProvider: string;
if (
this.userPreference.AIusagePreference ===
AIusagePreferenceEnum.Personal
this.userPreference.AIusagePreference ===
AIusagePreferenceEnum.Personal
) {
aiProvider = this.userPreference.AIconfiguration.AIProvider;
aiProvider = this.userPreference.AIconfiguration.AIProvider;
} else {
aiProvider = await this.app
.getAccessors()
.environmentReader.getSettings()
.getValueById(SettingEnum.AI_PROVIDER_OPTOIN_ID);
aiProvider = await this.app
.getAccessors()
.environmentReader.getSettings()
.getValueById(SettingEnum.AI_PROVIDER_OPTOIN_ID);
}


const content = correctGrammar ? this.getGrammarFixPrompt(message) : this.getAIResponsePrompt(message, prompt)
switch (aiProvider) {
case AIProviderEnum.SelfHosted:
case SettingEnum.SELF_HOSTED_MODEL:
return this.handleSelfHostedModel(user, message, prompt);

case AIProviderEnum.OpenAI:
case SettingEnum.OPEN_AI:
return this.handleOpenAI(user, message, prompt);

case AIProviderEnum.Gemini:
case SettingEnum.GEMINI:
return this.handleGemini(user, message, prompt);

default:
const errorMsg =
this.userPreference.AIusagePreference ===
AIusagePreferenceEnum.Personal
? t('AI_Not_Configured_Personal', this.language)
: t('AI_Not_Configured_Admin', this.language);

this.app.getLogger().log(errorMsg);
return errorMsg;
case AIProviderEnum.SelfHosted:
case SettingEnum.SELF_HOSTED_MODEL:
return this.handleSelfHostedModel(content);
case AIProviderEnum.OpenAI:
case SettingEnum.OPEN_AI:
return this.handleOpenAI(content);
case AIProviderEnum.Gemini:
case SettingEnum.GEMINI:
return this.handleGemini(content);
default:
const errorMsg =
this.userPreference.AIusagePreference ===
AIusagePreferenceEnum.Personal
? t('AI_Not_Configured_Personal', this.language)
: t('AI_Not_Configured_Admin', this.language);
this.app.getLogger().log(errorMsg);
return errorMsg;
}

}

private getPrompt(message: string, prompt: string): string {
return `Write a reply to this message: "${message}".Reply must be ${this.userPreference.AIconfiguration.AIPromptOptions} Use the as a prompt or response reply: "${prompt}" and make sure you respond with just the reply without quotes.`;
private getAIResponsePrompt(message: string, prompt: string): string {
return `You are a function that generates responses from a message and prompt message is : "${message}". ${this.userPreference.AIconfiguration.AIPromptOptions} and Use the following as a prompt : "${prompt}" and make sure you respond with just the reply without quotes.`;
}
private getGrammarFixPrompt(message: string): string {
return `You are a function that corrects grammar and spelling only. Fix any grammar errors, spelling mistakes, and punctuation in this message: "${message}". Return only the corrected text as a single string. Make no other changes to the content or meaning - just fix grammar and spelling issues.`;
}

private async handleSelfHostedModel(
user: IUser,
message: string,
prompt: string,
): Promise<string> {
try {
Expand Down Expand Up @@ -97,7 +98,7 @@ class AIHandler {
messages: [
{
role: 'system',
content: this.getPrompt(message, prompt),
content: prompt,
},
],
temperature: 0,
Expand Down Expand Up @@ -142,8 +143,6 @@ class AIHandler {
}

private async handleOpenAI(
user: IUser,
message: string,
prompt: string,
): Promise<string> {
try {
Expand Down Expand Up @@ -172,7 +171,7 @@ class AIHandler {
messages: [
{
role: 'system',
content: this.getPrompt(message, prompt),
content: prompt,
},
],
}),
Expand Down Expand Up @@ -219,8 +218,6 @@ class AIHandler {
}
}
private async handleGemini(
user: IUser,
message: string,
prompt: string,
): Promise<string> {
try {
Expand All @@ -239,7 +236,7 @@ class AIHandler {
}

const response: IHttpResponse = await this.http.post(
`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${geminiAPIkey}`,
`https://generativelanguage.googleapis.com/v1beta/models/gemini-3-flash-preview:generateContent?key=${geminiAPIkey}`,
{
headers: {
'Content-Type': 'application/json',
Expand All @@ -248,7 +245,7 @@ class AIHandler {
contents: [
{
parts: {
text: this.getPrompt(message, prompt),
text: prompt,
},
},
],
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/ExecuteBlockActionHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ export class ExecuteBlockActionHandler {
this.app,
this.http,
Preference,
).handleResponse(user, message, prompt);
).handleResponse(message, prompt);

await aiStorage.updateResponse(response);

Expand Down
27 changes: 26 additions & 1 deletion src/handlers/Handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ import {
sendHelperNotification,
} from '../helper/notification';
import { UserPreferenceModal } from '../modal/UserPreferenceModal';
import { Language } from '../lib/Translation/translation';
import { Language, t } from '../lib/Translation/translation';
import { ReplyAIModal } from '../modal/AIreplyModal';
import { AIstorage } from '../storage/AIStorage';
import { UserPreferenceStorage } from '../storage/userPreferenceStorage';
import { sendMessage } from '../helper/message';
import AIHandler from './AIHandler';

export class Handler implements IHandler {
public app: QuickRepliesApp;
Expand All @@ -35,6 +37,7 @@ export class Handler implements IHandler {
public triggerId?: string;
public threadId?: string;
public language: Language;
public params?: string[];

constructor(params: IHanderParams) {
this.app = params.app;
Expand All @@ -47,6 +50,7 @@ export class Handler implements IHandler {
this.triggerId = params.triggerId;
this.threadId = params.threadId;
this.language = params.language;
this.params = params.params;
const persistenceRead = params.read.getPersistenceReader();
this.roomInteractionStorage = new RoomInteractionStorage(
params.persis,
Expand Down Expand Up @@ -160,6 +164,27 @@ export class Handler implements IHandler {
return;
}

public async CorrectGrammarUsingAI(): Promise<void> {
const userPreference = new UserPreferenceStorage(
this.persis,
this.read.getPersistenceReader(),
this.sender.id,
);
const value = this.params?.slice(1).join(' ') || '';
const existingPreference = await userPreference.getUserPreference();
const AiHandler = new AIHandler(this.app, this.http, existingPreference);
if (!value) {
await sendMessage(this.modify, this.sender, this.room, t('Error_Grammar_Correct', this.language));
return;
}

const response = await AiHandler.handleResponse(
value, '', true
);

await sendMessage(this.modify, this.sender, this.room, response);
}

public async replyUsingAI(message?: string): Promise<void> {
const roomId = this.room.id;
const roomMessages = await this.read
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Translation/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const de = {
Error_Reply_Name_Invalid: "Ungültiger Name: Der Name muss eine nicht-leere Zeichenfolge mit maximal 100 Zeichen sein.",
Error_Reply_Body_Invalid: "Ungültiger Inhalt: Der Inhalt muss eine nicht-leere Zeichenfolge mit maximal 1000 Zeichen sein.",
Error_Fail_Internal: "Interner Fehler. Bitte versuchen Sie es später noch einmal.",
Helper_Commands: "Verwenden Sie `/quick`, um loszulegen \n Verwenden Sie `/quick create`, um eine neue schnelle Antwort zu erstellen \n Verwenden Sie `/quick list`, um alle schnellen Nachrichten aufzulisten \n Verwenden Sie `/quick config`, um die Benutzereinstellungen zu konfigurieren \n Verwenden Sie `/quick ai` um Antworten mit KI zu generieren \n Verwenden Sie `/quick help`, um Hilfe zu erhalten \n Verwenden Sie `/qs <replyname>`, um eine schnelle Antwort zu suchen und zu senden \n",
Error_Grammar_Correct: "Bitte geben Sie den Text ein, den Sie korrigieren möchten.",
Helper_Commands: "Verwenden Sie `/quick`, um loszulegen \n Verwenden Sie `/quick create`, um eine neue schnelle Antwort zu erstellen \n Verwenden Sie `/quick list`, um alle schnellen Nachrichten aufzulisten \n Verwenden Sie `/quick config`, um die Benutzereinstellungen zu konfigurieren \n Verwenden Sie `/quick ai` um Antworten mit KI zu generieren \n Verwenden Sie `/quick help`, um Hilfe zu erhalten \n Verwenden Sie `/qs <replyname>`, um eine schnelle Antwort zu suchen und zu senden \n Verwenden Sie `/quick grammar <text>`, um einen Text zu korrigieren",
Helper_Text: "Hey __name__, Ich bin Quick Bot 👋 Hier sind einige schnelle Tipps, um Ihnen den Einstieg zu erleichtern!",
Default_Message: "Hey __name__, Ich bin Quick Bot 👋 Ich kann Ihnen helfen, schnelle Antworten zu erstellen und zu senden. Wie kann ich Ihnen helfen?",
Create_Reply: "Antwort erstellen",
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Translation/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const en = {
Error_Reply_Name_Invalid:"Invalid name: Name must be a non-empty string with a maximum length of 100 characters.",
Error_Reply_Body_Invalid:"Invalid body: Body must be a non-empty string with a maximum length of 1000 characters.",
Error_Fail_Internal: "Internal error. Please try again later.",
Helper_Commands: "Use `/quick` to get started \n Use `/quick create` to create a new quick reply \n Use `/quick list` to list all quick messages \n Use `/quick config` to configure user preference \n Use `/quick ai` to generate replies using ai \n Use `/quick help` to get help \n Use `/qs <replyname>` to search and send a quick reply \n ",
Error_Grammar_Correct: "Please provide text to correct.",
Helper_Commands: "Use `/quick` to get started \n Use `/quick create` to create a new quick reply \n Use `/quick list` to list all quick messages \n Use `/quick config` to configure user preference \n Use `/quick ai` to generate replies using ai \n Use `/quick help` to get help \n Use `/qs <replyname>` to search and send a quick reply \n Use `/quick grammar <text>` to correct grammar",
Helper_Text: "Hey __name__, I'm Quick Bot 👋 Here are some quick tips to get you started!",
Default_Message: "Hey __name__, I'm Quick Bot 👋 I can help you create and send quick Reply. How can I help you?",
Create_Reply: "Create Reply",
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Translation/locales/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const pl = {
Error_Reply_Name_Invalid: "Nieprawidłowa nazwa: Nazwa musi być niepustym ciągiem znaków o maksymalnej długości 100 znaków.",
Error_Reply_Body_Invalid: "Nieprawidłowa treść: Treść musi być niepustym ciągiem znaków o maksymalnej długości 1000 znaków.",
Error_Fail_Internal: "Błąd wewnętrzny. Proszę spróbować później.",
Helper_Commands: "Użyj `/quick`, aby rozpocząć \n Użyj `/quick create`, aby utworzyć nową szybką odpowiedź \n Użyj `/quick list`, aby wyświetlić wszystkie szybkie wiadomości \n Użyj `/quick config`, aby skonfigurować preferencje użytkownika\n Użyj `/quick ai` aby generować odpowiedzi za pomocą AI \n Użyj `/quick help`, aby uzyskać pomoc \n Użyj `/qs <replyname>`, aby wyszukać i wysłać szybką odpowiedź \n",
Error_Grammar_Correct: "Proszę podać tekst do poprawy.",
Helper_Commands: "Użyj `/quick`, aby rozpocząć \n Użyj `/quick create`, aby utworzyć nową szybką odpowiedź \n Użyj `/quick list`, aby wyświetlić wszystkie szybkie wiadomości \n Użyj `/quick config`, aby skonfigurować preferencje użytkownika\n Użyj `/quick ai` aby generować odpowiedzi za pomocą AI \n Użyj `/quick help`, aby uzyskać pomoc \n Użyj `/qs <replyname>`, aby wyszukać i wysłać szybką odpowiedź \n Użyj `/quick grammar <text>`, aby poprawić gramatykę",
Helper_Text: "Hej __name__, Jestem Quick Bot 👋 Oto kilka szybkich wskazówek, które pomogą Ci zacząć!",
Default_Message: "Hej __name__, Jestem Quick Bot 👋 Mogę pomóc Ci tworzyć i wysyłać szybkie odpowiedzi. W czym mogę pomóc?",
Create_Reply: "Utwórz odpowiedź",
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Translation/locales/pt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const pt = {
Error_Reply_Name_Invalid: "Nome inválido: O nome deve ser uma string não vazia com no máximo 100 caracteres.",
Error_Reply_Body_Invalid: "Conteúdo inválido: O conteúdo deve ser uma string não vazia com no máximo 1000 caracteres.",
Error_Fail_Internal: "Erro interno. Por favor, tente novamente mais tarde.",
Helper_Commands: "Use `/quick` para começar \n Use `/quick create` para criar uma nova resposta rápida \n Use `/quick list` para listar todas as mensagens rápidas \n Use `/quick config` para configurar preferências do usuário \n Use `/quick ai` para gerar respostas usando IA \n Use `/quick help` para obter ajuda \n Use `/qs <replyname>` para procurar e enviar uma resposta rápida \n",
Error_Grammar_Correct: "Por favor, insira o texto que deseja corrigir.",
Helper_Commands: "Use `/quick` para começar \n Use `/quick create` para criar uma nova resposta rápida \n Use `/quick list` para listar todas as mensagens rápidas \n Use `/quick config` para configurar preferências do usuário \n Use `/quick ai` para gerar respostas usando IA \n Use `/quick help` para obter ajuda \n Use `/qs <replyname>` para procurar e enviar uma resposta rápida \n Use `/quick grammar <text>` para corrigir gramática",
Helper_Text: "Oi __name__, Eu sou o Quick Bot 👋 Aqui estão algumas dicas rápidas para começar!",
Default_Message: "Oi __name__, Eu sou o Quick Bot 👋 Posso ajudar você a criar e enviar respostas rápidas. Como posso ajudar?",
Create_Reply: "Criar resposta",
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Translation/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ export const ru = {
Error_Reply_Name_Invalid: "Неверное название: Название должно быть непустой строкой длиной до 100 символов.",
Error_Reply_Body_Invalid: "Неверное содержание: Содержание должно быть непустой строкой длиной до 1000 символов.",
Error_Fail_Internal: "Внутренняя ошибка. Пожалуйста, попробуйте снова позже.",
Helper_Commands: "Используйте `/quick`, чтобы начать \n Используйте `/quick create`, чтобы создать новый быстрый ответ \n Используйте `/quick list`, чтобы перечислить все быстрые сообщения \n Используйте `/quick config`, чтобы настроить предпочтения пользователя \n Используйте `/quick ai` чтобы генерировать ответы c помощью ИИ \n Используйте `/quick help`, чтобы получить помощь \n Используйте `/qs <replyname>`, чтобы найти и отправить быстрый ответ \n",
Error_Grammar_Correct: "Пожалуйста, введите текст, который вы хотите исправить.",
Helper_Commands: "Используйте `/quick`, чтобы начать \n Используйте `/quick create`, чтобы создать новый быстрый ответ \n Используйте `/quick list`, чтобы перечислить все быстрые сообщения \n Используйте `/quick config`, чтобы настроить предпочтения пользователя \n Используйте `/quick ai` чтобы генерировать ответы c помощью ИИ \n Используйте `/quick help`, чтобы получить помощь \n Используйте `/qs <replyname>`, чтобы найти и отправить быстрый ответ \n Используйте `/quick grammar <text>`, чтобы исправить грамматику",
Helper_Text: "Привет __name__, Я Quick Bot 👋 Вот несколько быстрых советов, чтобы помочь вам начать!",
Default_Message: "Привет __name__, Я Quick Bot 👋 Я могу помочь вам создать и отправить быстрые ответы. Как я могу помочь?",
Create_Reply: "Создать ответ",
Expand Down