UNPKG

@solufy/evolution-sdk

Version:

Unofficial SDK for the Evolution Whatsapp API v2

672 lines (657 loc) 20 kB
// src/api/routes.ts var Routes = { Message: { SendText: "message/sendText", SendMedia: "message/sendMedia", SendVoice: "message/sendWhatsAppAudio", SendSticker: "message/sendSticker", SendLocation: "message/sendLocation", SendContact: "message/sendContact", SendPoll: "message/sendPoll" }, Chats: { Check: "chat/whatsappNumbers", FindAll: "chat/findChats", SendPresence: "chat/sendPresence" }, Groups: { FindAll: "group/fetchAllGroups", FindByJid: "group/findGroupInfos", FindByInviteCode: "group/inviteInfo" } }; // src/modules/messages/schemas/audio.ts import { z as z3 } from "zod"; // src/schemas/common.ts import { isValidPhoneNumber, parsePhoneNumber } from "libphonenumber-js"; import { z } from "zod"; var PhoneNumberSchema = z.custom((value) => isValidPhoneNumber(value), "Invalid phone number").transform((phoneNumber) => parsePhoneNumber(phoneNumber).number); var JidSchema = z.string().endsWith( "@s.whatsapp.net", "Invalid remote JID, should end with @s.whatsapp.net" ); var GroupJidSchema = z.string().endsWith( "@g.us", "Invalid group JID, should end with @g.us" ); var GroupInviteCodeSchema = z.string().length(22).regex( /^[a-zA-Z0-9]{22}$/, "Invalid group invite code" ); var ApiNumberSchema = z.union([ PhoneNumberSchema, JidSchema, GroupJidSchema ]); var mediaSchema = z.union([z.string().url(), z.string().base64()]); // src/types/tags.ts var Jid = (jid) => jid; var MessageId = (id) => id; // src/utils/phone-numer-from-jid.ts import { parsePhoneNumber as parsePhoneNumber2 } from "libphonenumber-js"; function phoneNumberFromJid(jid) { return parsePhoneNumber2(`+${jid.split("@")[0]}`).number; } // src/modules/messages/schemas/base.ts import { z as z2 } from "zod"; var BaseMessageOptionsSchema = z2.object({ /** * Number (with country code) or JID to receive the message */ number: ApiNumberSchema, /** * Time in milliseconds before sending message */ delay: z2.number().optional() }); // src/modules/messages/schemas/audio.ts var AudioMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Audio URL or file in base64 */ audio: mediaSchema, /** * Audio mimetype */ mimetype: z3.string().optional() }); var AudioMessageBodySchema = AudioMessageOptionsSchema.transform( ({ audio, ...data }) => ({ ...data, media: audio, mediatype: "audio" }) ); var AudioMessageResponseSchema = z3.object({ key: z3.object({ remoteJid: z3.string(), id: z3.string() }), message: z3.object({ audioMessage: z3.object({ url: z3.string().url(), mimetype: z3.string().optional(), fileSha256: z3.string().base64(), fileLength: z3.coerce.number(), seconds: z3.number(), mediaKey: z3.string().base64(), fileEncSha256: z3.string().base64(), directPath: z3.string(), mediaKeyTimestamp: z3.coerce.number().transform((value) => new Date(value)) }) }), messageTimestamp: z3.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, media: { url: data.message.audioMessage.url, mimetype: data.message.audioMessage.mimetype, length: data.message.audioMessage.fileLength, durationInSeconds: data.message.audioMessage.seconds, sha256: data.message.audioMessage.fileSha256, encryptedSha256: data.message.audioMessage.fileEncSha256, directPath: data.message.audioMessage.directPath, key: data.message.audioMessage.mediaKey, keyTimestamp: data.message.audioMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/contact.ts import { parsePhoneNumber as parsePhoneNumber3 } from "libphonenumber-js"; import { z as z4 } from "zod"; var ContactMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Contact list */ contacts: z4.array( z4.object({ /** * Contact display name */ fullName: z4.string(), /** * Contact phone number */ phoneNumber: PhoneNumberSchema, /** * Contact organization */ organization: z4.string().optional(), /** * Contact email */ email: z4.string().email().optional(), /** * Contact website url */ url: z4.string().url().optional() }) ) }); var ContactMessageBodySchema = ContactMessageOptionsSchema.transform( ({ contacts, ...data }) => ({ ...data, contact: contacts.map((contact) => ({ ...contact, phoneNumber: parsePhoneNumber3(contact.phoneNumber).formatInternational(), wuid: contact.phoneNumber.replace(/\D/g, "") })) }) ); var ContactMessageResponseSchema = z4.object({ key: z4.object({ remoteJid: z4.string(), id: z4.string() }), message: z4.union([ z4.object({ contactMessage: z4.object({ displayName: z4.string(), vcard: z4.string() }) }), z4.object({ contactsArrayMessage: z4.object({ contacts: z4.array( z4.object({ displayName: z4.string(), vcard: z4.string() }) ) }) }) ]), messageTimestamp: z4.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, contacts: "contactMessage" in data.message ? [data.message.contactMessage] : data.message.contactsArrayMessage.contacts, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/document.ts import { z as z5 } from "zod"; var DocumentMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Document URL or file in base64 */ document: mediaSchema, /** * Caption to send with document */ caption: z5.string().optional(), /** * Document mimetype */ mimetype: z5.string().optional(), /** * Name of the file */ fileName: z5.string().optional() }).refine( (data) => URL.canParse(data.document) ? true : Boolean(data.fileName), { message: "fileName must be provided when document is not an URL", path: ["fileName"] } ); var DocumentMessageBodySchema = DocumentMessageOptionsSchema.transform( ({ document, ...data }) => ({ ...data, media: document, mediatype: "document" }) ); var DocumentMessageResponseSchema = z5.object({ key: z5.object({ remoteJid: z5.string(), id: z5.string() }), message: z5.object({ documentMessage: z5.object({ url: z5.string().url(), mimetype: z5.string().optional(), fileSha256: z5.string().base64(), fileLength: z5.coerce.number(), mediaKey: z5.string().base64(), caption: z5.string().optional(), fileName: z5.string(), fileEncSha256: z5.string().base64(), directPath: z5.string(), mediaKeyTimestamp: z5.coerce.number().transform((value) => new Date(value)) }) }), messageTimestamp: z5.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, media: { url: data.message.documentMessage.url, caption: data.message.documentMessage.caption, mimetype: data.message.documentMessage.mimetype, length: data.message.documentMessage.fileLength, sha256: data.message.documentMessage.fileSha256, fileName: data.message.documentMessage.fileName, encryptedSha256: data.message.documentMessage.fileEncSha256, directPath: data.message.documentMessage.directPath, key: data.message.documentMessage.mediaKey, keyTimestamp: data.message.documentMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/image.ts import { z as z6 } from "zod"; var ImageMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Image URL or file in base64 */ image: mediaSchema, /** * Caption to send with image */ caption: z6.string().optional(), /** * Image mimetype */ mimetype: z6.string().optional() }); var ImageMessageBodySchema = ImageMessageOptionsSchema.transform( ({ image, ...data }) => ({ ...data, media: image, mediatype: "image" }) ); var ImageMessageResponseSchema = z6.object({ key: z6.object({ remoteJid: z6.string(), id: z6.string() }), message: z6.object({ imageMessage: z6.object({ url: z6.string().url(), mimetype: z6.string().optional(), fileSha256: z6.string().base64(), fileLength: z6.coerce.number(), height: z6.number(), width: z6.number(), mediaKey: z6.string().base64(), caption: z6.string().optional(), fileEncSha256: z6.string().base64(), directPath: z6.string(), mediaKeyTimestamp: z6.coerce.number().transform((value) => new Date(value)) }) }), messageTimestamp: z6.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, media: { url: data.message.imageMessage.url, caption: data.message.imageMessage.caption, mimetype: data.message.imageMessage.mimetype, length: data.message.imageMessage.fileLength, height: data.message.imageMessage.height, width: data.message.imageMessage.width, sha256: data.message.imageMessage.fileSha256, encryptedSha256: data.message.imageMessage.fileEncSha256, directPath: data.message.imageMessage.directPath, key: data.message.imageMessage.mediaKey, keyTimestamp: data.message.imageMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/location.ts import { z as z7 } from "zod"; var LocationMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Location name */ name: z7.string(), /** * Location address */ address: z7.string(), /** * Location latitude */ latitude: z7.number(), /** * Location longitude */ longitude: z7.number() }); var LocationMessageBodySchema = LocationMessageOptionsSchema; var LocationMessageResponseSchema = z7.object({ key: z7.object({ remoteJid: z7.string(), id: z7.string() }), message: z7.object({ locationMessage: z7.object({ degreesLatitude: z7.number(), degreesLongitude: z7.number(), name: z7.string(), address: z7.string() }) }), messageTimestamp: z7.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, location: { latitude: data.message.locationMessage.degreesLatitude, longitude: data.message.locationMessage.degreesLongitude, name: data.message.locationMessage.name, address: data.message.locationMessage.address }, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/sticker.ts import { z as z8 } from "zod"; var StickerMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Image URL or file in base64 */ sticker: mediaSchema }); var StickerMessageBodySchema = StickerMessageOptionsSchema; var StickerMessageResponseSchema = z8.object({ key: z8.object({ remoteJid: z8.string(), id: z8.string() }), message: z8.object({ stickerMessage: z8.object({ url: z8.string().url(), fileSha256: z8.string().base64(), fileEncSha256: z8.string().base64(), mediaKey: z8.string().base64(), mimetype: z8.string().optional(), directPath: z8.string(), fileLength: z8.coerce.number(), mediaKeyTimestamp: z8.coerce.number().transform((value) => new Date(value)) }) }), messageTimestamp: z8.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, media: { url: data.message.stickerMessage.url, mimetype: data.message.stickerMessage.mimetype, length: data.message.stickerMessage.fileLength, sha256: data.message.stickerMessage.fileSha256, encryptedSha256: data.message.stickerMessage.fileEncSha256, directPath: data.message.stickerMessage.directPath, key: data.message.stickerMessage.mediaKey, keyTimestamp: data.message.stickerMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/text.ts import { z as z9 } from "zod"; var TextMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Message text content */ text: z9.string(), /** * Whether link preview should be shown */ linkPreview: z9.boolean().optional() }); var TextMessageBodySchema = TextMessageOptionsSchema; var TextMessageResponseSchema = z9.object({ key: z9.object({ remoteJid: z9.string(), id: z9.string() }), messageTimestamp: z9.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, messageId: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/video.ts import { z as z10 } from "zod"; var VideoMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Video URL or file in base64 */ video: mediaSchema, /** * Caption to send with video */ caption: z10.string().optional(), /** * Video mimetype */ mimetype: z10.string().optional() }); var VideoMessageBodySchema = VideoMessageOptionsSchema.transform( ({ video, ...data }) => ({ ...data, media: video, mediatype: "video" }) ); var VideoMessageResponseSchema = z10.object({ key: z10.object({ remoteJid: z10.string(), id: z10.string() }), message: z10.object({ videoMessage: z10.object({ url: z10.string().url(), mimetype: z10.string().optional(), fileSha256: z10.string().base64(), fileLength: z10.coerce.number(), mediaKey: z10.string().base64(), caption: z10.string().optional(), gifPlayback: z10.boolean(), fileEncSha256: z10.string().base64(), directPath: z10.string(), mediaKeyTimestamp: z10.coerce.number().transform((value) => new Date(value)) }) }), messageTimestamp: z10.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, media: { url: data.message.videoMessage.url, caption: data.message.videoMessage.caption, mimetype: data.message.videoMessage.mimetype, gifPlayback: data.message.videoMessage.gifPlayback, length: data.message.videoMessage.fileLength, sha256: data.message.videoMessage.fileSha256, encryptedSha256: data.message.videoMessage.fileEncSha256, directPath: data.message.videoMessage.directPath, key: data.message.videoMessage.mediaKey, keyTimestamp: data.message.videoMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/schemas/voice.ts import { z as z11 } from "zod"; var VoiceMessageOptionsSchema = BaseMessageOptionsSchema.extend({ /** * Audio URL or file in base64 */ audio: mediaSchema, /** * Encode audio into WhatsApp default format (allows audio to be sped up) * @default true */ encoding: z11.boolean().optional().default(true) }); var VoiceMessageBodySchema = VoiceMessageOptionsSchema; var VoiceMessageResponseSchema = z11.object({ key: z11.object({ remoteJid: z11.string(), id: z11.string() }), message: z11.object({ audioMessage: z11.object({ url: z11.string().url(), mimetype: z11.string(), fileSha256: z11.string().base64(), fileLength: z11.coerce.number(), seconds: z11.number(), ptt: z11.boolean().optional(), mediaKey: z11.string().base64(), fileEncSha256: z11.string().base64(), directPath: z11.string(), mediaKeyTimestamp: z11.coerce.number().transform((value) => new Date(value)), waveform: z11.string().base64().nullish() }) }), messageTimestamp: z11.coerce.date() }).transform((data) => ({ receiver: { phoneNumber: phoneNumberFromJid(data.key.remoteJid), jid: Jid(data.key.remoteJid) }, media: { url: data.message.audioMessage.url, mimetype: data.message.audioMessage.mimetype, length: data.message.audioMessage.fileLength, durationInSeconds: data.message.audioMessage.seconds, sha256: data.message.audioMessage.fileSha256, encryptedSha256: data.message.audioMessage.fileEncSha256, directPath: data.message.audioMessage.directPath, /** * Indicates whether the audio message is a push-to-talk (PTT) message */ isPtt: data.message.audioMessage.ptt, key: data.message.audioMessage.mediaKey, keyTimestamp: data.message.audioMessage.mediaKeyTimestamp, waveform: data.message.audioMessage.waveform }, messageId: MessageId(data.key.id), timestamp: data.messageTimestamp })); // src/modules/messages/index.ts var MessagesModule = class { constructor(api) { this.api = api; } /** * Sends a text message * @param options - Text message options */ async sendText(options) { const body = TextMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendText, { body }); return TextMessageResponseSchema.parse(response); } /** * Sends an image * @param options - Image message options */ async sendImage(options) { const body = ImageMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return ImageMessageResponseSchema.parse(response); } /** * Sends a video * @param options - Video message options */ async sendVideo(options) { const body = VideoMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return VideoMessageResponseSchema.parse(response); } /** * Sends a document * @param options - Document message options */ async sendDocument(options) { const body = DocumentMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return DocumentMessageResponseSchema.parse(response); } /** * Sends an audio * @param options - Audio message options */ async sendAudio(options) { const body = AudioMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return AudioMessageResponseSchema.parse(response); } /** * Sends a voice message * @param options - Voice message options */ async sendVoice(options) { const body = VoiceMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendVoice, { body }); return VoiceMessageResponseSchema.parse(response); } /** * Sends a sticker * @param options - Sticker message options */ async sendSticker(options) { const body = StickerMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendSticker, { body }); return StickerMessageResponseSchema.parse(response); } /** * Sends a location * @param options - Location message options */ async sendLocation(options) { const body = LocationMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendLocation, { body }); return LocationMessageResponseSchema.parse(response); } /** * Sends a contact * @param options - Contact message options */ async sendContact(options) { const body = ContactMessageBodySchema.parse(options); const response = await this.api.post(Routes.Message.SendContact, { body }); return ContactMessageResponseSchema.parse(response); } }; export { MessagesModule }; //# sourceMappingURL=index.mjs.map