Skip to content

Commit

Permalink
media management
Browse files Browse the repository at this point in the history
  • Loading branch information
jrCleber committed Oct 26, 2024
1 parent b1050fc commit 3925ffb
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 30 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ lerna-debug.log*
!/instances/.gitkeep
/test/
.env
/uploads
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "whatsapp-api",
"version": "1.3.3",
"version": "1.3.4",
"description": "Rest api for communication with WhatsApp",
"main": "./dist/src/main.js",
"scripts": {
Expand Down Expand Up @@ -57,7 +57,6 @@
"fluent-ffmpeg": "^2.1.3",
"form-data": "^4.0.0",
"hbs": "^4.2.0",
"join": "^3.0.0",
"js-yaml": "^4.1.0",
"jsonschema": "^1.4.1",
"jsonwebtoken": "^9.0.2",
Expand Down
32 changes: 32 additions & 0 deletions prisma/migrations/20241026114039_codechat/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
-- AlterTable
ALTER TABLE "ActivityLogs" ALTER COLUMN "dateTime" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Auth" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Chat" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Contact" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Instance" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Media" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "MessageUpdate" ALTER COLUMN "dateTime" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Typebot" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);

-- AlterTable
ALTER TABLE "Webhook" ALTER COLUMN "createdAt" SET DATA TYPE TIMESTAMP(3),
ALTER COLUMN "updatedAt" SET DATA TYPE TIMESTAMP(3);
2 changes: 1 addition & 1 deletion src/validate/validate.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@
*/

import { JSONSchema7, JSONSchema7Definition } from 'json-schema';
import { title } from 'process';
import { ulid } from 'ulid';

const isNotEmpty = (...propertyNames: string[]): JSONSchema7 => {
Expand Down Expand Up @@ -101,6 +100,7 @@ const optionsSchema: JSONSchema7 = {
},
quotedMessageId: { type: 'integer', description: 'Enter the message id' },
messageId: { type: 'string', description: 'Set your own id for the message.' },
convertAudio: { type: 'boolean', description: 'Convert audio to ogg' },
},
};

Expand Down
16 changes: 12 additions & 4 deletions src/whatsapp/controllers/sendMessage.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ export class SendMessageController {
if (isBase64(data?.mediaMessage?.media)) {
throw new BadRequestException('Owned media must be a url');
}
if (data.mediaMessage.mediatype === 'document' && !data.mediaMessage?.fileName) {
throw new BadRequestException(
'The "fileName" property must be provided for documents',
);
}
if (isURL(data?.mediaMessage?.media as string)) {
return await this.waMonitor.waInstances.get(instanceName).mediaMessage(data);
}
Expand All @@ -72,7 +77,7 @@ export class SendMessageController {
public async sendMediaFile(
{ instanceName }: InstanceDto,
data: MediaFileDto,
file: Express.Multer.File,
fileName: string,
) {
if (data?.delay && !isNumberString(data.delay)) {
throw new BadRequestException('The "delay" property must have an integer.');
Expand All @@ -81,7 +86,7 @@ export class SendMessageController {
}
return await this.waMonitor.waInstances
.get(instanceName)
.mediaFileMessage(data, file);
.mediaFileMessage(data, fileName);
}

public async sendWhatsAppAudio({ instanceName }: InstanceDto, data: SendAudioDto) {
Expand All @@ -98,16 +103,19 @@ export class SendMessageController {
public async sendWhatsAppAudioFile(
{ instanceName }: InstanceDto,
data: AudioMessageFileDto,
file: Express.Multer.File,
fileName: string,
) {
if (data?.delay && !isNumberString(data.delay)) {
throw new BadRequestException('The "delay" property must have an integer.');
} else {
data.delay = Number.parseInt(data?.delay as never);
}
if (data?.convertAudio) {
data.convertAudio = data.convertAudio === 'true';
}
return await this.waMonitor.waInstances
.get(instanceName)
.audioWhatsAppFile(data, file);
.audioWhatsAppFile(data, fileName);
}

public async sendLocation({ instanceName }: InstanceDto, data: SendLocationDto) {
Expand Down
4 changes: 3 additions & 1 deletion src/whatsapp/dto/sendMessage.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export class Options {
quotedMessageId?: number;
messageId?: string;
externalAttributes?: any;
convertAudio?: boolean;
}
class OptionsMessage {
options: Options;
Expand All @@ -69,8 +70,8 @@ export class MediaMessage {
caption?: string;
// for document
fileName?: string;
// url or base64
media: string | Buffer;
extension?: string;
}
export class SendMediaDto extends Metadata {
mediaMessage: MediaMessage;
Expand All @@ -93,6 +94,7 @@ export class SendAudioDto extends Metadata {
export class AudioMessageFileDto extends Metadata {
delay: number;
audio: Buffer;
convertAudio: boolean | string;
}

class LocationMessage {
Expand Down
24 changes: 20 additions & 4 deletions src/whatsapp/routers/sendMessage.router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ import { isEmpty } from 'class-validator';
import { HttpStatus } from '../../app.module';
import { SendMessageController } from '../controllers/sendMessage.controller';
import { routerPath, dataValidate } from '../../validate/router.validate';
import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { join } from 'path';
import { ROOT_DIR } from '../../config/path.config';

function validateMedia(req: Request, _: Response, next: NextFunction) {
if (!req?.file || req.file.fieldname !== 'attachment') {
Expand All @@ -86,6 +89,11 @@ export function MessageRouter(
sendMessageController: SendMessageController,
...guards: RequestHandler[]
) {
const uploadPath = join(ROOT_DIR, 'uploads');
if (!existsSync(uploadPath)) {
mkdirSync(uploadPath);
}

const uploadFile = multer({ preservePath: true });

const router = Router()
Expand Down Expand Up @@ -116,8 +124,10 @@ export function MessageRouter(
const response = await dataValidate<MediaFileDto>({
request: req,
schema: mediaFileMessageSchema,
execute: (instance, data, file) =>
sendMessageController.sendMediaFile(instance, data, file),
execute: (instance, data, file) => {
writeFileSync(join(uploadPath, file.originalname), file.buffer);
return sendMessageController.sendMediaFile(instance, data, file.originalname);
},
});
res.status(HttpStatus.CREATED).json(response);
},
Expand All @@ -141,8 +151,14 @@ export function MessageRouter(
const response = await dataValidate<AudioMessageFileDto>({
request: req,
schema: audioFileMessageSchema,
execute: (instance, data, file) =>
sendMessageController.sendWhatsAppAudioFile(instance, data, file),
execute: (instance, data, file) => {
writeFileSync(join(uploadPath, file.originalname), file.buffer);
return sendMessageController.sendWhatsAppAudioFile(
instance,
data,
file.originalname,
);
},
});
res.status(HttpStatus.CREATED).json(response);
},
Expand Down
Loading

0 comments on commit 3925ffb

Please sign in to comment.