mirror of
https://github.com/EvolutionAPI/evolution-api.git
synced 2025-12-20 12:22:21 -06:00
feat: prisma and remove mongodb
This commit is contained in:
@@ -5,8 +5,7 @@ import { ConfigService, HttpServer } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { BadRequestException } from '../../../../exceptions';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { MongodbRepository } from '../../../repository/mongodb/repository.manager';
|
||||
import { PrismaRepository } from '../../../repository/prisma/repository.service';
|
||||
import { PrismaRepository } from '../../../repository/repository.service';
|
||||
import { waMonitor } from '../../../server.module';
|
||||
import { CacheService } from '../../../services/cache.service';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
@@ -18,7 +17,6 @@ export class ChatwootController {
|
||||
constructor(
|
||||
private readonly chatwootService: ChatwootService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly mongodbRepository: MongodbRepository,
|
||||
private readonly prismaRepository: PrismaRepository,
|
||||
) {}
|
||||
|
||||
@@ -30,39 +28,39 @@ export class ChatwootController {
|
||||
throw new BadRequestException('url is not valid');
|
||||
}
|
||||
|
||||
if (!data.account_id) {
|
||||
throw new BadRequestException('account_id is required');
|
||||
if (!data.accountId) {
|
||||
throw new BadRequestException('accountId is required');
|
||||
}
|
||||
|
||||
if (!data.token) {
|
||||
throw new BadRequestException('token is required');
|
||||
}
|
||||
|
||||
if (data.sign_msg !== true && data.sign_msg !== false) {
|
||||
throw new BadRequestException('sign_msg is required');
|
||||
if (data.signMsg !== true && data.signMsg !== false) {
|
||||
throw new BadRequestException('signMsg is required');
|
||||
}
|
||||
if (data.sign_msg === false) data.sign_delimiter = null;
|
||||
if (data.signMsg === false) data.signDelimiter = null;
|
||||
}
|
||||
|
||||
if (!data.enabled) {
|
||||
logger.verbose('chatwoot disabled');
|
||||
data.account_id = '';
|
||||
data.accountId = '';
|
||||
data.token = '';
|
||||
data.url = '';
|
||||
data.sign_msg = false;
|
||||
data.sign_delimiter = null;
|
||||
data.reopen_conversation = false;
|
||||
data.conversation_pending = false;
|
||||
data.import_contacts = false;
|
||||
data.import_messages = false;
|
||||
data.merge_brazil_contacts = false;
|
||||
data.days_limit_import_messages = 0;
|
||||
data.auto_create = false;
|
||||
data.name_inbox = '';
|
||||
data.signMsg = false;
|
||||
data.signDelimiter = null;
|
||||
data.reopenConversation = false;
|
||||
data.conversationPending = false;
|
||||
data.importContacts = false;
|
||||
data.importMessages = false;
|
||||
data.mergeBrazilContacts = false;
|
||||
data.daysLimitImportMessages = 0;
|
||||
data.autoCreate = false;
|
||||
data.nameInbox = '';
|
||||
}
|
||||
|
||||
if (!data.name_inbox || data.name_inbox === '') {
|
||||
data.name_inbox = instance.instanceName;
|
||||
if (!data.nameInbox || data.nameInbox === '') {
|
||||
data.nameInbox = instance.instanceName;
|
||||
}
|
||||
|
||||
const result = await this.chatwootService.create(instance, data);
|
||||
@@ -87,10 +85,10 @@ export class ChatwootController {
|
||||
return {
|
||||
enabled: false,
|
||||
url: '',
|
||||
account_id: '',
|
||||
accountId: '',
|
||||
token: '',
|
||||
sign_msg: false,
|
||||
name_inbox: '',
|
||||
signMsg: false,
|
||||
nameInbox: '',
|
||||
webhook_url: '',
|
||||
};
|
||||
}
|
||||
@@ -107,13 +105,7 @@ export class ChatwootController {
|
||||
logger.verbose('requested receiveWebhook from ' + instance.instanceName + ' instance');
|
||||
|
||||
const chatwootCache = new CacheService(new CacheEngine(this.configService, ChatwootService.name).getEngine());
|
||||
const chatwootService = new ChatwootService(
|
||||
waMonitor,
|
||||
this.configService,
|
||||
this.mongodbRepository,
|
||||
this.prismaRepository,
|
||||
chatwootCache,
|
||||
);
|
||||
const chatwootService = new ChatwootService(waMonitor, this.configService, this.prismaRepository, chatwootCache);
|
||||
|
||||
return chatwootService.receiveWebhook(instance, data);
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
export class ChatwootDto {
|
||||
enabled?: boolean;
|
||||
account_id?: string;
|
||||
accountId?: string;
|
||||
token?: string;
|
||||
url?: string;
|
||||
name_inbox?: string;
|
||||
sign_msg?: boolean;
|
||||
sign_delimiter?: string;
|
||||
nameInbox?: string;
|
||||
signMsg?: boolean;
|
||||
signDelimiter?: string;
|
||||
number?: string;
|
||||
reopen_conversation?: boolean;
|
||||
conversation_pending?: boolean;
|
||||
merge_brazil_contacts?: boolean;
|
||||
import_contacts?: boolean;
|
||||
import_messages?: boolean;
|
||||
days_limit_import_messages?: number;
|
||||
auto_create?: boolean;
|
||||
reopenConversation?: boolean;
|
||||
conversationPending?: boolean;
|
||||
mergeBrazilContacts?: boolean;
|
||||
importContacts?: boolean;
|
||||
importMessages?: boolean;
|
||||
daysLimitImportMessages?: number;
|
||||
autoCreate?: boolean;
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class ChatwootRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
account_id?: string;
|
||||
token?: string;
|
||||
url?: string;
|
||||
name_inbox?: string;
|
||||
sign_msg?: boolean;
|
||||
sign_delimiter?: string;
|
||||
number?: string;
|
||||
reopen_conversation?: boolean;
|
||||
conversation_pending?: boolean;
|
||||
merge_brazil_contacts?: boolean;
|
||||
import_contacts?: boolean;
|
||||
import_messages?: boolean;
|
||||
days_limit_import_messages?: number;
|
||||
}
|
||||
|
||||
const chatwootSchema = new Schema<ChatwootRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
account_id: { type: String, required: true },
|
||||
token: { type: String, required: true },
|
||||
url: { type: String, required: true },
|
||||
name_inbox: { type: String, required: true },
|
||||
sign_msg: { type: Boolean, required: true },
|
||||
sign_delimiter: { type: String, required: false },
|
||||
number: { type: String, required: true },
|
||||
reopen_conversation: { type: Boolean, required: true },
|
||||
conversation_pending: { type: Boolean, required: true },
|
||||
merge_brazil_contacts: { type: Boolean, required: true },
|
||||
import_contacts: { type: Boolean, required: true },
|
||||
import_messages: { type: Boolean, required: true },
|
||||
days_limit_import_messages: { type: Number, required: true },
|
||||
});
|
||||
|
||||
export const ChatwootModel = mongodbServer?.model(ChatwootRaw.name, chatwootSchema, 'chatwoot');
|
||||
export type IChatwootModel = typeof ChatwootModel;
|
||||
@@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { ChatwootRaw, IChatwootModel } from '../../../models';
|
||||
|
||||
export class ChatwootRepository extends Repository {
|
||||
constructor(private readonly chatwootModel: IChatwootModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('ChatwootRepository');
|
||||
|
||||
public async create(data: ChatwootRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating chatwoot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving chatwoot to db');
|
||||
const insert = await this.chatwootModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('chatwoot saved to db: ' + insert.modifiedCount + ' chatwoot');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving chatwoot to store');
|
||||
|
||||
this.writeStore<ChatwootRaw>({
|
||||
path: join(this.storePath, 'chatwoot'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('chatwoot saved to store in path: ' + join(this.storePath, 'chatwoot') + '/' + instance);
|
||||
|
||||
this.logger.verbose('chatwoot created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<ChatwootRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding chatwoot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding chatwoot in db');
|
||||
return await this.chatwootModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding chatwoot in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'chatwoot', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as ChatwootRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,12 @@ import ChatwootClient, {
|
||||
inbox,
|
||||
} from '@figuro/chatwoot-sdk';
|
||||
import { request as chatwootRequest } from '@figuro/chatwoot-sdk/dist/core/request';
|
||||
import { proto } from '@whiskeysockets/baileys';
|
||||
import { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageModel } from '@prisma/client';
|
||||
import axios from 'axios';
|
||||
import FormData from 'form-data';
|
||||
import { createReadStream, unlinkSync, writeFileSync } from 'fs';
|
||||
import Jimp from 'jimp';
|
||||
import Long from 'long';
|
||||
import mimeTypes from 'mime-types';
|
||||
import path from 'path';
|
||||
|
||||
@@ -22,14 +23,20 @@ import i18next from '../../../../utils/i18n';
|
||||
import { ICache } from '../../../abstract/abstract.cache';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { Options, Quoted, SendAudioDto, SendMediaDto, SendTextDto } from '../../../dto/sendMessage.dto';
|
||||
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../models';
|
||||
import { MongodbRepository } from '../../../repository/mongodb/repository.manager';
|
||||
import { PrismaRepository } from '../../../repository/prisma/repository.service';
|
||||
import { PrismaRepository } from '../../../repository/repository.service';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { Events } from '../../../types/wa.types';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
import { chatwootImport } from '../utils/chatwoot-import-helper';
|
||||
|
||||
interface ChatwootMessage {
|
||||
messageId?: number;
|
||||
inboxId?: number;
|
||||
conversationId?: number;
|
||||
contactInboxSourceId?: string;
|
||||
isRead?: boolean;
|
||||
}
|
||||
|
||||
export class ChatwootService {
|
||||
private readonly logger = new Logger(ChatwootService.name);
|
||||
|
||||
@@ -38,7 +45,6 @@ export class ChatwootService {
|
||||
constructor(
|
||||
private readonly waMonitor: WAMonitoringService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly mongodbRepository: MongodbRepository,
|
||||
private readonly prismaRepository: PrismaRepository,
|
||||
private readonly cache: ICache,
|
||||
) {}
|
||||
@@ -46,7 +52,7 @@ export class ChatwootService {
|
||||
private async getProvider(instance: InstanceDto) {
|
||||
const cacheKey = `${instance.instanceName}:getProvider`;
|
||||
if (await this.cache.has(cacheKey)) {
|
||||
return (await this.cache.get(cacheKey)) as ChatwootRaw;
|
||||
return (await this.cache.get(cacheKey)) as ChatwootModel;
|
||||
}
|
||||
|
||||
this.logger.verbose('get provider to instance: ' + instance.instanceName);
|
||||
@@ -110,12 +116,12 @@ export class ChatwootService {
|
||||
|
||||
this.logger.verbose('chatwoot created');
|
||||
|
||||
if (data.auto_create) {
|
||||
if (data.autoCreate) {
|
||||
const urlServer = this.configService.get<HttpServer>('SERVER').URL;
|
||||
|
||||
await this.initInstanceChatwoot(
|
||||
instance,
|
||||
data.name_inbox ?? instance.instanceName.split('-cwId-')[0],
|
||||
data.nameInbox ?? instance.instanceName.split('-cwId-')[0],
|
||||
`${urlServer}/chatwoot/webhook/${encodeURIComponent(instance.instanceName)}`,
|
||||
true,
|
||||
data.number,
|
||||
@@ -1195,26 +1201,22 @@ export class ChatwootService {
|
||||
|
||||
this.logger.verbose('check if is a message deletion');
|
||||
if (body.event === 'message_updated' && body.content_attributes?.deleted) {
|
||||
const message = await this.mongodbRepository.message.find({
|
||||
const message = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
owner: instance.instanceName,
|
||||
chatwoot: {
|
||||
messageId: body.id,
|
||||
},
|
||||
chatwootMessageId: body.id,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
if (message.length && message[0].key?.id) {
|
||||
|
||||
if (message) {
|
||||
this.logger.verbose('deleting message in whatsapp. Message id: ' + message[0].key.id);
|
||||
await waInstance?.client.sendMessage(message[0].key.remoteJid, { delete: message[0].key });
|
||||
|
||||
this.logger.verbose('deleting message in repository. Message id: ' + message[0].key.id);
|
||||
this.mongodbRepository.message.delete({
|
||||
this.prismaRepository.message.deleteMany({
|
||||
where: {
|
||||
owner: instance.instanceName,
|
||||
chatwoot: {
|
||||
messageId: body.id,
|
||||
},
|
||||
instanceId: instance.instanceId,
|
||||
chatwootMessageId: body.id,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -1368,9 +1370,7 @@ export class ChatwootService {
|
||||
messageId: body.id,
|
||||
inboxId: body.inbox?.id,
|
||||
conversationId: body.conversation?.id,
|
||||
contactInbox: {
|
||||
sourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
contactInboxSourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
instance,
|
||||
);
|
||||
@@ -1391,25 +1391,27 @@ export class ChatwootService {
|
||||
},
|
||||
};
|
||||
|
||||
let messageSent: MessageRaw | proto.WebMessageInfo;
|
||||
let messageSent: any;
|
||||
try {
|
||||
messageSent = await waInstance?.textMessage(data, true);
|
||||
if (!messageSent) {
|
||||
throw new Error('Message not sent');
|
||||
}
|
||||
|
||||
if (Long.isLong(messageSent?.messageTimestamp)) {
|
||||
messageSent.messageTimestamp = messageSent.messageTimestamp?.toNumber();
|
||||
}
|
||||
|
||||
this.updateChatwootMessageId(
|
||||
{
|
||||
...messageSent,
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
{
|
||||
messageId: body.id,
|
||||
inboxId: body.inbox?.id,
|
||||
conversationId: body.conversation?.id,
|
||||
contactInbox: {
|
||||
sourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
contactInboxSourceId: body.conversation?.contact_inbox?.source_id,
|
||||
},
|
||||
instance,
|
||||
);
|
||||
@@ -1424,32 +1426,72 @@ export class ChatwootService {
|
||||
|
||||
const chatwootRead = this.configService.get<Chatwoot>('CHATWOOT').MESSAGE_READ;
|
||||
if (chatwootRead) {
|
||||
const lastMessage = await this.mongodbRepository.message.find({
|
||||
const lastMessage = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
key: {
|
||||
fromMe: false,
|
||||
path: ['fromMe'],
|
||||
equals: false,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
if (lastMessage.length > 0 && !lastMessage[0].chatwoot?.isRead) {
|
||||
if (lastMessage && !lastMessage.chatwootIsRead) {
|
||||
const key = lastMessage.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
waInstance?.markMessageAsRead({
|
||||
read_messages: lastMessage.map((msg) => ({
|
||||
id: msg.key?.id,
|
||||
fromMe: msg.key?.fromMe,
|
||||
remoteJid: msg.key?.remoteJid,
|
||||
})),
|
||||
read_messages: [
|
||||
{
|
||||
id: key.id,
|
||||
fromMe: key.fromMe,
|
||||
remoteJid: key.remoteJid,
|
||||
},
|
||||
],
|
||||
});
|
||||
const updateMessage = lastMessage.map((msg) => ({
|
||||
key: msg.key,
|
||||
owner: msg.owner,
|
||||
chatwoot: {
|
||||
...msg.chatwoot,
|
||||
isRead: true,
|
||||
const updateMessage = {
|
||||
chatwootMessageId: lastMessage.chatwootMessageId,
|
||||
chatwootConversationId: lastMessage.chatwootConversationId,
|
||||
chatwootInboxId: lastMessage.chatwootInboxId,
|
||||
chatwootContactInboxSourceId: lastMessage.chatwootContactInboxSourceId,
|
||||
chatwootIsRead: true,
|
||||
};
|
||||
|
||||
await this.prismaRepository.message.updateMany({
|
||||
where: {
|
||||
instanceId: instance.instanceId,
|
||||
AND: [
|
||||
{
|
||||
key: {
|
||||
path: ['id'],
|
||||
equals: key.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
path: ['remoteJid'],
|
||||
equals: key.remoteJid,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
path: ['fromMe'],
|
||||
equals: key.fromMe,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
path: ['participant'],
|
||||
equals: key.participant,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}));
|
||||
this.mongodbRepository.message.update(updateMessage, instance.instanceName, true);
|
||||
data: updateMessage,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1481,31 +1523,48 @@ export class ChatwootService {
|
||||
}
|
||||
}
|
||||
|
||||
private updateChatwootMessageId(
|
||||
message: MessageRaw,
|
||||
chatwootMessageIds: MessageRaw['chatwoot'],
|
||||
instance: InstanceDto,
|
||||
) {
|
||||
if (!chatwootMessageIds.messageId || !message?.key?.id) {
|
||||
private updateChatwootMessageId(message: MessageModel, chatwootMessageIds: ChatwootMessage, instance: InstanceDto) {
|
||||
const key = message.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
if (!chatwootMessageIds.messageId || !key?.id) {
|
||||
return;
|
||||
}
|
||||
|
||||
message.chatwoot = chatwootMessageIds;
|
||||
this.mongodbRepository.message.update([message], instance.instanceName, true);
|
||||
}
|
||||
|
||||
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageRaw> {
|
||||
const messages = await this.mongodbRepository.message.find({
|
||||
this.prismaRepository.message.updateMany({
|
||||
where: {
|
||||
key: {
|
||||
id: keyId,
|
||||
path: ['id'],
|
||||
equals: key.id,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
data: {
|
||||
chatwootMessageId: chatwootMessageIds.messageId,
|
||||
chatwootConversationId: chatwootMessageIds.conversationId,
|
||||
chatwootInboxId: chatwootMessageIds.inboxId,
|
||||
chatwootContactInboxSourceId: chatwootMessageIds.contactInboxSourceId,
|
||||
chatwootIsRead: chatwootMessageIds.isRead,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private async getMessageByKeyId(instance: InstanceDto, keyId: string): Promise<MessageModel> {
|
||||
const messages = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
key: {
|
||||
path: ['id'],
|
||||
equals: keyId,
|
||||
},
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
|
||||
return messages.length ? messages[0] : null;
|
||||
return messages || null;
|
||||
}
|
||||
|
||||
private async getReplyToIds(
|
||||
@@ -1519,8 +1578,8 @@ export class ChatwootService {
|
||||
inReplyToExternalId = msg.message?.extendedTextMessage?.contextInfo?.stanzaId;
|
||||
if (inReplyToExternalId) {
|
||||
const message = await this.getMessageByKeyId(instance, inReplyToExternalId);
|
||||
if (message?.chatwoot?.messageId) {
|
||||
inReplyTo = message.chatwoot.messageId;
|
||||
if (message?.chatwootMessageId) {
|
||||
inReplyTo = message.chatwootMessageId;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1533,16 +1592,21 @@ export class ChatwootService {
|
||||
|
||||
private async getQuotedMessage(msg: any, instance: InstanceDto): Promise<Quoted> {
|
||||
if (msg?.content_attributes?.in_reply_to) {
|
||||
const message = await this.mongodbRepository.message.find({
|
||||
const message = await this.prismaRepository.message.findFirst({
|
||||
where: {
|
||||
chatwoot: {
|
||||
messageId: msg?.content_attributes?.in_reply_to,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
chatwootMessageId: msg?.content_attributes?.in_reply_to,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
limit: 1,
|
||||
});
|
||||
if (message.length && message[0]?.key?.id) {
|
||||
|
||||
const key = message.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
if (message && key?.id) {
|
||||
return {
|
||||
key: message[0].key,
|
||||
message: message[0].message,
|
||||
@@ -1588,7 +1652,12 @@ export class ChatwootService {
|
||||
|
||||
private getReactionMessage(msg: any) {
|
||||
interface ReactionMessage {
|
||||
key: MessageRaw['key'];
|
||||
key: {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
text: string;
|
||||
}
|
||||
const reactionMessage: ReactionMessage | undefined = msg?.reactionMessage;
|
||||
@@ -2131,22 +2200,23 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
const message = await this.getMessageByKeyId(instance, body.key.id);
|
||||
if (message?.chatwoot?.messageId && message?.chatwoot?.conversationId) {
|
||||
if (message?.chatwootMessageId && message?.chatwootConversationId) {
|
||||
this.logger.verbose('deleting message in repository. Message id: ' + body.key.id);
|
||||
this.mongodbRepository.message.delete({
|
||||
this.prismaRepository.message.deleteMany({
|
||||
where: {
|
||||
key: {
|
||||
id: body.key.id,
|
||||
path: ['id'],
|
||||
equals: body.key.id,
|
||||
},
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
},
|
||||
});
|
||||
|
||||
this.logger.verbose('deleting message in chatwoot. Message id: ' + body.key.id);
|
||||
return await client.messages.delete({
|
||||
accountId: this.provider.account_id,
|
||||
conversationId: message.chatwoot.conversationId,
|
||||
messageId: message.chatwoot.messageId,
|
||||
conversationId: message.chatwootConversationId,
|
||||
messageId: message.chatwootMessageId,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -2157,18 +2227,25 @@ export class ChatwootService {
|
||||
body?.editedMessage?.conversation || body?.editedMessage?.extendedTextMessage?.text
|
||||
}\n\n_\`${i18next.t('cw.message.edited')}.\`_`;
|
||||
const message = await this.getMessageByKeyId(instance, body?.key?.id);
|
||||
const messageType = message.key?.fromMe ? 'outgoing' : 'incoming';
|
||||
const key = message.key as {
|
||||
id: string;
|
||||
fromMe: boolean;
|
||||
remoteJid: string;
|
||||
participant?: string;
|
||||
};
|
||||
|
||||
if (message && message.chatwoot?.conversationId) {
|
||||
const messageType = key?.fromMe ? 'outgoing' : 'incoming';
|
||||
|
||||
if (message && message.chatwootConversationId) {
|
||||
const send = await this.createMessage(
|
||||
instance,
|
||||
message.chatwoot.conversationId,
|
||||
message.chatwootConversationId,
|
||||
editedText,
|
||||
messageType,
|
||||
false,
|
||||
[],
|
||||
{
|
||||
message: { extendedTextMessage: { contextInfo: { stanzaId: message.key.id } } },
|
||||
message: { extendedTextMessage: { contextInfo: { stanzaId: key.id } } },
|
||||
},
|
||||
'WAID:' + body.key.id,
|
||||
);
|
||||
@@ -2189,9 +2266,11 @@ export class ChatwootService {
|
||||
}
|
||||
|
||||
const message = await this.getMessageByKeyId(instance, body.key.id);
|
||||
const { conversationId, contactInbox } = message?.chatwoot || {};
|
||||
const conversationId = message?.chatwootConversationId;
|
||||
const contactInboxSourceId = message?.chatwootContactInboxSourceId;
|
||||
|
||||
if (conversationId) {
|
||||
let sourceId = contactInbox?.sourceId;
|
||||
let sourceId = contactInboxSourceId;
|
||||
const inbox = (await this.getInbox(instance)) as inbox & {
|
||||
inbox_identifier?: string;
|
||||
};
|
||||
@@ -2317,7 +2396,7 @@ export class ChatwootService {
|
||||
/* We can't proccess messages exactly in batch because Chatwoot use message id to order
|
||||
messages in frontend and we are receiving the messages mixed between the batches.
|
||||
Because this, we need to put all batches together and order after */
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageRaw[]) {
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageModel[]) {
|
||||
if (!this.isImportHistoryAvailable()) {
|
||||
return;
|
||||
}
|
||||
@@ -2325,7 +2404,7 @@ export class ChatwootService {
|
||||
chatwootImport.addHistoryMessages(instance, messagesRaw);
|
||||
}
|
||||
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactRaw[]) {
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactModel[]) {
|
||||
if (!this.isImportHistoryAvailable()) {
|
||||
return;
|
||||
}
|
||||
@@ -2382,16 +2461,18 @@ export class ChatwootService {
|
||||
);
|
||||
|
||||
const contactsWithProfilePicture = (
|
||||
await this.mongodbRepository.contact.find({
|
||||
await this.prismaRepository.contact.findMany({
|
||||
where: {
|
||||
owner: instance.instanceName,
|
||||
instanceId: instance.instanceId,
|
||||
id: {
|
||||
$in: recentContacts.map((contact) => contact.identifier),
|
||||
in: recentContacts.map((contact) => Number(contact.identifier)),
|
||||
},
|
||||
profilePicUrl: {
|
||||
not: null,
|
||||
},
|
||||
profilePictureUrl: { $ne: null },
|
||||
},
|
||||
} as any)
|
||||
).reduce((acc: Map<string, ContactRaw>, contact: ContactRaw) => acc.set(contact.id, contact), new Map());
|
||||
})
|
||||
).reduce((acc: Map<number, ContactModel>, contact: ContactModel) => acc.set(contact.id, contact), new Map());
|
||||
|
||||
recentContacts.forEach(async (contact) => {
|
||||
if (contactsWithProfilePicture.has(contact.identifier)) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { inbox } from '@figuro/chatwoot-sdk';
|
||||
import { Chatwoot as ChatwootModel, Contact, Message } from '@prisma/client';
|
||||
import { proto } from '@whiskeysockets/baileys';
|
||||
|
||||
import { InstanceDto } from '../../../../api/dto/instance.dto';
|
||||
import { ChatwootRaw, ContactRaw, MessageRaw } from '../../../../api/models';
|
||||
import { Chatwoot, configService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { ChatwootDto } from '../dto/chatwoot.dto';
|
||||
import { postgresClient } from '../libs/postgres.client';
|
||||
import { ChatwootService } from '../services/chatwoot.service';
|
||||
|
||||
@@ -29,8 +30,8 @@ type IWebMessageInfo = Omit<proto.IWebMessageInfo, 'key'> & Partial<Pick<proto.I
|
||||
class ChatwootImport {
|
||||
private logger = new Logger(ChatwootImport.name);
|
||||
private repositoryMessagesCache = new Map<string, Set<string>>();
|
||||
private historyMessages = new Map<string, MessageRaw[]>();
|
||||
private historyContacts = new Map<string, ContactRaw[]>();
|
||||
private historyMessages = new Map<string, Message[]>();
|
||||
private historyContacts = new Map<string, Contact[]>();
|
||||
|
||||
public getRepositoryMessagesCache(instance: InstanceDto) {
|
||||
return this.repositoryMessagesCache.has(instance.instanceName)
|
||||
@@ -46,14 +47,14 @@ class ChatwootImport {
|
||||
this.repositoryMessagesCache.delete(instance.instanceName);
|
||||
}
|
||||
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: MessageRaw[]) {
|
||||
public addHistoryMessages(instance: InstanceDto, messagesRaw: Message[]) {
|
||||
const actualValue = this.historyMessages.has(instance.instanceName)
|
||||
? this.historyMessages.get(instance.instanceName)
|
||||
: [];
|
||||
this.historyMessages.set(instance.instanceName, actualValue.concat(messagesRaw));
|
||||
}
|
||||
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: ContactRaw[]) {
|
||||
public addHistoryContacts(instance: InstanceDto, contactsRaw: Contact[]) {
|
||||
const actualValue = this.historyContacts.has(instance.instanceName)
|
||||
? this.historyContacts.get(instance.instanceName)
|
||||
: [];
|
||||
@@ -78,7 +79,7 @@ class ChatwootImport {
|
||||
return this.historyMessages.get(instance.instanceName)?.length ?? 0;
|
||||
}
|
||||
|
||||
public async importHistoryContacts(instance: InstanceDto, provider: ChatwootRaw) {
|
||||
public async importHistoryContacts(instance: InstanceDto, provider: ChatwootDto) {
|
||||
try {
|
||||
if (this.getHistoryMessagesLenght(instance) > 0) {
|
||||
return;
|
||||
@@ -93,21 +94,21 @@ class ChatwootImport {
|
||||
return 0;
|
||||
}
|
||||
|
||||
let contactsChunk: ContactRaw[] = this.sliceIntoChunks(contacts, 3000);
|
||||
let contactsChunk: Contact[] = this.sliceIntoChunks(contacts, 3000);
|
||||
while (contactsChunk.length > 0) {
|
||||
// inserting contacts in chatwoot db
|
||||
let sqlInsert = `INSERT INTO contacts
|
||||
(name, phone_number, account_id, identifier, created_at, updated_at) VALUES `;
|
||||
const bindInsert = [provider.account_id];
|
||||
const bindInsert = [provider.accountId];
|
||||
|
||||
for (const contact of contactsChunk) {
|
||||
bindInsert.push(contact.pushName);
|
||||
const bindName = `$${bindInsert.length}`;
|
||||
|
||||
bindInsert.push(`+${contact.id.split('@')[0]}`);
|
||||
bindInsert.push(`+${contact.remoteJid.split('@')[0]}`);
|
||||
const bindPhoneNumber = `$${bindInsert.length}`;
|
||||
|
||||
bindInsert.push(contact.id);
|
||||
bindInsert.push(contact.remoteJid);
|
||||
const bindIdentifier = `$${bindInsert.length}`;
|
||||
|
||||
sqlInsert += `(${bindName}, ${bindPhoneNumber}, $1, ${bindIdentifier}, NOW(), NOW()),`;
|
||||
@@ -137,7 +138,7 @@ class ChatwootImport {
|
||||
instance: InstanceDto,
|
||||
chatwootService: ChatwootService,
|
||||
inbox: inbox,
|
||||
provider: ChatwootRaw,
|
||||
provider: ChatwootModel,
|
||||
) {
|
||||
try {
|
||||
const pgClient = postgresClient.getChatwootConnection();
|
||||
@@ -156,8 +157,16 @@ class ChatwootImport {
|
||||
|
||||
// ordering messages by number and timestamp asc
|
||||
messagesOrdered.sort((a, b) => {
|
||||
const aKey = a.key as {
|
||||
remoteJid: string;
|
||||
};
|
||||
|
||||
const bKey = b.key as {
|
||||
remoteJid: string;
|
||||
};
|
||||
|
||||
return (
|
||||
parseInt(a.key.remoteJid) - parseInt(b.key.remoteJid) ||
|
||||
parseInt(aKey.remoteJid) - parseInt(bKey.remoteJid) ||
|
||||
(a.messageTimestamp as number) - (b.messageTimestamp as number)
|
||||
);
|
||||
});
|
||||
@@ -165,7 +174,7 @@ class ChatwootImport {
|
||||
const allMessagesMappedByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesOrdered);
|
||||
// Map structure: +552199999999 => { first message timestamp from number, last message timestamp from number}
|
||||
const phoneNumbersWithTimestamp = new Map<string, firstLastTimestamp>();
|
||||
allMessagesMappedByPhoneNumber.forEach((messages: MessageRaw[], phoneNumber: string) => {
|
||||
allMessagesMappedByPhoneNumber.forEach((messages: Message[], phoneNumber: string) => {
|
||||
phoneNumbersWithTimestamp.set(phoneNumber, {
|
||||
first: messages[0]?.messageTimestamp as number,
|
||||
last: messages[messages.length - 1]?.messageTimestamp as number,
|
||||
@@ -174,9 +183,9 @@ class ChatwootImport {
|
||||
|
||||
// processing messages in batch
|
||||
const batchSize = 4000;
|
||||
let messagesChunk: MessageRaw[] = this.sliceIntoChunks(messagesOrdered, batchSize);
|
||||
let messagesChunk: Message[] = this.sliceIntoChunks(messagesOrdered, batchSize);
|
||||
while (messagesChunk.length > 0) {
|
||||
// Map structure: +552199999999 => MessageRaw[]
|
||||
// Map structure: +552199999999 => Message[]
|
||||
const messagesByPhoneNumber = this.createMessagesMapByPhoneNumber(messagesChunk);
|
||||
|
||||
if (messagesByPhoneNumber.size > 0) {
|
||||
@@ -191,9 +200,9 @@ class ChatwootImport {
|
||||
let sqlInsertMsg = `INSERT INTO messages
|
||||
(content, account_id, inbox_id, conversation_id, message_type, private, content_type,
|
||||
sender_type, sender_id, created_at, updated_at) VALUES `;
|
||||
const bindInsertMsg = [provider.account_id, inbox.id];
|
||||
const bindInsertMsg = [provider.accountId, inbox.id];
|
||||
|
||||
messagesByPhoneNumber.forEach((messages: MessageRaw[], phoneNumber: string) => {
|
||||
messagesByPhoneNumber.forEach((messages: any[], phoneNumber: string) => {
|
||||
const fksChatwoot = fksByNumber.get(phoneNumber);
|
||||
|
||||
messages.forEach((message) => {
|
||||
@@ -257,14 +266,14 @@ class ChatwootImport {
|
||||
}
|
||||
|
||||
public async selectOrCreateFksFromChatwoot(
|
||||
provider: ChatwootRaw,
|
||||
provider: ChatwootModel,
|
||||
inbox: inbox,
|
||||
phoneNumbersWithTimestamp: Map<string, firstLastTimestamp>,
|
||||
messagesByPhoneNumber: Map<string, MessageRaw[]>,
|
||||
messagesByPhoneNumber: Map<string, Message[]>,
|
||||
): Promise<Map<string, FksChatwoot>> {
|
||||
const pgClient = postgresClient.getChatwootConnection();
|
||||
|
||||
const bindValues = [provider.account_id, inbox.id];
|
||||
const bindValues = [provider.accountId, inbox.id];
|
||||
const phoneNumberBind = Array.from(messagesByPhoneNumber.keys())
|
||||
.map((phoneNumber) => {
|
||||
const phoneNumberTimestamp = phoneNumbersWithTimestamp.get(phoneNumber);
|
||||
@@ -348,7 +357,7 @@ class ChatwootImport {
|
||||
return new Map(fksFromChatwoot.rows.map((item: FksChatwoot) => [item.phone_number, item]));
|
||||
}
|
||||
|
||||
public async getChatwootUser(provider: ChatwootRaw): Promise<ChatwootUser> {
|
||||
public async getChatwootUser(provider: ChatwootModel): Promise<ChatwootUser> {
|
||||
try {
|
||||
const pgClient = postgresClient.getChatwootConnection();
|
||||
|
||||
@@ -362,10 +371,13 @@ class ChatwootImport {
|
||||
}
|
||||
}
|
||||
|
||||
public createMessagesMapByPhoneNumber(messages: MessageRaw[]): Map<string, MessageRaw[]> {
|
||||
return messages.reduce((acc: Map<string, MessageRaw[]>, message: MessageRaw) => {
|
||||
if (!this.isIgnorePhoneNumber(message?.key?.remoteJid)) {
|
||||
const phoneNumber = message?.key?.remoteJid?.split('@')[0];
|
||||
public createMessagesMapByPhoneNumber(messages: Message[]): Map<string, Message[]> {
|
||||
return messages.reduce((acc: Map<string, Message[]>, message: Message) => {
|
||||
const key = message?.key as {
|
||||
remoteJid: string;
|
||||
};
|
||||
if (!this.isIgnorePhoneNumber(key?.remoteJid)) {
|
||||
const phoneNumber = key?.remoteJid?.split('@')[0];
|
||||
if (phoneNumber) {
|
||||
const phoneNumberPlus = `+${phoneNumber}`;
|
||||
const messages = acc.has(phoneNumberPlus) ? acc.get(phoneNumberPlus) : [];
|
||||
@@ -380,7 +392,7 @@ class ChatwootImport {
|
||||
|
||||
public async getContactsOrderByRecentConversations(
|
||||
inbox: inbox,
|
||||
provider: ChatwootRaw,
|
||||
provider: ChatwootModel,
|
||||
limit = 50,
|
||||
): Promise<{ id: number; phone_number: string; identifier: string }[]> {
|
||||
try {
|
||||
@@ -394,7 +406,7 @@ class ChatwootImport {
|
||||
ORDER BY conversations.last_activity_at DESC
|
||||
LIMIT $3`;
|
||||
|
||||
return (await pgClient.query(sql, [provider.account_id, inbox.id, limit]))?.rows;
|
||||
return (await pgClient.query(sql, [provider.accountId, inbox.id, limit]))?.rows;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error on get recent conversations: ${error.toString()}`);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
import * as amqp from 'amqplib/callback_api';
|
||||
|
||||
import { configService, Rabbitmq } from '../../../../config/env.config';
|
||||
@@ -107,12 +108,14 @@ export const initQueues = (instanceName: string, events: string[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const removeQueues = (instanceName: string, events: string[]) => {
|
||||
if (!events || !events.length) return;
|
||||
export const removeQueues = (instanceName: string, events: JsonValue) => {
|
||||
const eventsArray = Array.isArray(events) ? events.map((event) => String(event)) : [];
|
||||
|
||||
if (!events || !eventsArray.length) return;
|
||||
|
||||
const channel = getAMQP();
|
||||
|
||||
const queues = events.map((event) => {
|
||||
const queues = eventsArray.map((event) => {
|
||||
return `${event.replace(/_/g, '.').toLowerCase()}`;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class RabbitmqRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
}
|
||||
|
||||
const rabbitmqSchema = new Schema<RabbitmqRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
});
|
||||
|
||||
export const RabbitmqModel = mongodbServer?.model(RabbitmqRaw.name, rabbitmqSchema, 'rabbitmq');
|
||||
export type IRabbitmqModel = typeof RabbitmqModel;
|
||||
@@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { IRabbitmqModel, RabbitmqRaw } from '../../../models';
|
||||
|
||||
export class RabbitmqRepository extends Repository {
|
||||
constructor(private readonly rabbitmqModel: IRabbitmqModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('RabbitmqRepository');
|
||||
|
||||
public async create(data: RabbitmqRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating rabbitmq');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving rabbitmq to db');
|
||||
const insert = await this.rabbitmqModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('rabbitmq saved to db: ' + insert.modifiedCount + ' rabbitmq');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving rabbitmq to store');
|
||||
|
||||
this.writeStore<RabbitmqRaw>({
|
||||
path: join(this.storePath, 'rabbitmq'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('rabbitmq saved to store in path: ' + join(this.storePath, 'rabbitmq') + '/' + instance);
|
||||
|
||||
this.logger.verbose('rabbitmq created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<RabbitmqRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding rabbitmq');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding rabbitmq in db');
|
||||
return await this.rabbitmqModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding rabbitmq in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'rabbitmq', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as RabbitmqRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Rabbitmq } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { RabbitmqRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { RabbitmqDto } from '../dto/rabbitmq.dto';
|
||||
import { initQueues } from '../libs/amqp.server';
|
||||
@@ -18,7 +19,7 @@ export class RabbitmqService {
|
||||
return { rabbitmq: { ...instance, rabbitmq: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<RabbitmqRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Rabbitmq> {
|
||||
try {
|
||||
this.logger.verbose('find rabbitmq: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findRabbitmq();
|
||||
@@ -29,7 +30,7 @@ export class RabbitmqService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, events: [] };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SQS } from '@aws-sdk/client-sqs';
|
||||
import { JsonValue } from '@prisma/client/runtime/library';
|
||||
|
||||
import { configService, Sqs } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
@@ -59,12 +60,13 @@ export const initQueues = (instanceName: string, events: string[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const removeQueues = (instanceName: string, events: string[]) => {
|
||||
if (!events || !events.length) return;
|
||||
export const removeQueues = (instanceName: string, events: JsonValue) => {
|
||||
const eventsArray = Array.isArray(events) ? events.map((event) => String(event)) : [];
|
||||
if (!events || !eventsArray.length) return;
|
||||
|
||||
const sqs = getSQS();
|
||||
|
||||
const queues = events.map((event) => {
|
||||
const queues = eventsArray.map((event) => {
|
||||
return `${event.replace(/_/g, '_').toLowerCase()}`;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class SqsRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
}
|
||||
|
||||
const sqsSchema = new Schema<SqsRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
});
|
||||
|
||||
export const SqsModel = mongodbServer?.model(SqsRaw.name, sqsSchema, 'sqs');
|
||||
export type ISqsModel = typeof SqsModel;
|
||||
@@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { ISqsModel, SqsRaw } from '../../../models';
|
||||
|
||||
export class SqsRepository extends Repository {
|
||||
constructor(private readonly sqsModel: ISqsModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('SqsRepository');
|
||||
|
||||
public async create(data: SqsRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating sqs');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving sqs to db');
|
||||
const insert = await this.sqsModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('sqs saved to db: ' + insert.modifiedCount + ' sqs');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving sqs to store');
|
||||
|
||||
this.writeStore<SqsRaw>({
|
||||
path: join(this.storePath, 'sqs'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('sqs saved to store in path: ' + join(this.storePath, 'sqs') + '/' + instance);
|
||||
|
||||
this.logger.verbose('sqs created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<SqsRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding sqs');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding sqs in db');
|
||||
return await this.sqsModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding sqs in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'sqs', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as SqsRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Sqs } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { SqsRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { SqsDto } from '../dto/sqs.dto';
|
||||
import { initQueues } from '../libs/sqs.server';
|
||||
@@ -18,7 +19,7 @@ export class SqsService {
|
||||
return { sqs: { ...instance, sqs: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<SqsRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Sqs> {
|
||||
try {
|
||||
this.logger.verbose('find sqs: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findSqs();
|
||||
@@ -29,7 +30,7 @@ export class SqsService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, events: [] };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { TypebotSession } from '@prisma/client';
|
||||
|
||||
export class Session {
|
||||
remoteJid?: string;
|
||||
sessionId?: string;
|
||||
@@ -19,9 +21,9 @@ export class TypebotDto {
|
||||
url: string;
|
||||
typebot?: string;
|
||||
expire?: number;
|
||||
keyword_finish?: string;
|
||||
delay_message?: number;
|
||||
unknown_message?: string;
|
||||
listening_from_me?: boolean;
|
||||
sessions?: Session[];
|
||||
keywordFinish?: string;
|
||||
delayMessage?: number;
|
||||
unknownMessage?: string;
|
||||
listeningFromMe?: boolean;
|
||||
sessions?: TypebotSession[];
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
class Session {
|
||||
remoteJid?: string;
|
||||
sessionId?: string;
|
||||
status?: string;
|
||||
createdAt?: number;
|
||||
updateAt?: number;
|
||||
prefilledVariables?: {
|
||||
remoteJid?: string;
|
||||
pushName?: string;
|
||||
additionalData?: { [key: string]: any };
|
||||
};
|
||||
}
|
||||
|
||||
export class TypebotRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
url: string;
|
||||
typebot?: string;
|
||||
expire?: number;
|
||||
keyword_finish?: string;
|
||||
delay_message?: number;
|
||||
unknown_message?: string;
|
||||
listening_from_me?: boolean;
|
||||
sessions?: Session[];
|
||||
}
|
||||
|
||||
const typebotSchema = new Schema<TypebotRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
url: { type: String, required: true },
|
||||
typebot: { type: String, required: true },
|
||||
expire: { type: Number, required: true },
|
||||
keyword_finish: { type: String, required: true },
|
||||
delay_message: { type: Number, required: true },
|
||||
unknown_message: { type: String, required: true },
|
||||
listening_from_me: { type: Boolean, required: true },
|
||||
sessions: [
|
||||
{
|
||||
remoteJid: { type: String, required: true },
|
||||
sessionId: { type: String, required: true },
|
||||
status: { type: String, required: true },
|
||||
createdAt: { type: Number, required: true },
|
||||
updateAt: { type: Number, required: true },
|
||||
prefilledVariables: {
|
||||
remoteJid: { type: String, required: false },
|
||||
pushName: { type: String, required: false },
|
||||
additionalData: { type: Schema.Types.Mixed, required: false },
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
export const TypebotModel = mongodbServer?.model(TypebotRaw.name, typebotSchema, 'typebot');
|
||||
export type ITypebotModel = typeof TypebotModel;
|
||||
@@ -1,68 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { ITypebotModel, TypebotRaw } from '../../../models';
|
||||
|
||||
export class TypebotRepository extends Repository {
|
||||
constructor(private readonly typebotModel: ITypebotModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('TypebotRepository');
|
||||
|
||||
public async create(data: TypebotRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating typebot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving typebot to db');
|
||||
const insert = await this.typebotModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('typebot saved to db: ' + insert.modifiedCount + ' typebot');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving typebot to store');
|
||||
|
||||
this.writeStore<TypebotRaw>({
|
||||
path: join(this.storePath, 'typebot'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('typebot saved to store in path: ' + join(this.storePath, 'typebot') + '/' + instance);
|
||||
|
||||
this.logger.verbose('typebot created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<TypebotRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding typebot');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding typebot in db');
|
||||
return await this.typebotModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding typebot in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'typebot', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as TypebotRaw;
|
||||
} catch (error) {
|
||||
return {
|
||||
enabled: false,
|
||||
url: '',
|
||||
typebot: '',
|
||||
expire: 0,
|
||||
sessions: [],
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +1,13 @@
|
||||
import { Message } from '@prisma/client';
|
||||
import axios from 'axios';
|
||||
import EventEmitter2 from 'eventemitter2';
|
||||
|
||||
import { ConfigService, Typebot } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { MessageRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { Events } from '../../../types/wa.types';
|
||||
import { Session, TypebotDto } from '../dto/typebot.dto';
|
||||
import { TypebotDto } from '../dto/typebot.dto';
|
||||
|
||||
export class TypebotService {
|
||||
constructor(
|
||||
@@ -64,10 +64,10 @@ export class TypebotService {
|
||||
url: findData.url,
|
||||
typebot: findData.typebot,
|
||||
expire: findData.expire,
|
||||
keyword_finish: findData.keyword_finish,
|
||||
delay_message: findData.delay_message,
|
||||
unknown_message: findData.unknown_message,
|
||||
listening_from_me: findData.listening_from_me,
|
||||
keywordFinish: findData.keywordFinish,
|
||||
delayMessage: findData.delayMessage,
|
||||
unknownMessage: findData.unknownMessage,
|
||||
listeningFromMe: findData.listeningFromMe,
|
||||
sessions: findData.sessions,
|
||||
};
|
||||
|
||||
@@ -82,19 +82,19 @@ export class TypebotService {
|
||||
}
|
||||
});
|
||||
} else if (status === 'paused') {
|
||||
const session: Session = {
|
||||
remoteJid: remoteJid,
|
||||
sessionId: Math.floor(Math.random() * 10000000000).toString(),
|
||||
status: status,
|
||||
createdAt: Date.now(),
|
||||
updateAt: Date.now(),
|
||||
prefilledVariables: {
|
||||
remoteJid: remoteJid,
|
||||
pushName: '',
|
||||
additionalData: {},
|
||||
},
|
||||
};
|
||||
findData.sessions.push(session);
|
||||
// const session: Session = {
|
||||
// remoteJid: remoteJid,
|
||||
// sessionId: Math.floor(Math.random() * 10000000000).toString(),
|
||||
// status: status,
|
||||
// createdAt: Date.now(),
|
||||
// updateAt: Date.now(),
|
||||
// prefilledVariables: {
|
||||
// remoteJid: remoteJid,
|
||||
// pushName: '',
|
||||
// additionalData: {},
|
||||
// },
|
||||
// };
|
||||
// findData.sessions.push(session);
|
||||
}
|
||||
|
||||
const typebotData = {
|
||||
@@ -102,10 +102,10 @@ export class TypebotService {
|
||||
url: findData.url,
|
||||
typebot: findData.typebot,
|
||||
expire: findData.expire,
|
||||
keyword_finish: findData.keyword_finish,
|
||||
delay_message: findData.delay_message,
|
||||
unknown_message: findData.unknown_message,
|
||||
listening_from_me: findData.listening_from_me,
|
||||
keywordFinish: findData.keywordFinish,
|
||||
delayMessage: findData.delayMessage,
|
||||
unknownMessage: findData.unknownMessage,
|
||||
listeningFromMe: findData.listeningFromMe,
|
||||
sessions: findData.sessions,
|
||||
};
|
||||
|
||||
@@ -124,7 +124,8 @@ export class TypebotService {
|
||||
|
||||
public async clearSessions(instance: InstanceDto, remoteJid: string) {
|
||||
const findTypebot = await this.find(instance);
|
||||
const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
const sessions = [];
|
||||
// const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
|
||||
const sessionWithRemoteJid = sessions.filter((session) => session.remoteJid === remoteJid);
|
||||
|
||||
@@ -138,10 +139,10 @@ export class TypebotService {
|
||||
url: findTypebot.url,
|
||||
typebot: findTypebot.typebot,
|
||||
expire: findTypebot.expire,
|
||||
keyword_finish: findTypebot.keyword_finish,
|
||||
delay_message: findTypebot.delay_message,
|
||||
unknown_message: findTypebot.unknown_message,
|
||||
listening_from_me: findTypebot.listening_from_me,
|
||||
keywordFinish: findTypebot.keywordFinish,
|
||||
delayMessage: findTypebot.delayMessage,
|
||||
unknownMessage: findTypebot.unknownMessage,
|
||||
listeningFromMe: findTypebot.listeningFromMe,
|
||||
sessions,
|
||||
};
|
||||
|
||||
@@ -163,10 +164,10 @@ export class TypebotService {
|
||||
const variables = data.variables;
|
||||
const findTypebot = await this.find(instance);
|
||||
const expire = findTypebot.expire;
|
||||
const keyword_finish = findTypebot.keyword_finish;
|
||||
const delay_message = findTypebot.delay_message;
|
||||
const unknown_message = findTypebot.unknown_message;
|
||||
const listening_from_me = findTypebot.listening_from_me;
|
||||
const keywordFinish = findTypebot.keywordFinish;
|
||||
const delayMessage = findTypebot.delayMessage;
|
||||
const unknownMessage = findTypebot.unknownMessage;
|
||||
const listeningFromMe = findTypebot.listeningFromMe;
|
||||
|
||||
const prefilledVariables = {
|
||||
remoteJid: remoteJid,
|
||||
@@ -188,10 +189,10 @@ export class TypebotService {
|
||||
typebot: typebot,
|
||||
remoteJid: remoteJid,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
prefilledVariables: prefilledVariables,
|
||||
});
|
||||
@@ -467,10 +468,10 @@ export class TypebotService {
|
||||
url: data.url,
|
||||
typebot: data.typebot,
|
||||
expire: data.expire,
|
||||
keyword_finish: data.keyword_finish,
|
||||
delay_message: data.delay_message,
|
||||
unknown_message: data.unknown_message,
|
||||
listening_from_me: data.listening_from_me,
|
||||
keywordFinish: data.keywordFinish,
|
||||
delayMessage: data.delayMessage,
|
||||
unknownMessage: data.unknownMessage,
|
||||
listeningFromMe: data.listeningFromMe,
|
||||
sessions: data.sessions,
|
||||
};
|
||||
|
||||
@@ -585,7 +586,7 @@ export class TypebotService {
|
||||
await instance.textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
@@ -598,7 +599,7 @@ export class TypebotService {
|
||||
await instance.mediaMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
mediaMessage: {
|
||||
@@ -612,7 +613,7 @@ export class TypebotService {
|
||||
await instance.mediaMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
mediaMessage: {
|
||||
@@ -626,7 +627,7 @@ export class TypebotService {
|
||||
await instance.audioWhatsapp({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'recording',
|
||||
encoding: true,
|
||||
},
|
||||
@@ -658,7 +659,7 @@ export class TypebotService {
|
||||
await instance.textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: instance.localTypebot.delay_message || 1000,
|
||||
delay: instance.localTypebot.delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
@@ -675,16 +676,17 @@ export class TypebotService {
|
||||
}
|
||||
}
|
||||
|
||||
public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: MessageRaw) {
|
||||
public async sendTypebot(instance: InstanceDto, remoteJid: string, msg: Message) {
|
||||
const findTypebot = await this.find(instance);
|
||||
const url = findTypebot.url;
|
||||
const typebot = findTypebot.typebot;
|
||||
const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
// const sessions = (findTypebot.sessions as Session[]) ?? [];
|
||||
const sessions = [];
|
||||
const expire = findTypebot.expire;
|
||||
const keyword_finish = findTypebot.keyword_finish;
|
||||
const delay_message = findTypebot.delay_message;
|
||||
const unknown_message = findTypebot.unknown_message;
|
||||
const listening_from_me = findTypebot.listening_from_me;
|
||||
const keywordFinish = findTypebot.keywordFinish;
|
||||
const delayMessage = findTypebot.delayMessage;
|
||||
const unknownMessage = findTypebot.unknownMessage;
|
||||
const listeningFromMe = findTypebot.listeningFromMe;
|
||||
const messageType = this.getTypeMessage(msg.message).messageType;
|
||||
|
||||
const session = sessions.find((session) => session.remoteJid === remoteJid);
|
||||
@@ -705,10 +707,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
remoteJid: remoteJid,
|
||||
pushName: msg.pushName,
|
||||
@@ -720,22 +722,22 @@ export class TypebotService {
|
||||
const content = this.getConversationMessage(msg.message);
|
||||
|
||||
if (!content) {
|
||||
if (unknown_message) {
|
||||
if (unknownMessage) {
|
||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: delay_message || 1000,
|
||||
delay: delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
text: unknown_message,
|
||||
text: unknownMessage,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) {
|
||||
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
|
||||
const newSessions = await this.clearSessions(instance, remoteJid);
|
||||
|
||||
const typebotData = {
|
||||
@@ -743,10 +745,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
};
|
||||
|
||||
@@ -801,10 +803,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: sessions,
|
||||
remoteJid: remoteJid,
|
||||
pushName: msg.pushName,
|
||||
@@ -819,22 +821,22 @@ export class TypebotService {
|
||||
const content = this.getConversationMessage(msg.message);
|
||||
|
||||
if (!content) {
|
||||
if (unknown_message) {
|
||||
if (unknownMessage) {
|
||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: delay_message || 1000,
|
||||
delay: delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
text: unknown_message,
|
||||
text: unknownMessage,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) {
|
||||
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
|
||||
const newSessions = await this.clearSessions(instance, remoteJid);
|
||||
|
||||
const typebotData = {
|
||||
@@ -842,10 +844,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
};
|
||||
|
||||
@@ -899,10 +901,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions,
|
||||
};
|
||||
|
||||
@@ -911,22 +913,22 @@ export class TypebotService {
|
||||
const content = this.getConversationMessage(msg.message);
|
||||
|
||||
if (!content) {
|
||||
if (unknown_message) {
|
||||
if (unknownMessage) {
|
||||
this.waMonitor.waInstances[instance.instanceName].textMessage({
|
||||
number: remoteJid.split('@')[0],
|
||||
options: {
|
||||
delay: delay_message || 1000,
|
||||
delay: delayMessage || 1000,
|
||||
presence: 'composing',
|
||||
},
|
||||
textMessage: {
|
||||
text: unknown_message,
|
||||
text: unknownMessage,
|
||||
},
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyword_finish && content.toLowerCase() === keyword_finish.toLowerCase()) {
|
||||
if (keywordFinish && content.toLowerCase() === keywordFinish.toLowerCase()) {
|
||||
const newSessions = await this.clearSessions(instance, remoteJid);
|
||||
|
||||
const typebotData = {
|
||||
@@ -934,10 +936,10 @@ export class TypebotService {
|
||||
url: url,
|
||||
typebot: typebot,
|
||||
expire: expire,
|
||||
keyword_finish: keyword_finish,
|
||||
delay_message: delay_message,
|
||||
unknown_message: unknown_message,
|
||||
listening_from_me: listening_from_me,
|
||||
keywordFinish: keywordFinish,
|
||||
delayMessage: delayMessage,
|
||||
unknownMessage: unknownMessage,
|
||||
listeningFromMe: listeningFromMe,
|
||||
sessions: newSessions,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { Schema } from 'mongoose';
|
||||
|
||||
import { mongodbServer } from '../../../../libs/mongodb.connect';
|
||||
|
||||
export class WebsocketRaw {
|
||||
_id?: string;
|
||||
enabled?: boolean;
|
||||
events?: string[];
|
||||
}
|
||||
|
||||
const websocketSchema = new Schema<WebsocketRaw>({
|
||||
_id: { type: String, _id: true },
|
||||
enabled: { type: Boolean, required: true },
|
||||
events: { type: [String], required: true },
|
||||
});
|
||||
|
||||
export const WebsocketModel = mongodbServer?.model(WebsocketRaw.name, websocketSchema, 'websocket');
|
||||
export type IWebsocketModel = typeof WebsocketModel;
|
||||
@@ -1,62 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { ConfigService } from '../../../../config/env.config';
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { IInsert, Repository } from '../../../abstract/abstract.repository';
|
||||
import { IWebsocketModel, WebsocketRaw } from '../../../models';
|
||||
|
||||
export class WebsocketRepository extends Repository {
|
||||
constructor(private readonly websocketModel: IWebsocketModel, private readonly configService: ConfigService) {
|
||||
super(configService);
|
||||
}
|
||||
|
||||
private readonly logger = new Logger('WebsocketRepository');
|
||||
|
||||
public async create(data: WebsocketRaw, instance: string): Promise<IInsert> {
|
||||
try {
|
||||
this.logger.verbose('creating websocket');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('saving websocket to db');
|
||||
const insert = await this.websocketModel.replaceOne({ _id: instance }, { ...data }, { upsert: true });
|
||||
|
||||
this.logger.verbose('websocket saved to db: ' + insert.modifiedCount + ' websocket');
|
||||
return { insertCount: insert.modifiedCount };
|
||||
}
|
||||
|
||||
this.logger.verbose('saving websocket to store');
|
||||
|
||||
this.writeStore<WebsocketRaw>({
|
||||
path: join(this.storePath, 'websocket'),
|
||||
fileName: instance,
|
||||
data,
|
||||
});
|
||||
|
||||
this.logger.verbose('websocket saved to store in path: ' + join(this.storePath, 'websocket') + '/' + instance);
|
||||
|
||||
this.logger.verbose('websocket created');
|
||||
return { insertCount: 1 };
|
||||
} catch (error) {
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
public async find(instance: string): Promise<WebsocketRaw> {
|
||||
try {
|
||||
this.logger.verbose('finding websocket');
|
||||
if (this.dbSettings.ENABLED) {
|
||||
this.logger.verbose('finding websocket in db');
|
||||
return await this.websocketModel.findOne({ _id: instance });
|
||||
}
|
||||
|
||||
this.logger.verbose('finding websocket in store');
|
||||
return JSON.parse(
|
||||
readFileSync(join(this.storePath, 'websocket', instance + '.json'), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
) as WebsocketRaw;
|
||||
} catch (error) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Websocket } from '@prisma/client';
|
||||
|
||||
import { Logger } from '../../../../config/logger.config';
|
||||
import { InstanceDto } from '../../../dto/instance.dto';
|
||||
import { WebsocketRaw } from '../../../models';
|
||||
import { WAMonitoringService } from '../../../services/monitor.service';
|
||||
import { WebsocketDto } from '../dto/websocket.dto';
|
||||
|
||||
@@ -16,7 +17,7 @@ export class WebsocketService {
|
||||
return { websocket: { ...instance, websocket: data } };
|
||||
}
|
||||
|
||||
public async find(instance: InstanceDto): Promise<WebsocketRaw> {
|
||||
public async find(instance: InstanceDto): Promise<Websocket> {
|
||||
try {
|
||||
this.logger.verbose('find websocket: ' + instance.instanceName);
|
||||
const result = await this.waMonitor.waInstances[instance.instanceName].findWebsocket();
|
||||
@@ -27,7 +28,7 @@ export class WebsocketService {
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
return { enabled: false, events: [] };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user