UNPKG

@solufy/evolution-sdk

Version:

Unofficial SDK for the Evolution Whatsapp API v2

1,222 lines (1,183 loc) 34.8 kB
import * as z from "zod/mini"; import { isValidPhoneNumber, parsePhoneNumberFromString, parsePhoneNumberWithError } from "libphonenumber-js/min"; //#region src/api/errors.ts var EvolutionApiError = class EvolutionApiError extends Error { code; instance; constructor(message, options) { const error = getError(options?.cause); super(message, error ? void 0 : { cause: options?.cause }); this.name = EvolutionApiError.name; this.message = error?.message ?? message; this.code = error?.code ?? options?.code; this.instance = options?.instance; } }; const Errors = [ defineError(z.literal("Unauthorized"), "unauthorized", "Unauthorized"), defineError(z.array(z.object({ exists: z.literal(false), jid: z.string(), number: z.string() })), "invalid_whatsapp_number", "Provided number is not a valid WhatsApp number"), defineError(z.array(z.string().check(z.includes("Media upload failed on all hosts"))), "media_upload_failed", "Media upload failed on all hosts"), defineError(z.array(z.string().check(z.includes("AxiosError"))), "generic", (r) => r.message[0]), defineError(z.array(z.string().check(z.includes("No session"))), "no_session_found", "No session found, try restarting your instance"), defineError(z.array(z.string().check(z.includes("AggregateError"))), "aggregate_error", "AggregateError"), defineError(z.array(z.string().check(z.includes("instance does not exist"))), "instance_not_found", "Instance not found") ]; function getError(response) { const error = Errors.find((message) => message.schema.safeParse(response).success); return error ? { code: error.code, message: typeof error.message === "string" ? error.message : error.message(response) } : void 0; } function defineError(schema, code, message) { return { schema: z.object({ message: schema }), code, message }; } //#endregion //#region src/api/index.ts var EvolutionApi = class { constructor(options) { this.options = options; } async get(path, options = {}) { return this.request(path, { ...options, method: "GET" }); } async post(path, options = {}) { return this.request(path, { ...options, method: "POST" }); } async put(path, options = {}) { return this.request(path, { ...options, method: "PUT" }); } async patch(path, options = {}) { return this.request(path, { ...options, method: "PATCH" }); } async delete(path, options = {}) { return this.request(path, { ...options, method: "DELETE" }); } async request(path, options = {}) { const { init, params } = this.makeInit(options); const url = new URL(`/${path}/?${params}`, this.options.serverUrl); const response = await fetch(url, init); const data = await response.json(); if (!response.ok || "error" in data) throw new EvolutionApiError(data.error ?? "Unknown Error", { cause: data.response }); return data; } makeInit(options) { const { params: _, headers, body, ...rest } = options; const paramsInit = options.params && Object.entries(options.params).filter(([, value]) => Boolean(value)).map(([key, value]) => [key, String(value)]); const params = new URLSearchParams(paramsInit); const init = { ...rest, headers: { ...headers || {}, apikey: this.options.token } }; if (body) { init.headers["Content-Type"] = body instanceof FormData ? "multipart/form-data" : "application/json"; init.body = body instanceof FormData ? body : JSON.stringify(body); } return { init, params }; } }; //#endregion //#region src/api/routes.ts const 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" }, Instances: { Create: "instance/create", Find: "instance/fetchInstances", Connect: (instance) => `instance/connect/${instance}`, Restart: (instance) => `instance/restart/${instance}`, Presence: (instance) => `instance/setPresence/${instance}`, Status: (instance) => `instance/connectionState/${instance}`, Logout: (instance) => `instance/logout/${instance}`, Delete: (instance) => `instance/delete/${instance}` } }; //#endregion //#region src/modules/instances/schemas/connect.ts const ResponseSchema$18 = z.object({ pairingCode: z.nullish(z.string()), code: z.nullish(z.string()), base64: z.nullish(z.string()) }); const Response$18 = (response) => { const { pairingCode, code, base64 } = ResponseSchema$18.parse(response); return { pairingCode: pairingCode ?? void 0, code: code ?? void 0, base64: base64 ?? void 0 }; }; //#endregion //#region src/schemas/common.ts const PhoneNumberSchema = z.string().check(z.refine((value) => isValidPhoneNumber(value), "Invalid phone number"), z.overwrite((phoneNumber) => parsePhoneNumberFromString(phoneNumber)?.number)); const JidSchema = z.pipe(z.string().check(z.endsWith("@s.whatsapp.net", "Invalid remote JID, should end with @s.whatsapp.net")), z.custom()); const GroupJidSchema = z.pipe(z.string().check(z.endsWith("@g.us", "Invalid group JID, should end with @g.us")), z.custom()); const GroupInviteCodeSchema = z.pipe(z.string().check(z.length(22), z.regex(/^[a-zA-Z0-9]{22}$/, "Invalid group invite code")), z.custom()); const ApiNumberSchema = z.union([ PhoneNumberSchema, JidSchema, GroupJidSchema ]); const MediaSchema = z.union([z.url(), z.base64()]); //#endregion //#region src/modules/instances/schemas/common.ts const IntegrationMap = { baileys: "WHATSAPP-BAILEYS", business: "WHATSAPP-BUSINESS", evolution: "EVOLUTION", "WHATSAPP-BAILEYS": "baileys", "WHATSAPP-BUSINESS": "business", EVOLUTION: "evolution" }; const IntegrationSchema = { Raw: z.union([ z.literal("WHATSAPP-BAILEYS"), z.literal("WHATSAPP-BUSINESS"), z.literal("EVOLUTION") ]), Map: z.union([ z.literal("baileys"), z.literal("business"), z.literal("evolution") ]) }; const StatusSchema = z.union([ z.literal("connecting"), z.literal("close"), z.literal("open") ]); const InstanceSchema = z.object({ id: z.string(), name: z.string(), connectionStatus: StatusSchema, ownerJid: z.nullable(z.string()), profileName: z.nullable(z.string()), profilePicUrl: z.nullable(z.string()), integration: IntegrationSchema.Raw, number: z.nullable(z.string()), token: z.string(), businessId: z.nullable(z.string()), clientName: z.string(), disconnectionReasonCode: z.nullable(z.number()), disconnectionObject: z.nullable(z.string()), disconnectionAt: z.nullable(z.string()), createdAt: z.string(), updatedAt: z.string(), _count: z.object({ Message: z.number(), Contact: z.number(), Chat: z.number() }) }); const InstanceResponse = (instance) => ({ id: instance.id, name: instance.name, status: instance.connectionStatus, integration: IntegrationMap[instance.integration], number: instance.number ?? void 0, token: instance.token, businessId: instance.businessId ?? void 0, clientName: instance.clientName, createdAt: new Date(instance.createdAt), updatedAt: new Date(instance.updatedAt), profile: instance.ownerJid && instance.profileName ? { jid: instance.ownerJid, name: instance.profileName, pictureUrl: instance.profilePicUrl ?? void 0 } : void 0, disconnection: instance.disconnectionAt && instance.disconnectionObject && instance.disconnectionReasonCode ? { reasonCode: instance.disconnectionReasonCode, object: instance.disconnectionObject, at: new Date(instance.disconnectionAt) } : void 0, count: { messages: instance._count.Message, contacts: instance._count.Contact, chats: instance._count.Chat } }); //#endregion //#region src/modules/instances/schemas/create.ts const OptionsSchema$11 = z.object({ name: z.string(), integration: z.optional(IntegrationSchema.Map), token: z.optional(z.string()), number: z.optional(PhoneNumberSchema) }); const Body$11 = (options) => { const data = OptionsSchema$11.parse(options); return { instanceName: data.name, integration: IntegrationMap[data.integration ?? "baileys"], number: data.number, token: data.token }; }; const ResponseSchema$17 = z.object({ instance: z.object({ instanceName: z.string(), instanceId: z.string(), integration: IntegrationSchema.Raw, status: StatusSchema }), hash: z.string() }); const Response$17 = (response) => { const data = ResponseSchema$17.parse(response); const { instance } = data; return { id: instance.instanceId, name: instance.instanceName, integration: IntegrationMap[instance.integration], status: instance.status, token: data.hash }; }; //#endregion //#region src/modules/instances/schemas/find-all.ts const ResponseSchema$16 = z.array(InstanceSchema); const Response$16 = (response) => { return ResponseSchema$16.parse(response).map(InstanceResponse); }; //#endregion //#region src/modules/instances/schemas/find-one.ts const ResponseSchema$15 = z.array(InstanceSchema); const Response$15 = (response) => { return InstanceResponse(ResponseSchema$15.parse(response)[0]); }; //#endregion //#region src/modules/instances/schemas/status.ts const ResponseSchema$14 = z.object({ instance: z.object({ instanceName: z.string(), state: StatusSchema }) }); const Response$14 = (response) => { const { instance } = ResponseSchema$14.parse(response); return instance.state; }; //#endregion //#region src/modules/instances/index.ts var InstancesModule = class { constructor(api) { this.api = api; } /** * Creates an instance * @param options - Instance options */ async create(options) { const body = Body$11(options); const response = await this.api.post(Routes.Instances.Create, { body }); return Response$17(response); } /** * Finds all instances */ async findAll() { const response = await this.api.get(Routes.Instances.Find); return Response$16(response); } /** * Finds one instance by id */ async findById(id) { const response = await this.api.get(Routes.Instances.Find, { params: { instanceId: id } }); return Response$15(response); } /** * Finds one instance by name */ async findByName(name) { const response = await this.api.get(Routes.Instances.Find, { params: { instanceName: name } }); return Response$15(response); } /** * Returns the QRCode and/or pairing code */ async connect(instance) { const response = await this.api.get(Routes.Instances.Connect(instance)); return Response$18(response); } /** * Restarts the instance and returns the QRCode and/or pairing code */ async restart(instance) { const response = await this.api.post(Routes.Instances.Restart(instance)); return Response$18(response); } /** * Returns the instance connection status */ async status(instance) { const response = await this.api.get(Routes.Instances.Status(instance)); return Response$14(response); } /** * Logs out the instance */ async logout(instance) { await this.api.delete(Routes.Instances.Logout(instance)); } /** * Deletes the instance */ async delete(instance) { await this.api.delete(Routes.Instances.Delete(instance)); } }; //#endregion //#region src/schemas/client.ts const ClientOptionsSchema = z.object({ serverUrl: z.url(), token: z.string() }); //#endregion //#region src/api/instance.ts var InstanceApi = class extends EvolutionApi { constructor(instance, options) { super(options); this.instance = instance; this.options = options; } async request(path, options = {}) { const { init, params } = this.makeInit(options); const url = new URL(`/${path}/${this.instance}/?${params}`, this.options.serverUrl); const response = await fetch(url, init); const data = await response.json(); if (!response.ok || "error" in data) throw new EvolutionApiError(data.error || "Unknown Error", { cause: data.response, instance: this.instance }); return data; } }; //#endregion //#region src/types/tags.ts const Jid = (jid) => jid; const GroupJid = (jid) => jid; const MessageId = (id) => id; const ChatId = (id) => id; //#endregion //#region src/modules/chats/schemas/check.ts const OptionsSchema$10 = z.array(PhoneNumberSchema); const Body$10 = (options) => { const data = OptionsSchema$10.parse(options); return { numbers: Array.isArray(data) ? data : [data] }; }; const ResponseSchema$13 = z.array(z.object({ exists: z.boolean(), jid: z.string(), number: z.string() })); const Response$13 = (response) => { return ResponseSchema$13.parse(response).map((number) => ({ exists: number.exists, jid: Jid(number.jid), number: parsePhoneNumberWithError(number.number).number })); }; //#endregion //#region src/utils/phone-numer-from-jid.ts /** * Get phone number from JID * @param jid - JID (remote JID) */ function phoneNumberFromJid(jid) { return parsePhoneNumberWithError(`+${jid.split("@")[0]}`).number; } //#endregion //#region src/modules/chats/schemas/find-all.ts const ResponseSchema$12 = z.array(z.object({ id: z.string(), remoteJid: z.string(), name: z.nullish(z.string()), labels: z.nullish(z.array(z.string())), createdAt: z.coerce.date(), updatedAt: z.coerce.date(), pushName: z.nullish(z.string()), profilePicUrl: z.nullish(z.url()) })); const Response$12 = (response) => { return ResponseSchema$12.parse(response).map((chat) => ({ id: ChatId(chat.id), jid: chat.remoteJid.endsWith("@g.us") ? GroupJid(chat.remoteJid) : Jid(chat.remoteJid), phoneNumber: phoneNumberFromJid(chat.remoteJid), name: chat.name || void 0, labels: chat.labels || void 0, createdAt: chat.createdAt, updatedAt: chat.updatedAt, pushName: chat.pushName || void 0, pictureUrl: chat.profilePicUrl || void 0 })); }; //#endregion //#region src/modules/chats/schemas/presence.ts const OptionsSchema$9 = z.object({ number: ApiNumberSchema, duration: z.number(), presence: z.enum(["composing", "recording"]), waitUntilFinish: z.optional(z.boolean()) }); const Body$9 = (options) => { const { waitUntilFinish, duration, ...data } = OptionsSchema$9.parse(options); return { ...data, delay: duration }; }; //#endregion //#region src/modules/chats/index.ts var ChatsModule = class { constructor(api) { this.api = api; } /** * Checks if a number has WhatsApp * @param numbers - Number(s) (with country code) to check */ async check(...numbers) { const body = Body$10(numbers.flat()); const response = await this.api.post(Routes.Chats.Check, { body }); return Response$13(response); } /** * Gets all chats */ async findAll() { const response = await this.api.post(Routes.Chats.FindAll); return Response$12(response); } /** * Sends a presence to a certain chat * @param options - Presence options */ async sendPresence(options) { const body = Body$9(options); if (options.waitUntilFinish) await this.api.post(Routes.Chats.SendPresence, { body }); else this.api.post(Routes.Chats.SendPresence, { body }); } }; //#endregion //#region src/modules/groups/schemas/common.ts const GroupSchema = z.object({ id: z.string(), subject: z.string(), subjectOwner: z.string(), subjectTime: z.coerce.date(), pictureUrl: z.nullish(z.url()), size: z.number(), creation: z.coerce.date(), owner: z.string(), restrict: z.boolean(), announce: z.boolean() }); const ParticipantSchema = z.object({ id: z.string(), admin: z.nullish(z.enum(["admin", "superadmin"])) }); const GroupWithParticipantsSchema = z.extend(GroupSchema, { participants: z.array(ParticipantSchema) }); const GroupResponse = (group) => ({ jid: GroupJid(group.id), name: group.subject, pictureUrl: group.pictureUrl || void 0, size: group.size, subject: { owner: Jid(group.subjectOwner), time: group.subjectTime }, owner: { jid: Jid(group.owner), phoneNumber: phoneNumberFromJid(group.owner) }, createdAt: group.creation, restrict: group.restrict, announce: group.announce }); const ParticipantResponse = (participant) => ({ id: participant.id, role: participant.admin ?? "member" }); const GroupWithParticipantsResponse = (group) => ({ ...GroupResponse(group), participants: group.participants.map(ParticipantResponse) }); //#endregion //#region src/modules/groups/schemas/find-all.ts const ResponseSchema$11 = z.array(GroupSchema); const ResponseWithParticipantsSchema = z.array(GroupWithParticipantsSchema); const Response$11 = (response) => { return ResponseSchema$11.parse(response).map(GroupResponse); }; const ResponseWithParticipants = (response) => { return ResponseWithParticipantsSchema.parse(response).map(GroupWithParticipantsResponse); }; //#endregion //#region src/modules/groups/schemas/find-by-invite-code.ts const ResponseSchema$10 = z.omit(z.extend(GroupWithParticipantsSchema, { isCommunity: z.boolean(), isCommunityAnnounce: z.boolean(), joinApprovalMode: z.boolean(), memberAddMode: z.boolean() }), { pictureUrl: true }); const Response$10 = (response) => { const data = ResponseSchema$10.parse(response); return { ...GroupWithParticipantsResponse({ ...data, pictureUrl: null }), isCommunity: data.isCommunity, isCommunityAnnounce: data.isCommunityAnnounce, joinApprovalMode: data.joinApprovalMode, memberAddMode: data.memberAddMode }; }; //#endregion //#region src/modules/groups/schemas/find-by-jid.ts const ResponseSchema$9 = GroupWithParticipantsSchema; const Response$9 = (response) => { return GroupWithParticipantsResponse(ResponseSchema$9.parse(response)); }; //#endregion //#region src/modules/groups/index.ts var GroupsModule = class { constructor(api) { this.api = api; } async findAll(participants = false) { const response = await this.api.get(Routes.Groups.FindAll, { params: { getParticipants: z.boolean().parse(participants) } }); if (participants) return ResponseWithParticipants(response); return Response$11(response); } /** * Gets a group by invite code * @param inviteCode - The group invite code (not the URL) */ async findByInviteCode(inviteCode) { const response = await this.api.get(Routes.Groups.FindByInviteCode, { params: { inviteCode: GroupInviteCodeSchema.parse(inviteCode) } }); return Response$10(response); } /** * Gets a group by JID * @param groupJid - The group JID terminated with \@g.us */ async findByJid(groupJid) { const response = await this.api.get(Routes.Groups.FindByJid, { params: { groupJid: GroupJidSchema.parse(groupJid) } }); return Response$9(response); } }; //#endregion //#region src/modules/messages/schemas/base.ts const BaseMessageOptionsSchema = z.object({ number: ApiNumberSchema, delay: z.optional(z.number()) }); const KeyResponseSchema = z.object({ remoteJid: z.string(), id: z.string() }); const ReceiverResponse = (remoteJid) => { return { phoneNumber: phoneNumberFromJid(remoteJid), jid: Jid(remoteJid) }; }; //#endregion //#region src/modules/messages/schemas/audio.ts const OptionsSchema$8 = z.extend(BaseMessageOptionsSchema, { audio: MediaSchema, mimetype: z.optional(z.string()) }); const Body$8 = (options) => { const { audio, ...data } = OptionsSchema$8.parse(options); return { ...data, media: audio, mediatype: "audio" }; }; const ResponseSchema$8 = z.object({ key: KeyResponseSchema, message: z.object({ audioMessage: z.object({ url: z.url(), mimetype: z.optional(z.string()), fileSha256: z.base64(), fileLength: z.coerce.number(), seconds: z.number(), mediaKey: z.base64(), fileEncSha256: z.base64(), directPath: z.string(), mediaKeyTimestamp: z.coerce.date() }) }), messageTimestamp: z.coerce.date() }); const Response$8 = (response) => { const data = ResponseSchema$8.parse(response); const { audioMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), media: { url: audioMessage.url, mimetype: audioMessage.mimetype, length: audioMessage.fileLength, durationInSeconds: audioMessage.seconds, sha256: audioMessage.fileSha256, encryptedSha256: audioMessage.fileEncSha256, directPath: audioMessage.directPath, key: audioMessage.mediaKey, keyTimestamp: audioMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/contact.ts const OptionsSchema$7 = z.extend(BaseMessageOptionsSchema, { contacts: z.array(z.object({ fullName: z.string(), phoneNumber: PhoneNumberSchema, organization: z.optional(z.string()), email: z.optional(z.email()), url: z.optional(z.url()) })) }); const Body$7 = (options) => { const { contacts, ...data } = OptionsSchema$7.parse(options); return { ...data, contact: contacts.map((contact) => ({ ...contact, phoneNumber: parsePhoneNumberWithError(contact.phoneNumber).formatInternational(), wuid: contact.phoneNumber.replace(/\D/g, "") })) }; }; const ResponseSchema$7 = z.object({ key: KeyResponseSchema, message: z.union([z.object({ contactMessage: z.object({ displayName: z.string(), vcard: z.string() }) }), z.object({ contactsArrayMessage: z.object({ contacts: z.array(z.object({ displayName: z.string(), vcard: z.string() })) }) })]), messageTimestamp: z.coerce.date() }); const Response$7 = (response) => { const data = ResponseSchema$7.parse(response); return { receiver: ReceiverResponse(data.key.remoteJid), contacts: "contactMessage" in data.message ? [data.message.contactMessage] : data.message.contactsArrayMessage.contacts, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/utils/greeting.ts function getGreeting(date = /* @__PURE__ */ new Date(), timeZone = "America/Sao_Paulo") { const hours = new Date(date.toLocaleString("en-US", { timeZone })).getHours(); if (hours >= 5 && hours < 12) return "Bom dia"; if (hours >= 12 && hours < 18) return "Boa tarde"; return "Boa noite"; } function replaceWithGreeting(value) { return value?.replaceAll("{{greeting}}", getGreeting()); } //#endregion //#region src/modules/messages/schemas/document.ts const OptionsSchema$6 = z.extend(BaseMessageOptionsSchema, { document: MediaSchema, caption: z.optional(z.string().check(z.overwrite(replaceWithGreeting))), mimetype: z.optional(z.string()), fileName: z.optional(z.string()) }).check(z.refine((data) => URL.canParse(data.document) ? true : Boolean(data.fileName), { message: "fileName must be provided when document is not an URL", path: ["fileName"] })); const Body$6 = (options) => { const { document, ...data } = OptionsSchema$6.parse(options); return { ...data, media: document, mediatype: "document" }; }; const ResponseSchema$6 = z.object({ key: KeyResponseSchema, message: z.object({ documentMessage: z.object({ url: z.url(), mimetype: z.optional(z.string()), fileSha256: z.base64(), fileLength: z.coerce.number(), mediaKey: z.base64(), caption: z.optional(z.string()), fileName: z.string(), fileEncSha256: z.base64(), directPath: z.string(), mediaKeyTimestamp: z.coerce.date() }) }), messageTimestamp: z.coerce.date() }); const Response$6 = (response) => { const data = ResponseSchema$6.parse(response); const { documentMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), media: { url: documentMessage.url, caption: documentMessage.caption, mimetype: documentMessage.mimetype, length: documentMessage.fileLength, sha256: documentMessage.fileSha256, fileName: documentMessage.fileName, encryptedSha256: documentMessage.fileEncSha256, directPath: documentMessage.directPath, key: documentMessage.mediaKey, keyTimestamp: documentMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/image.ts const OptionsSchema$5 = z.extend(BaseMessageOptionsSchema, { image: MediaSchema, caption: z.optional(z.string()).check(z.overwrite(replaceWithGreeting)), mimetype: z.optional(z.string()) }); const Body$5 = (options) => { const { image, ...data } = OptionsSchema$5.parse(options); return { ...data, media: image, mediatype: "image" }; }; const ResponseSchema$5 = z.object({ key: KeyResponseSchema, message: z.object({ imageMessage: z.object({ url: z.url(), mimetype: z.optional(z.string()), fileSha256: z.base64(), fileLength: z.coerce.number(), height: z.number(), width: z.number(), mediaKey: z.base64(), caption: z.optional(z.string()), fileEncSha256: z.base64(), directPath: z.string(), mediaKeyTimestamp: z.coerce.date() }) }), messageTimestamp: z.coerce.date() }); const Response$5 = (response) => { const data = ResponseSchema$5.parse(response); const { imageMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), media: { url: imageMessage.url, caption: imageMessage.caption, mimetype: imageMessage.mimetype, length: imageMessage.fileLength, height: imageMessage.height, width: imageMessage.width, sha256: imageMessage.fileSha256, encryptedSha256: imageMessage.fileEncSha256, directPath: imageMessage.directPath, key: imageMessage.mediaKey, keyTimestamp: imageMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/location.ts const OptionsSchema$4 = z.extend(BaseMessageOptionsSchema, { name: z.string(), address: z.string(), latitude: z.number(), longitude: z.number() }); const Body$4 = (options) => { return OptionsSchema$4.parse(options); }; const ResponseSchema$4 = z.object({ key: KeyResponseSchema, message: z.object({ locationMessage: z.object({ degreesLatitude: z.number(), degreesLongitude: z.number(), name: z.string(), address: z.string() }) }), messageTimestamp: z.coerce.date() }); const Response$4 = (response) => { const data = ResponseSchema$4.parse(response); const { locationMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), location: { latitude: locationMessage.degreesLatitude, longitude: locationMessage.degreesLongitude, name: locationMessage.name, address: locationMessage.address }, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/sticker.ts const OptionsSchema$3 = z.extend(BaseMessageOptionsSchema, { sticker: MediaSchema }); const Body$3 = (options) => { return OptionsSchema$3.parse(options); }; const ResponseSchema$3 = z.object({ key: KeyResponseSchema, message: z.object({ stickerMessage: z.object({ url: z.url(), fileSha256: z.base64(), fileEncSha256: z.base64(), mediaKey: z.base64(), mimetype: z.optional(z.string()), directPath: z.string(), fileLength: z.coerce.number(), mediaKeyTimestamp: z.coerce.date() }) }), messageTimestamp: z.coerce.date() }); const Response$3 = (response) => { const data = ResponseSchema$3.parse(response); const { stickerMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), media: { url: stickerMessage.url, mimetype: stickerMessage.mimetype, length: stickerMessage.fileLength, sha256: stickerMessage.fileSha256, encryptedSha256: stickerMessage.fileEncSha256, directPath: stickerMessage.directPath, key: stickerMessage.mediaKey, keyTimestamp: stickerMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/text.ts const OptionsSchema$2 = z.extend(BaseMessageOptionsSchema, { text: z.string().check(z.overwrite(replaceWithGreeting)), linkPreview: z.optional(z.boolean()) }); const Body$2 = (options) => { return OptionsSchema$2.parse(options); }; const ResponseSchema$2 = z.object({ key: KeyResponseSchema, messageTimestamp: z.coerce.date() }); const Response$2 = (response) => { const data = ResponseSchema$2.parse(response); return { receiver: ReceiverResponse(data.key.remoteJid), messageId: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/video.ts const OptionsSchema$1 = z.extend(BaseMessageOptionsSchema, { video: MediaSchema, caption: z.optional(z.string()).check(z.overwrite(replaceWithGreeting)), mimetype: z.optional(z.string()) }); const Body$1 = (options) => { const { video, ...data } = OptionsSchema$1.parse(options); return { ...data, media: video, mediatype: "video" }; }; const ResponseSchema$1 = z.object({ key: KeyResponseSchema, message: z.object({ videoMessage: z.object({ url: z.url(), mimetype: z.optional(z.string()), fileSha256: z.base64(), fileLength: z.coerce.number(), mediaKey: z.base64(), caption: z.optional(z.string()), gifPlayback: z.boolean(), fileEncSha256: z.base64(), directPath: z.string(), mediaKeyTimestamp: z.coerce.date() }) }), messageTimestamp: z.coerce.date() }); const Response$1 = (response) => { const data = ResponseSchema$1.parse(response); const { videoMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), media: { url: videoMessage.url, caption: videoMessage.caption, mimetype: videoMessage.mimetype, gifPlayback: videoMessage.gifPlayback, length: videoMessage.fileLength, sha256: videoMessage.fileSha256, encryptedSha256: videoMessage.fileEncSha256, directPath: videoMessage.directPath, key: videoMessage.mediaKey, keyTimestamp: videoMessage.mediaKeyTimestamp }, id: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region src/modules/messages/schemas/voice.ts const OptionsSchema = z.extend(BaseMessageOptionsSchema, { audio: MediaSchema, encoding: z._default(z.optional(z.boolean()), true) }); const Body = (options) => { return OptionsSchema.parse(options); }; const ResponseSchema = z.object({ key: KeyResponseSchema, message: z.object({ audioMessage: z.object({ url: z.url(), mimetype: z.string(), fileSha256: z.base64(), fileLength: z.coerce.number(), seconds: z.number(), ptt: z.optional(z.boolean()), mediaKey: z.base64(), fileEncSha256: z.base64(), directPath: z.string(), mediaKeyTimestamp: z.coerce.date(), waveform: z.nullish(z.base64()) }) }), messageTimestamp: z.coerce.date() }); const Response = (response) => { const data = ResponseSchema.parse(response); const { audioMessage } = data.message; return { receiver: ReceiverResponse(data.key.remoteJid), media: { url: audioMessage.url, mimetype: audioMessage.mimetype, length: audioMessage.fileLength, durationInSeconds: audioMessage.seconds, sha256: audioMessage.fileSha256, encryptedSha256: audioMessage.fileEncSha256, directPath: audioMessage.directPath, isPtt: audioMessage.ptt, key: audioMessage.mediaKey, keyTimestamp: audioMessage.mediaKeyTimestamp, waveform: audioMessage.waveform }, messageId: MessageId(data.key.id), timestamp: data.messageTimestamp }; }; //#endregion //#region 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 = Body$2(options); const response = await this.api.post(Routes.Message.SendText, { body }); return Response$2(response); } /** * Sends an image * @param options - Image message options */ async sendImage(options) { const body = Body$5(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return Response$5(response); } /** * Sends a video * @param options - Video message options */ async sendVideo(options) { const body = Body$1(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return Response$1(response); } /** * Sends a document * @param options - Document message options */ async sendDocument(options) { const body = Body$6(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return Response$6(response); } /** * Sends an audio * @param options - Audio message options */ async sendAudio(options) { const body = Body$8(options); const response = await this.api.post(Routes.Message.SendMedia, { body }); return Response$8(response); } /** * Sends a voice message * @param options - Voice message options */ async sendVoice(options) { const body = Body(options); const response = await this.api.post(Routes.Message.SendVoice, { body }); return Response(response); } /** * Sends a sticker * @param options - Sticker message options */ async sendSticker(options) { const body = Body$3(options); const response = await this.api.post(Routes.Message.SendSticker, { body }); return Response$3(response); } /** * Sends a location * @param options - Location message options */ async sendLocation(options) { const body = Body$4(options); const response = await this.api.post(Routes.Message.SendLocation, { body }); return Response$4(response); } /** * Sends a contact * @param options - Contact message options */ async sendContact(options) { const body = Body$7(options); const response = await this.api.post(Routes.Message.SendContact, { body }); return Response$7(response); } }; //#endregion //#region src/instance.ts var EvolutionInstance = class { /** * API service for directly interacting with the Evolution API */ api; /** * Find and manage chats, send presences and check numbers */ chats; /** * Find and manage groups */ groups; /** * Send messages */ messages; /** * Evolution Instance - API client for interacting with the Evolution API for instance routes * @param instance - Instance name * @param options - Client options */ constructor(instance, options) { this.instance = instance; this.options = options; z.string().parse(instance); ClientOptionsSchema.parse(options); this.api = new InstanceApi(instance, options); this.chats = new ChatsModule(this.api); this.groups = new GroupsModule(this.api); this.messages = new MessagesModule(this.api); } }; //#endregion //#region src/index.ts var EvolutionClient = class { /** * API service for directly interacting with the Evolution API (no specific typings) */ api; /** * Find and manage instances */ instances; /** * Evolution Client - API client for interacting with the Evolution API * @param options - Client options */ constructor(options) { this.options = options; ClientOptionsSchema.parse(options); this.api = new EvolutionApi(options); this.instances = new InstancesModule(this.api); } }; //#endregion export { ChatId, EvolutionApiError, EvolutionClient, EvolutionInstance, GroupJid, Jid, MessageId, phoneNumberFromJid };