@akson/chatsuite-sdk
Version:
Production-ready TypeScript SDK for ChatSuite - WhatsApp automation with built-in session management, message queuing, webhook server, and database sync
1,819 lines (1,808 loc) • 126 kB
JavaScript
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
// src/client/BaseClient.ts
import axios from "axios";
var BaseClient = class {
constructor(options) {
this.apiToken = options.apiToken;
this.baseUrl = options.baseUrl || "https://api.chatsuite.com";
this.axiosInstance = axios.create({
baseURL: this.baseUrl,
timeout: options.timeout || 3e4,
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${this.apiToken}`,
...options.headers
}
});
this.axiosInstance.interceptors.request.use(
(config) => {
if (!config.headers.Authorization) {
config.headers.Authorization = `Bearer ${this.apiToken}`;
}
return config;
},
(error) => Promise.reject(error)
);
this.axiosInstance.interceptors.response.use(
(response) => response,
async (error) => {
return Promise.reject(this.handleError(error));
}
);
if (options.retryConfig) {
this.setupRetryInterceptor(options.retryConfig);
}
}
setupRetryInterceptor(retryConfig) {
this.axiosInstance.interceptors.response.use(
void 0,
async (error) => {
const config = error.config;
if (!config || !retryConfig) {
return Promise.reject(error);
}
config._retry = config._retry || 0;
if (config._retry >= (retryConfig.retries || 3) || retryConfig.retryCondition && !retryConfig.retryCondition(error)) {
return Promise.reject(error);
}
config._retry += 1;
const retryCount = config._retry || 1;
await new Promise(
(resolve) => setTimeout(resolve, retryConfig.retryDelay || 1e3 * retryCount)
);
return this.axiosInstance(config);
}
);
}
handleError(error) {
const apiError = new Error();
if (error.response) {
const responseData = error.response.data;
apiError.message = responseData?.error || responseData?.message || error.message;
apiError.status = error.response.status;
apiError.code = responseData?.code;
apiError.details = responseData;
} else if (error.request) {
apiError.message = "No response from server";
apiError.code = "NETWORK_ERROR";
} else {
apiError.message = error.message;
apiError.code = "REQUEST_ERROR";
}
apiError.name = "WhatsAppApiError";
return apiError;
}
async get(path, config) {
const response = await this.axiosInstance.get(path, config);
return response.data;
}
async post(path, data, config) {
const response = await this.axiosInstance.post(path, data, config);
return response.data;
}
async put(path, data, config) {
const response = await this.axiosInstance.put(path, data, config);
return response.data;
}
async delete(path, config) {
const response = await this.axiosInstance.delete(path, config);
return response.data;
}
async patch(path, data, config) {
const response = await this.axiosInstance.patch(path, data, config);
return response.data;
}
/**
* Update the API token
*/
setApiToken(token) {
this.apiToken = token;
this.axiosInstance.defaults.headers.common["Authorization"] = `Bearer ${token}`;
}
/**
* Get the current base URL
*/
getBaseUrl() {
return this.baseUrl;
}
};
// src/resources/Sessions.ts
var Sessions = class {
constructor(client) {
this.client = client;
}
/**
* List all sessions
* @param environment - Filter by environment (optional)
*/
async list(environment) {
const params = environment ? { environment } : void 0;
const response = await this.client["get"]("/api/sessions", { params });
return {
sessions: response.sessions,
count: response.count
};
}
/**
* Get session details
* @param tel - Phone number
*/
async get(tel) {
const response = await this.client["get"](`/api/sessions/${encodeURIComponent(tel)}`);
return response.session;
}
/**
* Create a new session
* @param data - Session creation data
*/
async create(data) {
const response = await this.client["post"]("/api/sessions", data);
return response.session;
}
/**
* Update session details
* @param tel - Phone number
* @param data - Update data
*/
async update(tel, data) {
const response = await this.client["put"](`/api/sessions/${encodeURIComponent(tel)}`, data);
return response.session;
}
/**
* Initialize session (start connection and generate QR code)
* @param tel - Phone number
*/
async initialize(tel) {
const response = await this.client["post"](`/api/sessions/${encodeURIComponent(tel)}/init`);
return { message: response.message || "Session initialization started" };
}
/**
* Reset session (disconnect and clear auth)
* @param tel - Phone number
*/
async reset(tel) {
const response = await this.client["post"](`/api/sessions/${encodeURIComponent(tel)}/reset`);
return { message: response.message || "Session reset successfully" };
}
/**
* Delete session permanently
* @param tel - Phone number
*/
async delete(tel) {
const response = await this.client["delete"](`/api/sessions/${encodeURIComponent(tel)}`);
return { message: response.message || "Session deleted successfully" };
}
/**
* Poll for session status (useful for checking QR code availability)
* @param tel - Phone number
* @param maxAttempts - Maximum polling attempts
* @param interval - Polling interval in milliseconds
*/
async pollForQR(tel, maxAttempts = 30, interval = 2e3) {
let attempts = 0;
while (attempts < maxAttempts) {
const session = await this.get(tel);
if (session.qr || session.ready) {
return session;
}
attempts++;
if (attempts < maxAttempts) {
await new Promise((resolve) => setTimeout(resolve, interval));
}
}
throw new Error("Timeout waiting for QR code");
}
/**
* Wait for session to be ready (connected)
* @param tel - Phone number
* @param maxAttempts - Maximum polling attempts
* @param interval - Polling interval in milliseconds
*/
async waitForReady(tel, maxAttempts = 60, interval = 2e3) {
let attempts = 0;
while (attempts < maxAttempts) {
const session = await this.get(tel);
if (session.ready) {
return session;
}
attempts++;
if (attempts < maxAttempts) {
await new Promise((resolve) => setTimeout(resolve, interval));
}
}
throw new Error("Timeout waiting for session to be ready");
}
};
// src/resources/Messages.ts
var Messages = class {
constructor(client) {
this.client = client;
}
/**
* Send a text or media message
* @param data - Message data
*/
async send(data) {
const response = await this.client["post"]("/api/messages/send", data);
return response.message;
}
/**
* Send a text message (convenience method)
* @param tel - Sender phone number
* @param to - Recipient ID
* @param text - Message text
* @param options - Additional options
*/
async sendText(tel, to, text, options) {
return this.send({ tel, to, text, options });
}
/**
* Send a media message (convenience method)
* @param tel - Sender phone number
* @param to - Recipient ID
* @param media - Base64 encoded media
* @param mimetype - Media MIME type
* @param filename - Media filename
* @param caption - Optional caption
*/
async sendMedia(tel, to, media, mimetype, filename, caption) {
return this.send({ tel, to, media, mimetype, filename, caption });
}
/**
* Send an interactive message (buttons or list)
* @param tel - Sender phone number
* @param to - Recipient ID
* @param interactive - Interactive message data
*/
async sendInteractive(tel, to, interactive) {
const response = await this.client["post"]("/api/messages/interactive", {
tel,
to,
interactive
});
return response.message;
}
/**
* Send a poll
* @param tel - Sender phone number
* @param to - Recipient ID
* @param poll - Poll data
*/
async sendPoll(tel, to, poll) {
const response = await this.client["post"]("/api/messages/poll", {
tel,
to,
poll
});
return response.message;
}
/**
* Vote on a poll
* @param tel - Voter phone number
* @param vote - Vote data
*/
async votePoll(tel, vote) {
return this.client["post"]("/api/messages/poll/vote", {
tel,
...vote
});
}
/**
* List messages with filtering and pagination
* @param params - Query parameters
*/
async list(params) {
const response = await this.client["get"]("/api/messages", { params });
return {
messages: response.messages,
count: response.count,
total: response.total
};
}
/**
* Get a single message by ID
* @param id - Message database ID
*/
async get(id) {
const response = await this.client["get"](`/api/messages/${id}`);
return response.message;
}
/**
* Download media from a message
* @param id - Message database ID
*/
async downloadMedia(id) {
const response = await this.client["get"](`/api/messages/${id}/media`);
return {
data: response.data,
mimetype: response.mimetype,
filename: response.filename
};
}
/**
* Delete a message
* @param tel - Phone number
* @param messageId - WhatsApp message ID
* @param forEveryone - Delete for everyone
*/
async delete(tel, messageId, forEveryone = false) {
return this.client["delete"]("/api/messages", {
data: { tel, messageId, forEveryone }
});
}
/**
* React to a message
* @param tel - Phone number
* @param messageId - Message to react to
* @param emoji - Emoji reaction
*/
async react(tel, messageId, emoji) {
return this.client["post"](`/api/messages/${messageId}/reactions`, {
tel,
emoji
});
}
/**
* Remove a reaction from a message
* @param tel - Phone number
* @param messageId - Message to remove reaction from
*/
async removeReaction(tel, messageId) {
return this.client["post"](`/api/messages/${messageId}/reactions/remove`, {
tel
});
}
/**
* Get reactions for a message
* @param messageId - Message ID to get reactions for
*/
async getReactions(messageId) {
return this.client["get"](`/api/messages/${messageId}/reactions`);
}
/**
* Edit a message
* @param tel - Phone number
* @param messageId - Message to edit
* @param newText - New message text
*/
async edit(tel, messageId, newText) {
return this.client["post"]("/api/messages/edit", {
tel,
messageId,
newText
});
}
/**
* Pin a message
* @param tel - Phone number
* @param messageId - Message to pin
* @param duration - Pin duration in seconds (0 = forever)
*/
async pin(tel, messageId, duration = 0) {
return this.client["post"]("/api/messages/pin", {
tel,
messageId,
duration
});
}
/**
* Unpin a message
* @param tel - Phone number
* @param messageId - Message to unpin
*/
async unpin(tel, messageId) {
return this.client["post"]("/api/messages/unpin", {
tel,
messageId
});
}
/**
* Star a message
* @param tel - Phone number
* @param messageId - Message to star
*/
async star(tel, messageId) {
return this.client["post"]("/api/messages/star", {
tel,
messageId,
star: true
});
}
/**
* Unstar a message
* @param tel - Phone number
* @param messageId - Message to unstar
*/
async unstar(tel, messageId) {
return this.client["post"]("/api/messages/star", {
tel,
messageId,
star: false
});
}
/**
* Forward messages
* @param tel - Phone number
* @param to - Recipient IDs
* @param messageIds - Messages to forward
*/
async forward(tel, to, messageIds) {
const response = await this.client["post"]("/api/messages/forward", {
tel,
to,
messageIds
});
return response;
}
/**
* Send typing indicator
* @param tel - Phone number
* @param to - Chat ID
* @param typing - true for typing, false for paused
*/
async sendTyping(tel, to, typing = true) {
return this.client["post"]("/api/messages/typing", {
tel,
chatId: to,
typing
});
}
/**
* Mark messages as read
* @param tel - Phone number
* @param messageIds - Message IDs to mark as read
*/
async markRead(tel, messageIds) {
return this.client["post"]("/api/messages/read", {
tel,
messageIds
});
}
/**
* Send voice note
* @param tel - Phone number
* @param to - Recipient ID
* @param audioData - Base64 encoded audio data
* @param mimetype - Audio mimetype
* @param duration - Duration in seconds
*/
async sendVoiceNote(tel, to, audioData, mimetype = "audio/ogg; codecs=opus", duration) {
const response = await this.client["post"]("/api/messages/voice", {
tel,
to,
audioData,
mimetype,
duration
});
return response.message;
}
/**
* Send location message
* @param tel - Phone number
* @param to - Recipient ID
* @param latitude - Latitude coordinate
* @param longitude - Longitude coordinate
* @param name - Location name
* @param address - Location address
*/
async sendLocation(tel, to, latitude, longitude, name, address) {
const response = await this.client["post"]("/api/messages/location", {
tel,
to,
latitude,
longitude,
name,
address
});
return response.message;
}
/**
* Send live location message
* @param tel - Phone number
* @param to - Recipient ID
* @param latitude - Latitude coordinate
* @param longitude - Longitude coordinate
* @param duration - Sharing duration in seconds
*/
async sendLiveLocation(tel, to, latitude, longitude, duration = 3600) {
const response = await this.client["post"]("/api/messages/live-location", {
tel,
to,
latitude,
longitude,
duration
});
return response.message;
}
/**
* Send buttons message
* @param tel - Phone number
* @param to - Recipient ID
* @param text - Message text
* @param buttons - Array of buttons
* @param headerText - Optional header text
* @param footerText - Optional footer text
*/
async sendButtons(tel, to, text, buttons, headerText, footerText) {
const response = await this.client["post"]("/api/messages/buttons", {
tel,
to,
text,
buttons,
headerText,
footerText
});
return response.message;
}
/**
* Send list message
* @param tel - Phone number
* @param to - Recipient ID
* @param title - List title
* @param buttonText - Button text
* @param sections - List sections
*/
async sendList(tel, to, title, buttonText, sections) {
const response = await this.client["post"]("/api/messages/list", {
tel,
to,
title,
buttonText,
sections
});
return response.message;
}
/**
* Send sticker message
* @param tel - Phone number
* @param to - Recipient ID
* @param stickerData - Base64 encoded sticker data (WebP format)
*/
async sendSticker(tel, to, stickerData) {
const response = await this.client["post"]("/api/messages/sticker", {
tel,
to,
stickerData
});
return response.message;
}
/**
* Send album/multiple media
* @param tel - Phone number
* @param to - Recipient ID
* @param media - Array of media items
* @param caption - Shared caption
*/
async sendAlbum(tel, to, media, caption) {
const response = await this.client["post"]("/api/messages/album", {
tel,
to,
media,
caption
});
return response.message;
}
};
// src/resources/Chats.ts
var Chats = class {
constructor(client) {
this.client = client;
}
/**
* List all chats with optional filtering
* @param params - Query parameters for filtering
*/
async list(params) {
return this.client["get"]("/api/chats", { params });
}
/**
* Get a specific chat by ID
* @param tel - Phone number
* @param chatId - Chat ID
*/
async get(tel, chatId) {
const response = await this.client["get"](
`/api/chats/${encodeURIComponent(chatId)}`,
{ params: { tel } }
);
return response;
}
/**
* Mark chat as read
* @param tel - Phone number
* @param chatId - Chat ID
*/
async markAsRead(tel, chatId) {
return this.client["post"](
`/api/chats/${encodeURIComponent(chatId)}/read`,
{ tel }
);
}
/**
* Send typing indicator to chat
* @param tel - Phone number
* @param chatId - Chat ID
*/
async sendTyping(tel, chatId) {
return this.client["post"](
`/api/chats/${encodeURIComponent(chatId)}/typing`,
{ tel }
);
}
/**
* Archive or unarchive a chat
* @param tel - Phone number
* @param chatId - Chat ID
* @param archived - Archive status
*/
async archive(tel, chatId, archived = true) {
return this.client["patch"](
`/api/chats/${encodeURIComponent(chatId)}`,
{ tel, archived }
);
}
/**
* Pin or unpin a chat
* @param tel - Phone number
* @param chatId - Chat ID
* @param pinned - Pin status
*/
async pin(tel, chatId, pinned = true) {
return this.client["patch"](
`/api/chats/${encodeURIComponent(chatId)}`,
{ tel, pinned }
);
}
/**
* Mute or unmute a chat
* @param tel - Phone number
* @param chatId - Chat ID
* @param muted - Mute status
*/
async mute(tel, chatId, muted = true) {
return this.client["patch"](
`/api/chats/${encodeURIComponent(chatId)}`,
{ tel, muted }
);
}
/**
* Clear chat history
* @param tel - Phone number
* @param chatId - Chat ID
*/
async clearHistory(tel, chatId) {
return this.client["post"](
`/api/chats/${encodeURIComponent(chatId)}/clear`,
{ tel }
);
}
/**
* Update multiple chat properties at once
* @param tel - Phone number
* @param chatId - Chat ID
* @param updates - Properties to update
*/
async update(tel, chatId, updates) {
return this.client["patch"](
`/api/chats/${encodeURIComponent(chatId)}`,
{ tel, ...updates }
);
}
/**
* Get group chats only
* @param tel - Phone number
* @param params - Additional query parameters
*/
async getGroups(tel, params) {
return this.list({ tel, groups: true, ...params });
}
/**
* Get individual chats only
* @param tel - Phone number
* @param params - Additional query parameters
*/
async getIndividual(tel, params) {
return this.list({ tel, groups: false, ...params });
}
/**
* Get unread chats only
* @param tel - Phone number
* @param params - Additional query parameters
*/
async getUnread(tel, params) {
return this.list({ tel, unreadOnly: true, ...params });
}
/**
* Get archived chats
* @param tel - Phone number
* @param params - Additional query parameters
*/
async getArchived(tel, params) {
return this.list({ tel, archived: true, ...params });
}
/**
* Search chats by name or content
* @param tel - Phone number
* @param query - Search query
* @param params - Additional query parameters
*/
async search(tel, query, params) {
return this.list({ tel, search: query, ...params });
}
};
// src/resources/Contacts.ts
var Contacts = class {
constructor(client) {
this.client = client;
}
/**
* List all contacts
* @param tel - Phone number
* @param search - Optional search query
*/
async list(tel, search) {
const params = search ? { search } : void 0;
const response = await this.client["get"](
`/api/contacts/${encodeURIComponent(tel)}`,
{ params }
);
return response.contacts;
}
/**
* Get contact details
* @param tel - Phone number
* @param contactId - Contact ID
*/
async get(tel, contactId) {
const response = await this.client["get"](`/api/contacts/${encodeURIComponent(tel)}/${encodeURIComponent(contactId)}`);
return response.contact;
}
/**
* Check if numbers are registered on WhatsApp
* @param tel - Phone number
* @param numbers - Array of phone numbers to check
*/
async checkRegistered(tel, numbers) {
const response = await this.client["post"]("/api/contacts/check", {
tel,
numbers
});
return response.results;
}
/**
* Get contact profile picture
* @param tel - Phone number
* @param contactId - Contact ID
*/
async getProfilePicture(tel, contactId) {
const response = await this.client["get"](`/api/contacts/${encodeURIComponent(tel)}/${encodeURIComponent(contactId)}/picture`);
return { url: response.url };
}
/**
* Get contact status/about
* @param tel - Phone number
* @param contactId - Contact ID
*/
async getStatus(tel, contactId) {
const response = await this.client["get"](`/api/contacts/${encodeURIComponent(tel)}/${encodeURIComponent(contactId)}/status`);
return { status: response.status };
}
/**
* Block a contact
* @param tel - Phone number
* @param contactId - Contact ID to block
*/
async block(tel, contactId) {
return this.client["post"]("/api/contacts/block", {
tel,
contactId
});
}
/**
* Unblock a contact
* @param tel - Phone number
* @param contactId - Contact ID to unblock
*/
async unblock(tel, contactId) {
return this.client["post"]("/api/contacts/unblock", {
tel,
contactId
});
}
/**
* Get blocked contacts
* @param tel - Phone number
*/
async getBlocked(tel) {
const response = await this.client["get"](`/api/contacts/${encodeURIComponent(tel)}/blocked`);
return response.blockedContacts;
}
/**
* Get business profile of a contact
* @param tel - Phone number
* @param contactId - Business contact ID
*/
async getBusinessProfile(tel, contactId) {
const response = await this.client["get"](`/api/contacts/${encodeURIComponent(tel)}/${encodeURIComponent(contactId)}/business`);
return response.profile;
}
};
// src/resources/Groups.ts
var Groups = class {
constructor(client) {
this.client = client;
}
/**
* List all groups
* @param tel - Phone number
*/
async list(tel) {
const response = await this.client["get"](`/api/groups/${encodeURIComponent(tel)}`);
return response.groups;
}
/**
* Get group details
* @param tel - Phone number
* @param groupId - Group ID
*/
async get(tel, groupId) {
const response = await this.client["get"](`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}`);
return response.group;
}
/**
* Create a new group
* @param data - Group creation data
*/
async create(data) {
const response = await this.client["post"]("/api/groups", data);
return response.group;
}
/**
* Update group details
* @param tel - Phone number
* @param groupId - Group ID
* @param data - Update data
*/
async update(tel, groupId, data) {
return this.client["put"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}`,
data
);
}
/**
* Leave a group
* @param tel - Phone number
* @param groupId - Group ID
*/
async leave(tel, groupId) {
return this.client["post"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/leave`
);
}
/**
* Add participants to a group
* @param tel - Phone number
* @param groupId - Group ID
* @param participants - Array of participant IDs
*/
async addParticipants(tel, groupId, participants) {
return this.client["post"](`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/participants`, {
participants
});
}
/**
* Remove participants from a group
* @param tel - Phone number
* @param groupId - Group ID
* @param participants - Array of participant IDs
*/
async removeParticipants(tel, groupId, participants) {
return this.client["delete"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/participants`,
{ data: { participants } }
);
}
/**
* Promote participants to admin
* @param tel - Phone number
* @param groupId - Group ID
* @param participants - Array of participant IDs
*/
async promoteParticipants(tel, groupId, participants) {
return this.client["post"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/promote`,
{ participants }
);
}
/**
* Demote participants from admin
* @param tel - Phone number
* @param groupId - Group ID
* @param participants - Array of participant IDs
*/
async demoteParticipants(tel, groupId, participants) {
return this.client["post"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/demote`,
{ participants }
);
}
/**
* Get group invite link
* @param tel - Phone number
* @param groupId - Group ID
*/
async getInviteLink(tel, groupId) {
const response = await this.client["get"](`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/invite`);
return { code: response.code, url: response.url };
}
/**
* Revoke group invite link
* @param tel - Phone number
* @param groupId - Group ID
*/
async revokeInviteLink(tel, groupId) {
const response = await this.client["post"](`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/invite/revoke`);
return { code: response.code, url: response.url };
}
/**
* Accept group invite
* @param tel - Phone number
* @param inviteCode - Invite code
*/
async acceptInvite(tel, inviteCode) {
const response = await this.client["post"]("/api/groups/join", { tel, inviteCode });
return { groupId: response.groupId };
}
/**
* Set group profile picture
* @param tel - Phone number
* @param groupId - Group ID
* @param image - Base64 encoded image
*/
async setProfilePicture(tel, groupId, image) {
return this.client["post"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/picture`,
{ image }
);
}
/**
* Remove group profile picture
* @param tel - Phone number
* @param groupId - Group ID
*/
async removeProfilePicture(tel, groupId) {
return this.client["delete"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/picture`
);
}
/**
* Get group members who have read a message
* @param tel - Phone number
* @param groupId - Group ID
* @param messageId - Message ID
*/
async getMessageReaders(tel, groupId, messageId) {
const response = await this.client["get"](`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/readers/${messageId}`);
return response.readers;
}
/**
* Toggle group settings
* @param tel - Phone number
* @param groupId - Group ID
* @param setting - Setting to toggle
* @param value - New value
*/
async toggleSetting(tel, groupId, setting, value) {
return this.client["post"](
`/api/groups/${encodeURIComponent(tel)}/${encodeURIComponent(groupId)}/settings`,
{ [setting]: value }
);
}
};
// src/resources/Status.ts
var Status = class {
constructor(client) {
this.client = client;
}
/**
* Get all status updates
* @param tel - Phone number
*/
async list(tel) {
const response = await this.client["get"](`/api/status/${encodeURIComponent(tel)}`);
return response.statuses;
}
/**
* Get status updates from a specific contact
* @param tel - Phone number
* @param contactId - Contact ID
*/
async getContactStatus(tel, contactId) {
const response = await this.client["get"](`/api/status/${encodeURIComponent(tel)}/${encodeURIComponent(contactId)}`);
return response.statuses;
}
/**
* Post a new status update
* @param data - Status update data
*/
async post(data) {
const response = await this.client["post"]("/api/status", data);
return { id: response.id };
}
/**
* Post a text status
* @param tel - Phone number
* @param content - Status text
* @param backgroundColor - Background color (hex)
* @param font - Font style (0-5)
*/
async postText(tel, content, backgroundColor, font) {
return this.post({
tel,
type: "text",
content,
backgroundColor,
font
});
}
/**
* Post an image status
* @param tel - Phone number
* @param media - Base64 encoded image
* @param caption - Optional caption
*/
async postImage(tel, media, caption) {
return this.post({
tel,
type: "image",
media,
caption
});
}
/**
* Post a video status
* @param tel - Phone number
* @param media - Base64 encoded video
* @param caption - Optional caption
*/
async postVideo(tel, media, caption) {
return this.post({
tel,
type: "video",
media,
caption
});
}
/**
* Delete a status update
* @param tel - Phone number
* @param statusId - Status ID to delete
*/
async delete(tel, statusId) {
return this.client["delete"](
`/api/status/${encodeURIComponent(tel)}/${statusId}`
);
}
/**
* Mark status as seen
* @param tel - Phone number
* @param statusId - Status ID
*/
async markSeen(tel, statusId) {
return this.client["post"]("/api/status/seen", {
tel,
statusId
});
}
/**
* Get status privacy settings
* @param tel - Phone number
*/
async getPrivacySettings(tel) {
const response = await this.client["get"](`/api/status/${encodeURIComponent(tel)}/privacy`);
return response.privacy;
}
/**
* Update status privacy settings
* @param tel - Phone number
* @param settings - Privacy settings
*/
async updatePrivacySettings(tel, settings) {
return this.client["post"](
`/api/status/${encodeURIComponent(tel)}/privacy`,
settings
);
}
/**
* Download status media
* @param tel - Phone number
* @param statusId - Status ID
*/
async downloadMedia(tel, statusId) {
const response = await this.client["get"](`/api/status/${encodeURIComponent(tel)}/${statusId}/media`);
return {
data: response.data,
mimetype: response.mimetype,
filename: response.filename
};
}
/**
* Get who viewed a status
* @param tel - Phone number
* @param statusId - Status ID
*/
async getViewers(tel, statusId) {
const response = await this.client["get"](`/api/status/${encodeURIComponent(tel)}/${statusId}/viewers`);
return response.viewers;
}
};
// src/resources/Webhooks.ts
var Webhooks = class {
constructor(client) {
this.client = client;
}
/**
* Get all webhooks for a session
* @param tel - Phone number
*/
async list(tel) {
const response = await this.client["get"](`/api/sessions/${encodeURIComponent(tel)}/webhooks`);
return response.data;
}
/**
* Get webhook details
* @param tel - Phone number
* @param webhookId - Webhook ID
*/
async get(tel, webhookId) {
const response = await this.client["get"](`/api/sessions/${encodeURIComponent(tel)}/webhooks/${webhookId}`);
return response.data;
}
/**
* Create a new webhook for a session
* @param tel - Phone number
* @param data - Webhook creation data
*/
async create(tel, data) {
const response = await this.client["post"](`/api/sessions/${encodeURIComponent(tel)}/webhooks`, {
...data,
tel
});
return response.data;
}
/**
* Update webhook details
* @param tel - Phone number
* @param webhookId - Webhook ID
* @param data - Update data
*/
async update(tel, webhookId, data) {
const response = await this.client["put"](`/api/sessions/${encodeURIComponent(tel)}/webhooks/${webhookId}`, data);
return response.data;
}
/**
* Delete a webhook
* @param tel - Phone number
* @param webhookId - Webhook ID
*/
async delete(tel, webhookId) {
const response = await this.client["delete"](
`/api/sessions/${encodeURIComponent(tel)}/webhooks/${webhookId}`
);
return { message: response.message || "Webhook deleted successfully" };
}
/**
* Test a webhook
* @param tel - Phone number
* @param webhookId - Webhook ID
*/
async test(tel, webhookId) {
return this.client["post"](
`/api/sessions/${encodeURIComponent(tel)}/webhooks/${webhookId}/test`
);
}
/**
* Rotate webhook secret
* @param tel - Phone number
* @param webhookId - Webhook ID
*/
async rotateSecret(tel, webhookId) {
const response = await this.client["post"](`/api/sessions/${encodeURIComponent(tel)}/webhooks/${webhookId}/rotate-secret`);
return response.data;
}
/**
* Get webhook logs and statistics
* @param tel - Phone number
* @param webhookId - Webhook ID
*/
async getLogs(tel, webhookId) {
const response = await this.client["get"](`/api/sessions/${encodeURIComponent(tel)}/webhooks/${webhookId}/logs`);
return response.data;
}
/**
* Toggle webhook active status
* @param tel - Phone number
* @param webhookId - Webhook ID
* @param active - Active status
*/
async toggleActive(tel, webhookId, active) {
return this.update(tel, webhookId, { active });
}
/**
* Bulk create webhooks for multiple events
* @param tel - Phone number
* @param url - Webhook URL
* @param events - Array of events to subscribe to
* @param options - Optional webhook configuration
*/
async createForEvents(tel, url, events, options) {
return this.create(tel, {
name: options?.name || `Webhook for ${events.join(", ")}`,
url,
events,
headers: options?.headers,
retryConfig: options?.retryConfig
});
}
/**
* Quick setup for message events
* @param tel - Phone number
* @param url - Webhook URL
* @param name - Optional webhook name
*/
async setupMessageWebhook(tel, url, name) {
return this.createForEvents(tel, url, ["message.received"], {
name: name || "Message Webhook"
});
}
/**
* Quick setup for session events
* @param tel - Phone number
* @param url - Webhook URL
* @param name - Optional webhook name
*/
async setupSessionWebhook(tel, url, name) {
return this.createForEvents(tel, url, [
"session.connected",
"session.disconnected",
"session.qr"
], {
name: name || "Session Events Webhook"
});
}
};
// src/resources/Admin.ts
var Admin = class {
constructor(client) {
this.client = client;
}
// User Management
/**
* List all users
* @param params - Query parameters for filtering and pagination
*/
async listUsers(params) {
return this.client["get"]("/api/users", { params });
}
/**
* Get a specific user by ID
* @param userId - User ID
*/
async getUser(userId) {
return this.client["get"](`/api/users/${userId}`);
}
/**
* Create a new user
* @param userData - User creation data
*/
async createUser(userData) {
return this.client["post"]("/api/users", userData);
}
/**
* Update an existing user
* @param userId - User ID
* @param updates - User update data
*/
async updateUser(userId, updates) {
return this.client["put"](`/api/users/${userId}`, updates);
}
/**
* Deactivate a user
* @param userId - User ID
*/
async deactivateUser(userId) {
return this.client["patch"](`/api/users/${userId}/deactivate`);
}
/**
* Delete a user permanently
* @param userId - User ID
*/
async deleteUser(userId) {
return this.client["delete"](`/api/users/${userId}`);
}
// Token Management
/**
* List all API tokens
* @param params - Query parameters for filtering and pagination
*/
async listTokens(params) {
return this.client["get"]("/api/tokens", { params });
}
/**
* Get a specific token by ID
* @param tokenId - Token ID
*/
async getToken(tokenId) {
return this.client["get"](`/api/tokens/${tokenId}`);
}
/**
* Create a new API token
* @param tokenData - Token creation data
*/
async createToken(tokenData) {
return this.client["post"]("/api/tokens", tokenData);
}
/**
* Update an existing token
* @param tokenId - Token ID
* @param updates - Token update data
*/
async updateToken(tokenId, updates) {
return this.client["put"](`/api/tokens/${tokenId}`, updates);
}
/**
* Revoke a token (set inactive)
* @param tokenId - Token ID
*/
async revokeToken(tokenId) {
return this.client["post"](`/api/tokens/${tokenId}/revoke`);
}
/**
* Rotate a token (generate new token value)
* @param tokenId - Token ID
*/
async rotateToken(tokenId) {
return this.client["post"](`/api/tokens/${tokenId}/rotate`);
}
/**
* Delete a token permanently
* @param tokenId - Token ID
*/
async deleteToken(tokenId) {
return this.client["delete"](`/api/tokens/${tokenId}`);
}
// Session Management
/**
* Assign users to a session
* @param tel - Session phone number
* @param userIds - Array of user IDs to assign
*/
async assignUsersToSession(tel, userIds) {
return this.client["post"](`/api/sessions/${encodeURIComponent(tel)}/assign-users`, {
userIds
});
}
/**
* Assign tokens to a session
* @param tel - Session phone number
* @param tokenIds - Array of token IDs to assign
*/
async assignTokensToSession(tel, tokenIds) {
return this.client["post"](`/api/sessions/${encodeURIComponent(tel)}/assign-tokens`, {
tokenIds
});
}
// Analytics
/**
* Get system analytics
* @param period - Time period ('day', 'week', 'month')
*/
async getSystemAnalytics(period = "week") {
return this.client["get"]("/api/admin/analytics", {
params: { period }
});
}
/**
* Get user analytics
* @param userId - User ID
* @param period - Time period
*/
async getUserAnalytics(userId, period = "week") {
return this.client["get"](`/api/admin/users/${userId}/analytics`, {
params: { period }
});
}
/**
* Get token analytics
* @param tokenId - Token ID
* @param period - Time period
*/
async getTokenAnalytics(tokenId, period = "week") {
return this.client["get"](`/api/admin/tokens/${tokenId}/analytics`, {
params: { period }
});
}
};
// src/resources/Business.ts
var Business = class {
constructor(client) {
this.client = client;
}
// Product Management
/**
* List all products for a session
* @param tel - Phone number
* @param params - Query parameters for filtering and pagination
*/
async listProducts(tel, params) {
return this.client["get"]("/api/catalog/products", {
params: { tel, ...params }
});
}
/**
* Get a specific product by ID
* @param tel - Phone number
* @param productId - Product ID
*/
async getProduct(tel, productId) {
return this.client["get"](`/api/catalog/products/${productId}`, {
params: { tel }
});
}
/**
* Create a new product
* @param productData - Product creation data
*/
async createProduct(productData) {
return this.client["post"]("/api/catalog/products", productData);
}
/**
* Update an existing product
* @param tel - Phone number
* @param productId - Product ID
* @param updates - Product update data
*/
async updateProduct(tel, productId, updates) {
return this.client["put"](`/api/catalog/products/${productId}`, {
tel,
...updates
});
}
/**
* Delete a product
* @param tel - Phone number
* @param productId - Product ID
*/
async deleteProduct(tel, productId) {
return this.client["delete"](`/api/catalog/products/${productId}`, {
data: { tel }
});
}
/**
* Update product inventory
* @param tel - Phone number
* @param productId - Product ID
* @param inventory - New inventory count
* @param inStock - Stock status
*/
async updateInventory(tel, productId, inventory, inStock) {
return this.client["patch"](`/api/catalog/products/${productId}/inventory`, {
tel,
inventory,
inStock: inStock ?? inventory > 0
});
}
// Order Management
/**
* List all orders for a session
* @param tel - Phone number
* @param params - Query parameters for filtering and pagination
*/
async listOrders(tel, params) {
return this.client["get"]("/api/orders", {
params: { tel, ...params }
});
}
/**
* Get a specific order by ID
* @param tel - Phone number
* @param orderId - Order ID
*/
async getOrder(tel, orderId) {
return this.client["get"](`/api/orders/${orderId}`, {
params: { tel }
});
}
/**
* Confirm an order
* @param tel - Phone number
* @param orderId - Order ID
* @param notes - Optional confirmation notes
*/
async confirmOrder(tel, orderId, notes) {
return this.client["post"](`/api/orders/${orderId}/confirm`, {
tel,
notes
});
}
/**
* Update order status
* @param tel - Phone number
* @param orderId - Order ID
* @param status - New order status
* @param notes - Optional status update notes
*/
async updateOrderStatus(tel, orderId, status, notes) {
return this.client["patch"](`/api/orders/${orderId}/status`, {
tel,
status,
notes
});
}
/**
* Cancel an order
* @param tel - Phone number
* @param orderId - Order ID
* @param reason - Cancellation reason
*/
async cancelOrder(tel, orderId, reason) {
return this.client["post"](`/api/orders/${orderId}/cancel`, {
tel,
reason
});
}
// Shopping Cart Management
/**
* Create a new shopping cart for a customer
* @param tel - Phone number
* @param customerId - Customer ID
* @param expirationHours - Cart expiration in hours (default: 24)
*/
async createCart(tel, customerId, expirationHours = 24) {
return this.client["post"]("/api/carts", {
tel,
customerId,
expirationHours
});
}
/**
* Get a customer's cart
* @param tel - Phone number
* @param customerId - Customer ID
*/
async getCart(tel, customerId) {
return this.client["get"](`/api/carts/${customerId}`, {
params: { tel }
});
}
/**
* Add item to cart
* @param tel - Phone number
* @param customerId - Customer ID
* @param productId - Product ID to add
* @param quantity - Quantity to add
*/
async addToCart(tel, customerId, productId, quantity = 1) {
return this.client["post"](`/api/carts/${customerId}/items`, {
tel,
productId,
quantity
});
}
/**
* Update item quantity in cart
* @param tel - Phone number
* @param customerId - Customer ID
* @param productId - Product ID to update
* @param quantity - New quantity
*/
async updateCartItem(tel, customerId, productId, quantity) {
return this.client["patch"](`/api/carts/${customerId}/items/${productId}`, {
tel,
quantity
});
}
/**
* Remove item from cart
* @param tel - Phone number
* @param customerId - Customer ID
* @param productId - Product ID to remove
*/
async removeFromCart(tel, customerId, productId) {
return this.client["delete"](`/api/carts/${customerId}/items/${productId}`, {
data: { tel }
});
}
/**
* Clear entire cart
* @param tel - Phone number
* @param customerId - Customer ID
*/
async clearCart(tel, customerId) {
return this.client["delete"](`/api/carts/${customerId}`, {
data: { tel }
});
}
/**
* Convert cart to order
* @param tel - Phone number
* @param customerId - Customer ID
* @param shipping - Shipping information
* @param payment - Payment information
*/
async checkoutCart(tel, customerId, shipping, payment) {
return this.client["post"](`/api/carts/${customerId}/checkout`, {
tel,
shipping,
payment
});
}
// Business Analytics
/**
* Get product analytics
* @param tel - Phone number
* @param period - Time period ('day', 'week', 'month')
*/
async getProductAnalytics(tel, period = "week") {
return this.client["get"]("/api/business/analytics/products", {
params: { tel, period }
});
}
/**
* Get order analytics
* @param tel - Phone number
* @param period - Time period ('day', 'week', 'month')
*/
async getOrderAnalytics(tel, period = "week") {
return this.client["get"]("/api/business/analytics/orders", {
params: { tel, period }
});
}
};
// src/bot/BotFramework.ts
import { EventEmitter } from "events";
var BotFramework = class extends EventEmitter {
constructor(client, tel, config) {
super();
this.client = client;
this.tel = tel;
this.commands = /* @__PURE__ */ new Map();
this.middleware = [];
this.rateLimits = /* @__PURE__ */ new Map();
this.config = {
caseSensitive: false,
defaultResponse: "Command not found. Type !help for available commands.",
maxCommandsPerMinute: 10,
permissionDeniedMessage: "You do not have permission to use this command.",
commandNotFoundMessage: "Command not found. Type !help for available commands.",
errorMessage: "An error occurred while processing your command.",
...config
};
this.addCommand({
name: "help",
description: "Show available commands",
usage: `${this.config.prefix}help [command]`,
handler: async (context, args) => {
if (args.length > 0) {
return this.getCommandHelp(args[0]);
}
return this.getHelpText();
}
});
}
/**
* Add a command to the bot
*/
addCommand(command) {
const commandName = this.config.caseSensitive ? command.name : command.name.toLowerCase();
this.commands.set(commandName, command);
this.emit("command:added", command);
}
/**
* Remove a command from the bot
*/
removeCommand(name) {
const commandName = this.config.caseSensitive ? name : name.toLowerCase();
const removed = this.commands.delete(commandName);
if (removed) {
this.emit("command:removed", name);
}
return removed;
}
/**
* Add middleware to the bot
*/
use(middleware2) {
this.middleware.push(middleware2);
}
/**
* Process an incoming message
*/
async processMessage(message) {
try {
const text = message.message?.conversation || message.message?.extendedTextMessage?.text || "";
if (!text.startsWith(this.config.prefix)) {
return;
}
const commandText = text.slice(this.config.prefix.length).trim();
const [commandName, ...args] = commandText.split(/\s+/);
if (!commandName) {
return;
}
const context = {
message,
client: this.client,
tel: this.tel,
chatId: message.key.remoteJid,
senderId: message.key.participant || message.key.remoteJid,
isGroup: message.key.remoteJid.endsWith("@g.us")
};
if (!this.checkRateLimit(context.senderId)) {
await this.sendResponse(context, "You are sending commands too quickly. Please wait before trying again.");
return;
}
const lookupName = this.config.caseSensitive ? commandName : commandName.toLowerCase();
const command = this.commands.get(lookupName);
if (!command) {
await this.sendResponse(context, this.config.commandNotFoundMessage);
return;
}
let middlewareIndex = 0;
const executeMiddleware = async () => {
if (middlewareIndex >= this.middleware.length) {
await this.executeCommand(command, context, args);
return;
}
const middleware2 = this.middleware[middlewareIndex++];
await middleware2(context, executeMiddleware);
};
await executeMiddleware();
} catch (error) {
this.emit("error", error);
console.error("Bot error:", error);
}
}
/**
* Execute a command
*/
async executeCommand(command, context, args) {
try {
if (command.permissions && command.permissions.length > 0) {
if (!context.user || !this.hasPermissions(context.user, command.permissions)) {
await this.sendResponse(context, this.config.permissionDeniedMessage);
return;
}
}
this.emit("command:start", { command: command.name, context, args });
const response = await command.handler(context, args);
if (response) {
await this.sendResponse(context, response);
}
this.emit("command:complete", { command: command.name, context, args, response });
} catch (error) {
this.emit("command:error", { command: command.name, context, args, error });
await this.sendResponse(context, this.config.errorMessage);
throw error instanceof Error ? error : new Error(String(error));
}
}
/**
* Send response to chat
*/
async sendResponse(context, response) {
try {
await this.client.messages.sendText(context.tel, context.chatId, response);
} catch (error) {
this.emit("error", error);
console.error("Failed to send bot response:", error);
}
}
/**
* Check rate limiting for user
*/
checkRateLimit(userId) {
const now = Date.n