@mengkodingan/ckptw
Version:
Create powerful WhatsApp bots easily
1,618 lines (1,592 loc) • 46.3 kB
JavaScript
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
// src/Constant/Events.ts
var Events;
var init_Events = __esm({
"src/Constant/Events.ts"() {
"use strict";
Events = {
"ClientReady": "ClientReady",
"ConnectionUpdate": "ConnectionUpdate",
"MessagesUpsert": "MessagesUpsert",
"QR": "QR",
"GroupsJoin": "GroupsJoin",
"UserJoin": "UserJoin",
"UserLeave": "UserLeave",
"Poll": "Poll",
"PollVote": "PollVote",
"Reactions": "Reactions",
"Call": "Call"
};
}
});
// src/Common/Functions.ts
import { getContentType, jidDecode, proto } from "@whiskeysockets/baileys";
import fs from "fs";
import path from "path";
var arrayMove, getContentFromMsg, getSender, walk, decodeJid, makeRealInteractiveMessage;
var init_Functions = __esm({
"src/Common/Functions.ts"() {
"use strict";
arrayMove = (arr, old_index, new_index) => {
if (new_index >= arr.length) {
let k = new_index - arr.length + 1;
while (k--) {
arr.push(void 0);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr;
};
getContentFromMsg = (msg) => {
const type = getContentType(msg.message);
switch (type) {
case "conversation":
return msg.message?.conversation;
case "imageMessage":
return msg.message?.imageMessage?.caption;
case "documentMessage":
return msg.message?.documentMessage?.caption;
case "videoMessage":
return msg.message?.videoMessage?.caption;
case "extendedTextMessage":
return msg.message?.extendedTextMessage?.text;
case "listResponseMessage":
return msg.message?.listResponseMessage?.singleSelectReply?.selectedRowId;
case "buttonsResponseMessage":
return msg.message?.buttonsResponseMessage?.selectedButtonId;
case "templateButtonReplyMessage":
return msg.message?.templateButtonReplyMessage?.selectedId;
case "interactiveResponseMessage":
return JSON.parse(
msg.message?.interactiveResponseMessage?.nativeFlowResponseMessage?.paramsJson
)?.id;
case "messageContextInfo":
return msg.message?.buttonsResponseMessage?.selectedButtonId || msg.message?.listResponseMessage?.singleSelectReply?.selectedRowId || msg.message?.interactiveResponseMessage?.nativeFlowResponseMessage;
default:
return "";
}
};
getSender = (msg, client) => {
return msg.key?.fromMe ? client.user?.id : msg.participant ? msg.participant : msg.key?.participant ? msg.key.participant : msg.key?.remoteJid;
};
walk = (dir, callback) => {
const files = fs.readdirSync(dir);
files.forEach((file) => {
var filepath = path.join(dir, file);
const stats = fs.statSync(filepath);
if (stats.isDirectory()) {
walk(filepath, callback);
} else if (stats.isFile()) {
callback(filepath, stats);
}
});
};
decodeJid = (jid) => {
if (!jid) return jid;
if (/:\d+@/gi.test(jid)) {
let decode = jidDecode(jid);
return decode?.user && decode.server && decode.user + "@" + decode.server || jid;
} else return jid;
};
makeRealInteractiveMessage = (content) => {
let contentReal = {};
Object.keys(content).map((x) => {
if (x === "body") {
contentReal["body"] = proto.Message.InteractiveMessage.Body.create({ text: content.body });
} else if (x === "footer") {
contentReal["footer"] = proto.Message.InteractiveMessage.Footer.create({ text: content.footer });
} else if (x === "contextInfo") {
contentReal["contextInfo"] = content["contextInfo"];
} else if (x === "shopStorefrontMessage") {
contentReal["shopStorefrontMessage"] = proto.Message.InteractiveMessage.ShopMessage.create(content["shopStorefrontMessage"]);
} else {
let prop = proto.Message.InteractiveMessage[x.charAt(0).toUpperCase() + x.slice(1)];
contentReal[x] = prop.create(content[x]);
}
});
return contentReal;
};
}
});
// src/Classes/Collector/Collector.ts
import { Collection } from "@discordjs/collection";
import { EventEmitter } from "events";
var Collector;
var init_Collector = __esm({
"src/Classes/Collector/Collector.ts"() {
"use strict";
Collector = class extends EventEmitter {
isRun;
filter;
time;
max;
maxProcessed;
collector;
received;
constructor(options = {
filter: function() {
throw new Error("Function not implemented.");
},
time: 0,
max: 0,
maxProcessed: 0
}) {
super();
this.isRun = false;
this.filter = options.filter ?? (() => true);
if (this.isRun) throw new Error("some collector already run in another instance");
if (typeof this.filter !== "function") throw new Error("filter options in collector must be Function");
this.time = options.time;
this.max = options.max;
this.maxProcessed = options.maxProcessed;
this.collector = new Collection();
this.collect = this.collect.bind(this);
if (options.time) this.isRun = setTimeout(() => this.stop(), this.time);
}
async collect(t) {
let args = this._collect(t);
if (args) {
if (this.maxProcessed && this.maxProcessed === this.received) {
this.stop("processedLimit");
} else {
let filtered = await this.filter(args, this.collector);
if (filtered) {
if (this.max && this.max <= this.collector.size) {
this.stop("limit");
} else {
if (this.isRun) {
this.collector.set(args.jid, args);
this.emit("collect", args);
}
}
}
}
}
}
stop(r = "timeout") {
if (this.isRun) {
clearTimeout(this.isRun);
this.isRun = void 0;
this.emit("end", this.collector, r);
}
}
};
}
});
// src/Classes/Collector/MessageCollector.ts
var MessageCollector;
var init_MessageCollector = __esm({
"src/Classes/Collector/MessageCollector.ts"() {
"use strict";
init_Functions();
init_Events();
init_Collector();
MessageCollector = class extends Collector {
constructor(clientReq, options = {
filter: function(args, collector) {
throw new Error("Function not implemented.");
},
time: 0,
max: 0,
maxProcessed: 0
}) {
super(options);
this.clientReq = clientReq;
this.jid = this.clientReq.msg.key.remoteJid;
this.received = 0;
this.clientReq.self.ev.on(Events.MessagesUpsert, this.collect);
this.once("end", () => {
this.removeListener(Events.MessagesUpsert, this.collect);
});
return this;
}
_collect(msg) {
let content = getContentFromMsg(msg);
if (!msg.key?.fromMe && this.jid === msg.key?.remoteJid && content?.length) {
this.received++;
let sender = getSender(msg, this.clientReq.self.core);
return {
...msg,
jid: msg.key?.remoteJid,
decodedJid: msg.key?.remoteJid ? decodeJid(msg.key.remoteJid) : null,
sender,
decodedSender: sender ? decodeJid(sender) : null,
content
};
} else {
return null;
}
}
};
}
});
// src/Classes/Group/GroupData.ts
var GroupData;
var init_GroupData = __esm({
"src/Classes/Group/GroupData.ts"() {
"use strict";
init_Functions();
GroupData = class {
ctx;
jid;
constructor(ctx, jid) {
this.ctx = ctx;
this.jid = jid;
}
async members() {
let metadata = await this.metadata();
return metadata.participants;
}
async inviteCode() {
return await this.ctx._client.groupInviteCode(this.jid);
}
async revokeInviteCode() {
return await this.ctx._client.groupRevokeInvite(this.jid);
}
async joinApproval(mode) {
return await this.ctx._client.groupJoinApprovalMode(this.jid, mode);
}
async leave() {
this.ctx._client.groupLeave(this.jid);
}
async membersCanAddMemberMode(mode) {
return await this.ctx._client.groupMemberAddMode(this.jid, mode === "on" ? "all_member_add" : "admin_add");
}
async metadata() {
return await this.ctx._client.groupMetadata(this.jid);
}
async getMetadata(key) {
let metadata = await this.metadata();
return metadata[key];
}
async name() {
return await this.getMetadata("subject");
}
async description() {
return await this.getMetadata("desc");
}
async owner() {
return await this.getMetadata("owner");
}
async isAdmin(jid) {
let members = await this.members();
let check = members.filter((x) => decodeJid(x.id) === decodeJid(jid) && (x.admin === "admin" || x.admin === "superadmin"));
return check.length > 0;
}
async isSenderAdmin() {
return await this.isAdmin(this.ctx.sender.decodedJid);
}
async isBotAdmin() {
return await this.isAdmin(this.ctx.me.decodedId);
}
async toggleEphemeral(expiration) {
return await this.ctx._client.groupToggleEphemeral(this.jid, expiration);
}
async updateDescription(description) {
return await this.ctx._client.groupUpdateDescription(this.jid, description);
}
async updateSubject(subject) {
return await this.ctx._client.groupUpdateSubject(this.jid, subject);
}
async membersUpdate(members, action) {
return await this.ctx._client.groupParticipantsUpdate(this.jid, members, action);
}
async kick(members) {
return await this.membersUpdate(members, "remove");
}
async add(members) {
return await this.membersUpdate(members, "add");
}
async promote(members) {
return await this.membersUpdate(members, "promote");
}
async demote(members) {
return await this.membersUpdate(members, "demote");
}
async pendingMembers() {
return await this.ctx._client.groupRequestParticipantsList(this.jid);
}
async pendingMembersUpdate(members, action) {
return this.ctx._client.groupRequestParticipantsUpdate(this.jid, members, action);
}
async approvePendingMembers(members) {
return this.pendingMembersUpdate(members, "approve");
}
async rejectPendingMembers(members) {
return this.pendingMembersUpdate(members, "reject");
}
async updateSetting(setting) {
await this.ctx._client.groupSettingUpdate(this.jid, setting);
}
async open() {
await this.updateSetting("not_announcement");
}
async close() {
await this.updateSetting("announcement");
}
async lock() {
await this.updateSetting("locked");
}
async unlock() {
await this.updateSetting("unlocked");
}
};
}
});
// src/Classes/Group/Group.ts
var Group;
var init_Group = __esm({
"src/Classes/Group/Group.ts"() {
"use strict";
Group = class {
ctx;
constructor(ctx) {
this.ctx = ctx;
}
async create(subject, members) {
return await this.ctx._client.groupCreate(subject, members);
}
async inviteCodeInfo(code) {
return await this.ctx._client.groupGetInviteInfo(code);
}
async acceptInvite(code) {
return await this.ctx._client.groupAcceptInvite(code);
}
async acceptInviteV4(key, inviteMessage) {
return await this.ctx._client.groupAcceptInviteV4(key, inviteMessage);
}
};
}
});
// src/Classes/Ctx.ts
import { downloadMediaMessage, generateWAMessageFromContent, getDevice, prepareWAMessageMedia, proto as proto2 } from "@whiskeysockets/baileys";
var Ctx;
var init_Ctx = __esm({
"src/Classes/Ctx.ts"() {
"use strict";
init_Functions();
init_MessageCollector();
init_GroupData();
init_Group();
Ctx = class {
_used;
_args;
_self;
_client;
_msg;
_sender;
_config;
constructor(options) {
this._used = options.used;
this._args = options.args;
this._self = options.self;
this._client = options.client;
this._msg = this._self.m;
this._sender = {
jid: getSender(this._msg, this._client),
decodedJid: null,
pushName: this._msg.pushName
};
if (this._sender.jid) this._sender.decodedJid = decodeJid(this._sender.jid);
this._config = {
prefix: this._self.prefix,
cmd: this._self.cmd
};
}
get id() {
return this._msg.key?.remoteJid;
}
get used() {
return this._used;
}
get bot() {
return this._self;
}
get me() {
let user = this.core.user;
user["decodedId"] = decodeJid(user?.id);
user["readyAt"] = this.bot.readyAt;
return user;
}
get core() {
return this._client;
}
get decodedId() {
if (this._msg.key?.remoteJid) return decodeJid(this._msg.key.remoteJid);
}
get args() {
return this._args;
}
get msg() {
return {
...this._msg,
media: {
toBuffer: () => this.getMediaMessage(this._msg, "buffer"),
toStream: () => this.getMediaMessage(this._msg, "stream")
}
};
}
get sender() {
return this._sender;
}
async sendMessage(jid, content, options = {}) {
if (this._self.autoMention) {
let matchMention = content.text?.match(/(@[^](?![a-zA-Z]).\d*[$]*)/gm);
if (matchMention) {
for (let i = 0; i < matchMention.length; i++) {
if (matchMention[i].match(/^@\d/gm)) {
const num = matchMention[i].slice(1);
if (content.mentions) {
content.mentions.push(`${num}.whatsapp.net`);
} else {
content.mentions = [];
content.mentions.push(`${num}.whatsapp.net`);
}
}
}
}
}
return this._client.sendMessage(jid, content, options);
}
async reply(content, options = {}) {
if (typeof content === "string") content = { text: content };
return this.sendMessage(this.id, content, {
quoted: this._msg,
...options
});
}
async replyWithJid(jid, content, options = {}) {
return this.sendMessage(jid, content, { quoted: this._msg, ...options });
}
async react(jid, emoji, key) {
return this._client.sendMessage(jid, {
react: { text: emoji, key: key ? key : this._msg.key }
});
}
MessageCollector(args = {
filter: function(args2, collector) {
throw new Error("Function not implemented.");
},
time: 0,
max: 0,
maxProcessed: 0
}) {
return new MessageCollector({ self: this._self, msg: this._msg }, args);
}
awaitMessages(args = {
filter: function(args2, collector) {
throw new Error("Function not implemented.");
},
time: 0,
max: 0,
maxProcessed: 0
}) {
return new Promise((resolve, reject) => {
const col = this.MessageCollector(args);
col.once("end", (collected, r) => {
if (args.endReason?.includes(r)) {
reject(collected);
} else {
resolve(collected);
}
});
});
}
getMessageType() {
return this._msg.messageType;
}
async getMediaMessage(msg, type) {
try {
let buffer = await downloadMediaMessage(msg, type, {}, { logger: this._self.logger, reuploadRequest: this._client.updateMediaMessage });
return buffer;
} catch {
return null;
}
}
read() {
let m = this._msg;
this._client.readMessages([
{
remoteJid: m.key?.remoteJid,
id: m.key?.id,
participant: m.key?.participant
}
]);
}
simulateTyping() {
this._client.sendPresenceUpdate("composing", this.id);
}
async deleteMessage(key) {
return this._client.sendMessage(this.id, { delete: key });
}
simulateRecording() {
this._client.sendPresenceUpdate("recording", this.id);
}
async editMessage(key, newText) {
return await this.sendMessage(this.id, {
text: newText,
edit: key
});
}
async sendPoll(jid, args) {
args.selectableCount = args.singleSelect ? true : false;
return this._client.sendMessage(jid, { poll: args });
}
getMentioned() {
return this._msg.message?.extendedTextMessage ? this._msg.message.extendedTextMessage.contextInfo?.mentionedJid : [];
}
getDevice(id) {
return getDevice(id ? id : this._msg.key?.id);
}
isGroup() {
return this.id?.endsWith("@g.us");
}
async block(jid) {
if (jid) {
await this._client.updateBlockStatus(decodeJid(jid), "block");
} else {
await this._client.updateBlockStatus(decodeJid(this.id), "block");
}
}
async unblock(jid) {
if (jid) {
await this._client.updateBlockStatus(decodeJid(jid), "unblock");
} else {
await this._client.updateBlockStatus(decodeJid(this.id), "unblock");
}
}
get groups() {
return new Group(this);
}
group(jid) {
return new GroupData(this, jid ? jid : this.id);
}
get quoted() {
let msgContext = this._msg.message?.extendedTextMessage?.contextInfo;
let quotedMessage = msgContext?.quotedMessage;
return {
...quotedMessage,
senderJid: msgContext?.participant,
decodedSenderJid: decodeJid(msgContext?.participant),
media: {
toBuffer: async () => {
try {
let type = this.getContentType(quotedMessage);
let stream = await this.downloadContentFromMessage(quotedMessage?.[type], type.slice(0, -7));
let buffer = Buffer.from([]);
for await (const chunk of stream) {
buffer = Buffer.concat([buffer, chunk]);
}
return buffer;
} catch {
return null;
}
},
toStream: async () => {
try {
let type = this.getContentType(quotedMessage);
let stream = await this.downloadContentFromMessage(quotedMessage?.[type], type.slice(0, -7));
return stream;
} catch {
return null;
}
}
}
};
}
getContentType(content) {
return this._self.getContentType(content);
}
downloadContentFromMessage(downloadable, type, opts) {
return this._self.downloadContentFromMessage(downloadable, type, opts);
}
sendInteractiveMessage(jid, content, options = {}) {
let contentReal = makeRealInteractiveMessage(content);
if (this._self.autoMention) {
let matchMention = content.body?.match(/(@[^](?![a-zA-Z]).\d*[$]*)/gm);
if (matchMention) {
for (let i = 0; i < matchMention.length; i++) {
if (matchMention[i].match(/^@\d/gm)) {
const num = matchMention[i].slice(1);
if (contentReal.contextInfo?.mentionedJid) {
contentReal.contextInfo?.mentionedJid.push(`${num}.whatsapp.net`);
} else {
contentReal.contextInfo = { ...contentReal.contextInfo, mentionedJid: [] };
contentReal.contextInfo?.mentionedJid?.push(`${num}.whatsapp.net`);
}
}
}
}
}
let msg = generateWAMessageFromContent(jid, {
viewOnceMessage: {
message: {
"messageContextInfo": {
"deviceListMetadata": {},
"deviceListMetadataVersion": 2
},
interactiveMessage: proto2.Message.InteractiveMessage.create(contentReal)
}
}
}, options);
this._client.relayMessage(jid, msg.message, {
messageId: msg.key.id
});
}
async replyInteractiveMessage(content, options = {}) {
return this.sendInteractiveMessage(this.id, content, {
quoted: this._msg,
...options
});
}
async prepareWAMessageMedia(message, options) {
return prepareWAMessageMedia(message, options);
}
decodeJid(jid) {
return decodeJid(jid);
}
};
}
});
// src/Handler/Commands.ts
var Commands_exports = {};
__export(Commands_exports, {
default: () => Commands_default
});
var Commands_default;
var init_Commands = __esm({
"src/Handler/Commands.ts"() {
"use strict";
init_Functions();
init_Ctx();
Commands_default = async (self, runMiddlewares) => {
let { cmd, prefix, m } = self;
if (!m?.message || m.key?.remoteJid === "status@broadcast") return;
if (!self.selfReply && m.key?.fromMe) return;
const hasHears = Array.from(self.hearsMap.values()).filter(
(x) => x.name === m.content || x.name === m.messageType || new RegExp(x.name).test(m.content) || Array.isArray(x.name) && x.name.includes(m.content)
);
if (hasHears.length) return hasHears.forEach((x) => x.code(new Ctx({ used: { hears: m.content }, args: [], self, client: self.core })));
let commandsList = Array.from(cmd?.values() ?? []);
let selectedPrefix;
if (Array.isArray(prefix)) {
if (prefix[0] == "") {
const emptyIndex = prefix.findIndex((x) => x.includes(""));
prefix = arrayMove(prefix, emptyIndex - 1, prefix.length - 1);
} else {
selectedPrefix = prefix.find((p) => m.content?.startsWith(p));
}
} else if (prefix instanceof RegExp) {
const match = m.content?.match(prefix);
if (match) selectedPrefix = match[0];
}
if (!selectedPrefix) return;
let args = m.content?.slice(selectedPrefix.length).trim().split(/\s+/) || [];
let commandName = args?.shift()?.toLowerCase();
if (!commandName) return;
const matchedCommands = commandsList.filter(
(c) => c.name.toLowerCase() === commandName || (Array.isArray(c.aliases) ? c.aliases.includes(commandName) : c.aliases === commandName)
);
if (!matchedCommands.length) return;
let ctx = new Ctx({ used: { prefix: selectedPrefix, command: commandName }, args, self, client: self.core });
if (!await runMiddlewares(ctx)) return;
matchedCommands.forEach((cmd2) => cmd2.code(ctx));
};
}
});
// src/index.ts
import { Browsers as Browsers2, fetchLatestWaWebVersion } from "@whiskeysockets/baileys";
// src/Classes/Client.ts
init_Events();
init_Ctx();
init_Functions();
import makeWASocket3, {
Browsers,
DisconnectReason,
downloadContentFromMessage,
getContentType as getContentType2,
proto as proto3,
useMultiFileAuthState
} from "@whiskeysockets/baileys";
import pino from "pino";
import EventEmitter2 from "events";
import { Collection as Collection2 } from "@discordjs/collection";
// src/Handler/MessageEvents.ts
init_Ctx();
init_Events();
// src/Constant/MessageType.ts
var MessageType = {
"conversation": "conversation",
"senderKeyDistributionMessage": "senderKeyDistributionMessage",
"imageMessage": "imageMessage",
"contactMessage": "contactMessage",
"locationMessage": "locationMessage",
"extendedTextMessage": "extendedTextMessage",
"documentMessage": "documentMessage",
"audioMessage": "audioMessage",
"videoMessage": "videoMessage",
"call": "call",
"chat": "chat",
"protocolMessage": "protocolMessage",
"contactsArrayMessage": "contactsArrayMessage",
"highlyStructuredMessage": "highlyStructuredMessage",
"fastRatchetKeySenderKeyDistributionMessage": "fastRatchetKeySenderKeyDistributionMessage",
"sendPaymentMessage": "sendPaymentMessage",
"liveLocationMessage": "liveLocationMessage",
"requestPaymentMessage": "requestPaymentMessage",
"declinePaymentRequestMessage": "declinePaymentRequestMessage",
"cancelPaymentRequestMessage": "cancelPaymentRequestMessage",
"templateMessage": "templateMessage",
"stickerMessage": "stickerMessage",
"groupInviteMessage": "groupInviteMessage",
"templateButtonReplyMessage": "templateButtonReplyMessage",
"productMessage": "productMessage",
"deviceSentMessage": "deviceSentMessage",
"messageContextInfo": "messageContextInfo",
"listMessage": "listMessage",
"viewOnceMessage": "viewOnceMessage",
"orderMessage": "orderMessage",
"listResponseMessage": "listResponseMessage",
"ephemeralMessage": "ephemeralMessage",
"invoiceMessage": "invoiceMessage",
"buttonsMessage": "buttonsMessage",
"buttonsResponseMessage": "buttonsResponseMessage",
"paymentInviteMessage": "paymentInviteMessage",
"interactiveMessage": "interactiveMessage",
"reactionMessage": "reactionMessage",
"stickerSyncRmrMessage": "stickerSyncRmrMessage",
"interactiveResponseMessage": "interactiveResponseMessage",
"pollCreationMessage": "pollCreationMessage",
"pollUpdateMessage": "pollUpdateMessage",
"keepInChatMessage": "keepInChatMessage",
"documentWithCaptionMessage": "documentWithCaptionMessage",
"requestPhoneNumberMessage": "requestPhoneNumberMessage",
"viewOnceMessageV2": "viewOnceMessageV2",
"encReactionMessage": "encReactionMessage",
"editedMessage": "editedMessage",
"viewOnceMessageV2Extension": "viewOnceMessageV2Extension",
"pollCreationMessageV2": "pollCreationMessageV2",
"scheduledCallCreationMessage": "scheduledCallCreationMessage",
"groupMentionedMessage": "groupMentionedMessage",
"pinInChatMessage": "pinInChatMessage",
"pollCreationMessageV3": "pollCreationMessageV3",
"scheduledCallEditMessage": "scheduledCallEditMessage",
"ptvMessage": "ptvMessage",
"botInvokeMessage": "botInvokeMessage"
};
// src/Handler/ExtractEventsContent.ts
function ExtractEventsContent(m, msgType) {
let used = { upsert: m.content };
const eventMapping = {
[MessageType.pollCreationMessage]: (m2) => ({
poll: m2.message.pollCreationMessage.name
}),
[MessageType.pollUpdateMessage]: (m2) => ({
pollVote: m2.content
}),
[MessageType.reactionMessage]: (m2) => ({
reactions: m2.content
})
};
return eventMapping[msgType] ? { ...used, ...eventMapping[msgType](m) } : used;
}
var ExtractEventsContent_default = ExtractEventsContent;
// src/Handler/MessageEvents.ts
var emitPollCreation = async (m, ev, self, core) => {
let used = ExtractEventsContent_default(m, MessageType.pollCreationMessage);
m.pollValues = m.message.pollCreationMessage.options.map((x) => x.optionName);
m.pollSingleSelect = Boolean(m.message.pollCreationMessage.selectableOptionsCount);
ev?.emit(Events.Poll, m, new Ctx({ used, args: [], self, client: core }));
};
var emitPollUpdate = async (m, ev, self, core) => {
let used = ExtractEventsContent_default(m, MessageType.pollUpdateMessage);
ev?.emit(Events.PollVote, m, new Ctx({ used, args: [], self, client: core }));
};
var emitReaction = async (m, ev, self, core) => {
let used = ExtractEventsContent_default(m, MessageType.reactionMessage);
ev.emit(Events.Reactions, m, new Ctx({ used, args: [], self, client: core }));
};
var MessageEventList = {
[MessageType.pollCreationMessage]: emitPollCreation,
[MessageType.pollUpdateMessage]: emitPollUpdate,
[MessageType.reactionMessage]: emitReaction
};
// src/Constant/PHONENUMBER_MCC.ts
var PHONENUMBER_MCC = [
"1",
"7",
"20",
"27",
"30",
"31",
"32",
"33",
"34",
"36",
"39",
"40",
"41",
"43",
"44",
"45",
"46",
"47",
"48",
"49",
"51",
"52",
"53",
"54",
"55",
"56",
"57",
"58",
"60",
"61",
"62",
"63",
"64",
"65",
"66",
"81",
"82",
"84",
"86",
"90",
"91",
"92",
"93",
"94",
"95",
"98",
"211",
"212",
"213",
"216",
"218",
"220",
"221",
"222",
"223",
"224",
"225",
"226",
"227",
"228",
"229",
"230",
"231",
"232",
"233",
"234",
"235",
"236",
"237",
"238",
"239",
"240",
"241",
"242",
"243",
"244",
"245",
"248",
"249",
"250",
"251",
"253",
"254",
"255",
"256",
"257",
"258",
"260",
"261",
"262",
"263",
"264",
"265",
"266",
"267",
"268",
"269",
"290",
"291",
"297",
"298",
"299",
"350",
"351",
"352",
"353",
"354",
"355",
"356",
"357",
"358",
"359",
"370",
"371",
"372",
"373",
"374",
"375",
"376",
"377",
"378",
"379",
"380",
"381",
"382",
"383",
"385",
"386",
"387",
"389",
"420",
"423",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"509",
"591",
"592",
"593",
"595",
"597",
"598",
"599",
"670",
"673",
"674",
"675",
"676",
"677",
"678",
"679",
"680",
"681",
"682",
"683",
"685",
"686",
"687",
"688",
"689",
"690",
"691",
"692",
"850",
"852",
"855",
"856",
"880",
"886",
"960",
"961",
"962",
"963",
"964",
"965",
"966",
"967",
"968",
"970",
"971",
"972",
"973",
"974",
"975",
"976",
"977",
"992",
"993",
"994",
"995",
"998",
"1-684",
"1-264",
"1-268",
"1-242",
"1-246",
"1-441",
"1-284",
"1-345",
"1-767",
"1-809",
"1-849",
"1-829",
"1-473",
"1-671",
"1-876",
"1-664",
"1-670",
"1-787, 1-939",
"1-869",
"1-758",
"1-784",
"1-868",
"1-649",
"1-340"
];
// src/Classes/Client.ts
import consolefy from "@mengkodingan/consolefy";
var Client = class {
prefix;
readIncommingMsg;
authDir;
printQRInTerminal;
state;
saveCreds;
core;
ev;
cmd;
cooldown;
middlewares;
readyAt;
hearsMap;
qrTimeout;
markOnlineOnConnect;
logger;
phoneNumber;
usePairingCode;
selfReply;
WAVersion;
autoMention;
fallbackWAVersion;
authAdapter;
consolefy;
browser;
constructor(opts) {
this.prefix = opts.prefix;
this.readIncommingMsg = opts.readIncommingMsg ?? false;
this.authDir = opts.authDir ?? "./state";
this.printQRInTerminal = opts.printQRInTerminal ?? true;
this.phoneNumber = opts.phoneNumber;
this.usePairingCode = opts.usePairingCode ?? false;
this.qrTimeout = opts.qrTimeout ?? 6e4;
this.markOnlineOnConnect = opts.markOnlineOnConnect ?? true;
this.logger = opts.logger ?? pino({ level: "fatal" });
this.selfReply = opts.selfReply ?? false;
this.WAVersion = opts.WAVersion;
this.autoMention = opts.autoMention ?? false;
this.fallbackWAVersion = [2, 3e3, 1025144028];
this.authAdapter = opts.authAdapter ?? useMultiFileAuthState(this.authDir);
this.browser = opts.browser ?? Browsers.ubuntu("CHROME");
this.ev = new EventEmitter2();
this.cmd = new Collection2();
this.cooldown = new Collection2();
this.hearsMap = new Collection2();
this.middlewares = new Collection2();
this.consolefy = new consolefy.Consolefy();
if (typeof this.prefix === "string") this.prefix = this.prefix.split("");
}
onConnectionUpdate() {
this.core?.ev.on("connection.update", (update) => {
this.ev.emit(Events.ConnectionUpdate, update);
const { connection, lastDisconnect } = update;
if (update.qr) this.ev.emit(Events.QR, update.qr);
if (connection === "close") {
const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
this.consolefy?.error("connection closed due to ", lastDisconnect?.error, ", reconnecting ", shouldReconnect);
if (shouldReconnect) this.launch();
} else if (connection === "open") {
this.readyAt = Date.now();
this.ev?.emit(Events.ClientReady, this.core);
}
});
}
onCredsUpdate() {
this.core?.ev.on("creds.update", this.saveCreds);
}
read(m) {
this.core?.readMessages([
{
remoteJid: m.key?.remoteJid,
id: m.key?.id,
participant: m.key?.participant
}
]);
}
use(fn) {
this.middlewares?.set(this.middlewares.size, fn);
}
async runMiddlewares(ctx, index = 0) {
const middlewareFn = this.middlewares?.get(index);
if (!middlewareFn) return true;
let nextCalled = false;
let chainCompleted = false;
await middlewareFn(ctx, async () => {
nextCalled = true;
chainCompleted = await this.runMiddlewares(ctx, index + 1);
});
return nextCalled && chainCompleted;
}
onMessage() {
this.core?.ev.on("messages.upsert", async (m) => {
let msgType = getContentType2(m.messages[0].message);
let text = getContentFromMsg(m.messages[0]);
m.content = null;
if (text?.length) m.content = text;
m.messageType = msgType;
m = { ...m, ...m.messages[0] };
delete m.messages;
let self = { ...this, getContentType: getContentType2, downloadContentFromMessage, proto: proto3, m };
let used = ExtractEventsContent_default(m, msgType);
let ctx = new Ctx({ used, args: [], self, client: this.core });
if (MessageEventList[msgType]) {
await MessageEventList[msgType](m, this.ev, self, this.core);
}
this.ev?.emit(Events.MessagesUpsert, m, ctx);
if (this.readIncommingMsg) this.read(m);
const { default: CommandHandler2 } = await Promise.resolve().then(() => (init_Commands(), Commands_exports));
await CommandHandler2(self, this.runMiddlewares.bind(this));
});
}
onGroupParticipantsUpdate() {
this.core?.ev.on("group-participants.update", async (m) => {
if (m.action === "add") return this.ev.emit(Events.UserJoin, m);
if (m.action === "remove") return this.ev.emit(Events.UserLeave, m);
});
}
onGroupsJoin() {
this.core?.ev.on("groups.upsert", (m) => {
this.ev.emit(Events.GroupsJoin, m);
});
}
onCall() {
this.core?.ev.on("call", (m) => {
let withDecodedId = m.map((v) => ({ ...v, decodedFrom: decodeJid(v.from), decodedChatId: decodeJid(v.chatId) }));
this.ev.emit(Events.Call, withDecodedId);
});
}
/**
* Create a new command.
* @param opts Command options object or command name string.
* @param code If the first parameter is a command name as a string, then you should create a callback function in second parameter.
* @example
* ```
* bot.command('ping', async(ctx) => ctx.reply({ text: 'Pong!' }));
*
* // same as
*
* bot.command({
* name: 'ping',
* code: async(ctx) => {
* ctx.reply('Pong!');
* }
* });
* ```
*/
command(opts, code) {
if (typeof opts !== "string") return this.cmd?.set(this.cmd.size, opts);
if (!code) code = async () => {
return null;
};
return this.cmd?.set(this.cmd.size, { name: opts, code });
}
/**
* "Callback" will be triggered when someone sends the "query" in the chats. Hears function like command but without command prefix.
* @param query The trigger.
* @param callback Callback function
*/
hears(query, callback) {
this.hearsMap.set(this.hearsMap.size, { name: query, code: callback });
}
/**
* Set the bot bio/about.
* @param content The bio content.
*/
bio(content) {
this.core?.query({
tag: "iq",
attrs: {
to: "@s.whatsapp.net",
type: "set",
xmlns: "status"
},
content: [
{
tag: "status",
attrs: {},
content
}
]
});
}
/**
* Fetch bio/about from given Jid or if the param empty will fetch the bot bio/about.
* @param [jid] the jid.
*/
async fetchBio(jid) {
let decodedJid = decodeJid(jid ? jid : this.core?.user?.id);
let re = await this.core?.fetchStatus(decodedJid);
return re;
}
/**
* All the groups that the bot joins.
*/
async groups() {
return await this.core.groupFetchAllParticipating();
}
decodeJid(jid) {
return decodeJid(jid);
}
async launch() {
const { state, saveCreds } = await this.authAdapter;
this.state = state;
this.saveCreds = saveCreds;
const version = this.WAVersion ? this.WAVersion : this.fallbackWAVersion;
this.core = makeWASocket3({
logger: this.logger,
printQRInTerminal: this.printQRInTerminal,
auth: this.state,
browser: this.browser,
version,
qrTimeout: this.qrTimeout,
markOnlineOnConnect: this.markOnlineOnConnect
});
if (this.usePairingCode && !this.core.authState.creds.registered) {
this.consolefy?.setTag("pairing-code");
if (this.printQRInTerminal) {
this.consolefy?.error("If you are set the usePairingCode to true then you need to set printQRInTerminal to false.");
this.consolefy?.resetTag();
return;
}
if (!this.phoneNumber) {
this.consolefy?.error("The phoneNumber options are required if you are using usePairingCode.");
this.consolefy?.resetTag();
return;
}
this.phoneNumber = this.phoneNumber.replace(/[^0-9]/g, "");
if (!this.phoneNumber.length) {
this.consolefy?.error("Invalid phoneNumber.");
this.consolefy?.resetTag();
return;
}
if (!PHONENUMBER_MCC.some((v) => this.phoneNumber.startsWith(v))) {
this.consolefy?.error("phoneNumber format must be like: 62xxx (starts with the country code).");
this.consolefy?.resetTag();
return;
}
setTimeout(async () => {
const code = await this.core.requestPairingCode(this.phoneNumber);
this.consolefy?.info(`Pairing Code: ${code}`);
this.consolefy?.resetTag();
}, 3e3);
}
this.onConnectionUpdate();
this.onCredsUpdate();
this.onMessage();
this.onGroupParticipantsUpdate();
this.onGroupsJoin();
this.onCall();
}
};
// src/Classes/CommandHandler.ts
init_Functions();
import consolefy2 from "@mengkodingan/consolefy";
var CommandHandler = class {
_bot;
_path;
consolefy;
/**
* Create a new command handler instance
*
* ```ts
* import { CommandHandler } from "@mengkodingan/ckptw";
* import path from "path";
*
* const cmd = new CommandHandler(bot, path.resolve() + '/path/to/dir');
* cmd.load();
*
* ```
*
* @param bot The bot instance
* @param path A string that represent a path to commands directory. Recomended using `path` library.
*
* ```ts
* import path from "path";
* const cmd = new CommandHandler(bot, path.resolve() + '/path/to/dir');
* ```
*/
constructor(bot, path2) {
this._bot = bot;
this._path = path2;
this.consolefy = new consolefy2.Consolefy({ tag: "command-handler" });
}
async load(isShowLog = true) {
if (isShowLog) this.consolefy?.group("Command Handler Load");
const files = [];
walk(this._path, (filepath, stats) => {
files.push(filepath);
return {};
});
for (const filepath of files) {
try {
const module = await import(filepath);
const cmdObj = module.default || module;
if (!cmdObj.type || cmdObj.type === "command") {
this._bot.cmd.set(cmdObj.name, cmdObj);
if (isShowLog) this.consolefy?.success(`Loaded Command - ${cmdObj.name}`);
} else if (cmdObj.type === "hears") {
this._bot.hearsMap.set(cmdObj.name, cmdObj);
if (isShowLog) this.consolefy?.success(`Loaded Hears - ${cmdObj.name}`);
}
} catch (error) {
if (isShowLog) this.consolefy?.error(`Failed to load ${filepath}: ${error}`);
}
}
if (isShowLog) this.consolefy?.groupEnd();
}
};
// src/Classes/Builder/Button.ts
var ButtonBuilder = class {
id;
displayText;
type;
merhcant_url;
url;
copy_code;
constructor(opts) {
this.id = opts?.id || null;
this.displayText = opts?.displayText || null;
this.type = opts?.type || "quick_reply";
this.merhcant_url = opts?.merhcant_url || null;
this.url = opts?.url || null;
this.copy_code = opts?.copy_code || null;
}
setId(id) {
this.id = id;
return this;
}
setDisplayText(text) {
this.displayText = text;
return this;
}
setType(type = "quick_reply") {
this.type = type;
return this;
}
setMerchantURL(url) {
this.merhcant_url = url;
return this;
}
setURL(url) {
this.url = url;
return this;
}
setCopyCode(content) {
this.copy_code = content;
return this;
}
build() {
return {
name: this.type,
buttonParamsJson: JSON.stringify({ display_text: this.displayText, id: this.id, copy_code: this.copy_code, merhcant_url: this.merhcant_url, url: this.url })
};
}
};
// src/Classes/Builder/Sections.ts
var SectionsBuilder = class {
displayText;
sections;
constructor(opts) {
this.displayText = opts?.displayText || null;
this.sections = opts?.sections || [];
}
setDisplayText(text) {
this.displayText = text;
return this;
}
addSection(content) {
this.sections.push(content);
return this;
}
build() {
return {
name: "single_select",
buttonParamsJson: JSON.stringify({ title: this.displayText, sections: this.sections })
};
}
};
// src/Classes/Cooldown.ts
init_Functions();
import EventEmitter3 from "events";
var Cooldown = class extends EventEmitter3 {
ms;
cooldown;
timeout;
constructor(ctx, ms) {
super();
this.ms = ms;
this.cooldown = ctx._self.cooldown;
this.timeout = 0;
let q = `cooldown_${ctx._used.command}_${decodeJid(ctx._msg.key?.remoteJid)}_${decodeJid(ctx._sender.jid)}`;
const get = this.cooldown?.get(q);
if (get) {
this.timeout = Number(get) - Date.now();
} else {
this.cooldown?.set(q, Date.now() + ms);
setTimeout(() => {
this.cooldown?.delete(q);
this.emit("end");
}, ms);
}
}
get onCooldown() {
return this.timeout ? true : false;
}
get timeleft() {
return this.timeout;
}
};
// src/Classes/Builder/VCard.ts
var VCardBuilder = class {
fullName;
org;
number;
constructor(opts) {
this.fullName = opts?.fullName || null;
this.org = opts?.org || null;
this.number = opts?.number || null;
}
setFullName(fullName) {
if (!fullName) throw new Error("[ckptw] vcard builder need full name");
this.fullName = fullName;
return this;
}
setOrg(organizationName) {
if (!organizationName) throw new Error("[ckptw] vcard builder need organization name");
this.org = organizationName;
return this;
}
setNumber(number) {
if (!number) throw new Error("[ckptw] vcard builder need number");
this.number = number;
return this;
}
build() {
return `BEGIN:VCARD
VERSION:3.0
FN:${this.fullName}
ORG:${this.org};
TEL;type=CELL;type=VOICE;waid=${this.number?.replace(/\s/g, "")}:+${this.number}
END:VCARD`;
}
};
// src/Classes/Builder/TemplateButtons.ts
var TemplateButtonsBuilder = class {
array;
index;
constructor(opts) {
this.array = opts?.array || [];
this.index = 0;
}
addURL(opts) {
if (!opts.displayText || !opts.url) throw new Error("[ckptw] template button builder need url display text or url");
let index = this.index + 1;
this.array.push({ index, urlButton: { ...opts } });
this.index = index;
return this;
}
addCall(opts) {
if (!opts.displayText || !opts.phoneNumber) throw new Error("[ckptw] template button builder need call display text or phone number");
let index = this.index + 1;
this.array.push({ index, callButton: { ...opts } });
this.index = index;
return this;
}
addQuickReply(opts) {
if (!opts.displayText || !opts.id) throw new Error("[ckptw] template button builder need quick reply display text or id");
let index = this.index + 1;
this.array.push({ index, quickReplyButton: { ...opts } });
this.index = index;
return this;
}
build() {
return this.array;
}
};
// src/Classes/Builder/Carousel.ts
init_Functions();
var CarouselBuilder = class {
cards;
constructor(opts) {
this.cards = opts?.cards || [];
}
addCard(content) {
this.cards.push(makeRealInteractiveMessage(content));
return this;
}
build() {
return this.cards;
}
};
// src/index.ts
init_Group();
init_GroupData();
// src/Helper/Formatter.ts
var bold = (str) => {
return `*${str}*`;
};
var italic = (str) => {
return `_${str}_`;
};
var strikethrough = (str) => {
return `~${str}~`;
};
var quote = (str) => {
return `> ${str}`;
};
var monospace = (str) => {
return `\`\`\`${str}\`\`\``;
};
var inlineCode = (str) => {
return `\`${str}\``;
};
// src/index.ts
init_Ctx();
init_Collector();
init_MessageCollector();
init_Events();
export {
Browsers2 as Browsers,
ButtonBuilder,
CarouselBuilder,
Client,
Collector,
CommandHandler,
Cooldown,
Ctx,
Events,
Group,
GroupData,
MessageCollector,
MessageType,
SectionsBuilder,
TemplateButtonsBuilder,
VCardBuilder,
bold,
fetchLatestWaWebVersion,
inlineCode,
italic,
monospace,
quote,
strikethrough
};
//# sourceMappingURL=index.js.map