Skip to content

Commit

Permalink
feat: send pix button
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidsonGomes committed Oct 29, 2024
1 parent 23640a7 commit fbccf2e
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"jsonschema": "^1.4.1",
"link-preview-js": "^3.0.4",
"long": "^5.2.3",
"mediainfo.js": "^0.3.2",
"mime": "^3.0.0",
"minio": "^8.0.1",
"multer": "^1.4.5-lts.1",
Expand Down
94 changes: 94 additions & 0 deletions src/api/integrations/channel/whatsapp/whatsapp.baileys.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,70 @@ import qrcodeTerminal from 'qrcode-terminal';
import sharp from 'sharp';
import { PassThrough } from 'stream';
import { v4 } from 'uuid';
import { Readable } from 'stream';

const groupMetadataCache = new CacheService(new CacheEngine(configService, 'groups').getEngine());

// Adicione a função getVideoDuration no início do arquivo
async function getVideoDuration(input: Buffer | string | Readable): Promise<number> {
const MediaInfoFactory = (await import('mediainfo.js')).default;
const mediainfo = await MediaInfoFactory({ format: 'JSON' });

let fileSize: number;
let readChunk: (size: number, offset: number) => Promise<Buffer>;

if (Buffer.isBuffer(input)) {
fileSize = input.length;
readChunk = async (size: number, offset: number): Promise<Buffer> => {
return input.slice(offset, offset + size);
};
} else if (typeof input === 'string') {
const fs = await import('fs');
const stat = await fs.promises.stat(input);
fileSize = stat.size;
const fd = await fs.promises.open(input, 'r');

readChunk = async (size: number, offset: number): Promise<Buffer> => {
const buffer = Buffer.alloc(size);
await fd.read(buffer, 0, size, offset);
return buffer;
};

try {
const result = await mediainfo.analyzeData(() => fileSize, readChunk);
const jsonResult = JSON.parse(result);

const generalTrack = jsonResult.media.track.find((t: any) => t['@type'] === 'General');
const duration = generalTrack.Duration;

return Math.round(parseFloat(duration));
} finally {
await fd.close();
}
} else if (input instanceof Readable) {
const chunks: Buffer[] = [];
for await (const chunk of input) {
chunks.push(chunk);
}
const data = Buffer.concat(chunks);
fileSize = data.length;

readChunk = async (size: number, offset: number): Promise<Buffer> => {
return data.slice(offset, offset + size);
};
} else {
throw new Error('Tipo de entrada não suportado');
}

const result = await mediainfo.analyzeData(() => fileSize, readChunk);
const jsonResult = JSON.parse(result);

const generalTrack = jsonResult.media.track.find((t: any) => t['@type'] === 'General');
const duration = generalTrack.Duration;

return Math.round(parseFloat(duration));
}

export class BaileysStartupService extends ChannelStartupService {
constructor(
public readonly configService: ConfigService,
Expand Down Expand Up @@ -1101,6 +1162,7 @@ export class BaileysStartupService extends ChannelStartupService {
received?.message?.stickerMessage ||
received?.message?.documentMessage ||
received?.message?.documentWithCaptionMessage ||
received?.message?.ptvMessage ||
received?.message?.audioMessage;

if (this.localSettings.readMessages && received.key.id !== 'status@broadcast') {
Expand Down Expand Up @@ -2097,6 +2159,7 @@ export class BaileysStartupService extends ChannelStartupService {
messageSent?.message?.ptvMessage ||
messageSent?.message?.documentMessage ||
messageSent?.message?.documentWithCaptionMessage ||
messageSent?.message?.ptvMessage ||
messageSent?.message?.audioMessage;

if (this.configService.get<Chatwoot>('CHATWOOT').ENABLED && this.localChatwoot?.enabled && !isIntegration) {
Expand Down Expand Up @@ -2500,6 +2563,37 @@ export class BaileysStartupService extends ChannelStartupService {

if (mediaMessage.mediatype === 'ptv') {
prepareMedia[mediaType] = prepareMedia[type + 'Message'];
mimetype = 'video/mp4';

if (!prepareMedia[mediaType]) {
throw new Error('Failed to prepare video message');
}

try {
let mediaInput;
if (isURL(mediaMessage.media)) {
mediaInput = mediaMessage.media;
} else {
const mediaBuffer = Buffer.from(mediaMessage.media, 'base64');
if (!mediaBuffer || mediaBuffer.length === 0) {
throw new Error('Invalid media buffer');
}
mediaInput = mediaBuffer;
}

const duration = await getVideoDuration(mediaInput);
if (!duration || duration <= 0) {
throw new Error('Invalid media duration');
}

this.logger.verbose(`Video duration: ${duration} seconds`);
prepareMedia[mediaType].seconds = duration;

} catch (error) {
this.logger.error('Error getting video duration:');
this.logger.error(error);
throw new Error(`Failed to get video duration: ${error.message}`);
}
}

prepareMedia[mediaType].caption = mediaMessage?.caption;
Expand Down
2 changes: 1 addition & 1 deletion src/api/types/wa.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ export declare namespace wa {
export type StatusMessage = 'ERROR' | 'PENDING' | 'SERVER_ACK' | 'DELIVERY_ACK' | 'READ' | 'DELETED' | 'PLAYED';
}

export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage'];
export const TypeMediaMessage = ['imageMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'stickerMessage', 'ptvMessage'];

export const MessageSubtype = [
'ephemeralMessage',
Expand Down

0 comments on commit fbccf2e

Please sign in to comment.