Skip to content

Commit

Permalink
refactor: using stream instead of temp files in chatwoot and reposito…
Browse files Browse the repository at this point in the history
…ry services

This commit refactors the code in the `chatwoot.service.ts` and `repository.service.ts` files to use streams instead of temporary files. This change reduces the number of disk operations, making the application faster and more efficient.

In the `chatwoot.service.ts` file, the `createReadStream`, `unlinkSync`, and `writeFileSync` functions have been replaced with the `Readable` stream. The `sendData` method has been updated to accept a `fileStream` and `fileName` instead of a file path. The `processImage` method has been refactored to use a stream instead of writing the image to a file.

In the `repository.service.ts` file, the `initStoreFolders` method has been removed, as it is no longer needed.

These changes improve the maintainability of the codebase by reducing the number of disk operations and simplifying the code. This refactoring also makes the application more efficient and faster, as it reduces the number of disk operations.

Motivation:
The motivation behind this refactoring is to improve the performance and efficiency of the application by reducing the number of disk operations.

Impact:
This refactoring reduces the number of disk operations, making the application faster and more efficient. It also simplifies the codebase and improves its maintainability.
  • Loading branch information
dgcode-tec committed Jul 13, 2024
1 parent d3ab402 commit e3a97d0
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 51 deletions.
70 changes: 40 additions & 30 deletions src/api/integrations/chatwoot/services/chatwoot.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ import { Chatwoot as ChatwootModel, Contact as ContactModel, Message as MessageM
import axios from 'axios';
import { proto } from 'baileys';
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';
import { Readable } from 'stream';

import { Chatwoot, ConfigService, HttpServer } from '../../../../config/env.config';
import { Logger } from '../../../../config/logger.config';
Expand Down Expand Up @@ -867,7 +867,8 @@ export class ChatwootService {

private async sendData(
conversationId: number,
file: string,
fileStream: Readable,
fileName: string,
messageType: 'incoming' | 'outgoing' | undefined,
content?: string,
instance?: InstanceDto,
Expand All @@ -883,7 +884,7 @@ export class ChatwootService {

data.append('message_type', messageType);

data.append('attachments[]', createReadStream(file));
data.append('attachments[]', fileStream, { filename: fileName });

const sourceReplyId = quotedMsg?.chatwootMessageId || null;

Expand Down Expand Up @@ -919,20 +920,18 @@ export class ChatwootService {
try {
const { data } = await axios.request(config);

unlinkSync(file);

return data;
} catch (error) {
this.logger.error(error);
unlinkSync(file);
}
}

public async createBotQr(
instance: InstanceDto,
content: string,
messageType: 'incoming' | 'outgoing' | undefined,
file?: string,
fileStream?: Readable,
fileName?: string,
) {
const client = await this.clientCw(instance);

Expand Down Expand Up @@ -970,8 +969,8 @@ export class ChatwootService {

data.append('message_type', messageType);

if (file) {
data.append('attachments[]', createReadStream(file));
if (fileStream && fileName) {
data.append('attachments[]', fileStream, { filename: fileName });
}

const config = {
Expand All @@ -988,8 +987,6 @@ export class ChatwootService {
try {
const { data } = await axios.request(config);

unlinkSync(file);

return data;
} catch (error) {
this.logger.error(error);
Expand Down Expand Up @@ -1838,9 +1835,10 @@ export class ChatwootService {

const fileData = Buffer.from(downloadBase64.base64, 'base64');

const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`;

writeFileSync(fileName, fileData, 'utf8');
const fileStream = new Readable();
fileStream._read = () => {};
fileStream.push(fileData);
fileStream.push(null);

if (body.key.remoteJid.includes('@g.us')) {
const participantName = body.pushName;
Expand All @@ -1855,7 +1853,8 @@ export class ChatwootService {

const send = await this.sendData(
getConversation,
fileName,
fileStream,
nameFile,
messageType,
content,
instance,
Expand All @@ -1873,7 +1872,8 @@ export class ChatwootService {
} else {
const send = await this.sendData(
getConversation,
fileName,
fileStream,
nameFile,
messageType,
bodyMessage,
instance,
Expand Down Expand Up @@ -1929,15 +1929,17 @@ export class ChatwootService {
const random = Math.random().toString(36).substring(7);
const nameFile = `${random}.${mimeTypes.extension(mimeType)}`;
const fileData = Buffer.from(imgBuffer.data, 'binary');
const fileName = `${path.join(waInstance?.storePath, 'temp', `${nameFile}`)}`;

await Jimp.read(fileData)
.then(async (img) => {
await img.cover(320, 180).writeAsync(fileName);
})
.catch((err) => {
this.logger.error(`image is not write: ${err}`);
});

const img = await Jimp.read(fileData);
await img.cover(320, 180);

const processedBuffer = await img.getBufferAsync(Jimp.MIME_PNG);

const fileStream = new Readable();
fileStream._read = () => {}; // _read is required but you can noop it
fileStream.push(processedBuffer);
fileStream.push(null);

const truncStr = (str: string, len: number) => {
return str.length > len ? str.substring(0, len) + '...' : str;
};
Expand All @@ -1947,7 +1949,8 @@ export class ChatwootService {

const send = await this.sendData(
getConversation,
fileName,
fileStream,
nameFile,
messageType,
`${bodyMessage}\n\n\n**${title}**\n${description}\n${adsMessage.sourceUrl}`,
instance,
Expand Down Expand Up @@ -2156,11 +2159,18 @@ export class ChatwootService {
} else {
const fileData = Buffer.from(body?.qrcode.base64.replace('data:image/png;base64,', ''), 'base64');

const fileName = `${path.join(waInstance?.storePath, 'temp', `${instance.instanceName}.png`)}`;

writeFileSync(fileName, fileData, 'utf8');
const fileStream = new Readable();
fileStream._read = () => {};
fileStream.push(fileData);
fileStream.push(null);

await this.createBotQr(instance, i18next.t('qrgeneratedsuccesfully'), 'incoming', fileName);
await this.createBotQr(
instance,
i18next.t('qrgeneratedsuccesfully'),
'incoming',
fileStream,
`${instance.instanceName}.png`,
);

let msgQrCode = `⚡️${i18next.t('qrgeneratedsuccesfully')}\n\n${i18next.t('scanqr')}`;

Expand Down
21 changes: 0 additions & 21 deletions src/api/repository/repository.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { PrismaClient } from '@prisma/client';
import fs from 'fs';
import { join } from 'path';

import { ConfigService } from '../../config/env.config';
import { Logger } from '../../config/logger.config';
Expand All @@ -15,29 +13,10 @@ export class Query<T> {
export class PrismaRepository extends PrismaClient {
constructor(private readonly configService: ConfigService) {
super();

this.initStoreFolders();
}

private readonly logger = new Logger(PrismaRepository.name);

private async initStoreFolders() {
try {
const storePath = join(process.cwd(), 'store');

this.logger.verbose('creating store path: ' + storePath);

const tempDir = join(storePath, 'temp');

if (!fs.existsSync(tempDir)) {
this.logger.verbose('creating temp dir: ' + tempDir);
fs.mkdirSync(tempDir, { recursive: true });
}
} catch (error) {
this.logger.error(error);
}
}

public async onModuleInit() {
await this.$connect();
this.logger.info('Repository:Prisma - ON');
Expand Down

0 comments on commit e3a97d0

Please sign in to comment.