@roidev/kachina-md 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,120 @@
1
+ import { downloadMediaMessage, getContentType } from 'baileys';
2
+ import { fileTypeFromBuffer } from 'file-type';
3
+
4
+ export async function serialize(msg, sock) {
5
+ if (!msg) return msg;
6
+
7
+ const m = {};
8
+
9
+ // Basic info
10
+ m.key = msg.key;
11
+ m.chat = msg.key.remoteJid;
12
+ m.fromMe = msg.key.fromMe;
13
+ m.id = msg.key.id;
14
+ m.isGroup = m.chat.endsWith('@g.us');
15
+ m.sender = m.isGroup ? msg.key.participant : m.chat;
16
+ m.pushName = msg.pushName || '';
17
+
18
+ // Message type
19
+ const type = getContentType(msg.message);
20
+ m.type = type;
21
+ m.message = msg.message;
22
+
23
+ // Get message body
24
+ m.body = getBody(msg.message);
25
+
26
+ // Get quoted message
27
+ const quoted = msg.message?.[type]?.contextInfo?.quotedMessage;
28
+ if (quoted) {
29
+ m.quoted = await serialize({
30
+ key: {
31
+ remoteJid: m.chat,
32
+ fromMe: msg.message[type].contextInfo.participant === sock.user.id,
33
+ id: msg.message[type].contextInfo.stanzaId,
34
+ participant: msg.message[type].contextInfo.participant
35
+ },
36
+ message: quoted,
37
+ pushName: msg.message[type].contextInfo.pushName || ''
38
+ }, sock);
39
+ }
40
+
41
+ // Media info
42
+ if (type && msg.message[type]) {
43
+ const msgContent = msg.message[type];
44
+ m.caption = msgContent.caption || '';
45
+ m.mimetype = msgContent.mimetype || '';
46
+ m.fileSize = msgContent.fileLength || msgContent.fileSha256 || 0;
47
+ }
48
+
49
+ // Mentions
50
+ m.mentions = msg.message?.[type]?.contextInfo?.mentionedJid || [];
51
+
52
+ // Helper methods
53
+ m.reply = async (text, options = {}) => {
54
+ return await sock.sendMessage(m.chat, { text, ...options }, { quoted: msg });
55
+ };
56
+
57
+ m.react = async (emoji) => {
58
+ return await sock.sendMessage(m.chat, {
59
+ react: { text: emoji, key: m.key }
60
+ });
61
+ };
62
+
63
+ m.download = async () => {
64
+ if (!msg.message) return null;
65
+ try {
66
+ const buffer = await downloadMediaMessage(msg, 'buffer', {});
67
+ return buffer;
68
+ } catch (error) {
69
+ console.error('Download error:', error);
70
+ return null;
71
+ }
72
+ };
73
+
74
+ m.delete = async () => {
75
+ return await sock.sendMessage(m.chat, { delete: m.key });
76
+ };
77
+
78
+ m.forward = async (jid, options = {}) => {
79
+ return await sock.sendMessage(jid, { forward: msg }, options);
80
+ };
81
+
82
+ m.copyNForward = async (jid, options = {}) => {
83
+ return await sock.copyNForward(jid, msg, options);
84
+ };
85
+
86
+ return m;
87
+ }
88
+
89
+ function getBody(message) {
90
+ if (!message) return '';
91
+
92
+ const type = getContentType(message);
93
+ if (!type) return '';
94
+
95
+ const content = message[type];
96
+
97
+ // Text messages
98
+ if (type === 'conversation') return content;
99
+ if (type === 'extendedTextMessage') return content.text;
100
+
101
+ // Button responses
102
+ if (type === 'buttonsResponseMessage') return content.selectedButtonId;
103
+ if (type === 'templateButtonReplyMessage') return content.selectedId;
104
+ if (type === 'listResponseMessage') return content.singleSelectReply?.selectedRowId;
105
+ if (type === 'interactiveResponseMessage') {
106
+ try {
107
+ const response = JSON.parse(content.nativeFlowResponseMessage?.paramsJson || '{}');
108
+ return response.id || '';
109
+ } catch {
110
+ return '';
111
+ }
112
+ }
113
+
114
+ // Media messages with caption
115
+ if (content.caption) return content.caption;
116
+
117
+ return '';
118
+ }
119
+
120
+ export default serialize;
@@ -0,0 +1,72 @@
1
+ import { Sticker, StickerTypes } from 'wa-sticker-formatter';
2
+
3
+ /**
4
+ * Create sticker from image/video buffer
5
+ * @param {Buffer} buffer - Image or video buffer
6
+ * @param {Object} options - Sticker options
7
+ * @returns {Promise<Buffer>} Sticker buffer
8
+ */
9
+ export async function createSticker(buffer, options = {}) {
10
+ const sticker = new Sticker(buffer, {
11
+ pack: options.pack || 'Sticker',
12
+ author: options.author || 'Kachina Bot',
13
+ type: options.type || StickerTypes.DEFAULT,
14
+ categories: options.categories || [],
15
+ id: options.id || '',
16
+ quality: options.quality || 50,
17
+ background: options.background || 'transparent'
18
+ });
19
+
20
+ return await sticker.toBuffer();
21
+ }
22
+
23
+ /**
24
+ * Create full sticker (no crop)
25
+ */
26
+ export async function createFullSticker(buffer, options = {}) {
27
+ return await createSticker(buffer, {
28
+ ...options,
29
+ type: StickerTypes.FULL
30
+ });
31
+ }
32
+
33
+ /**
34
+ * Create cropped sticker
35
+ */
36
+ export async function createCroppedSticker(buffer, options = {}) {
37
+ return await createSticker(buffer, {
38
+ ...options,
39
+ type: StickerTypes.CROPPED
40
+ });
41
+ }
42
+
43
+ /**
44
+ * Create circle sticker
45
+ */
46
+ export async function createCircleSticker(buffer, options = {}) {
47
+ return await createSticker(buffer, {
48
+ ...options,
49
+ type: StickerTypes.CIRCLE
50
+ });
51
+ }
52
+
53
+ /**
54
+ * Create rounded sticker
55
+ */
56
+ export async function createRoundedSticker(buffer, options = {}) {
57
+ return await createSticker(buffer, {
58
+ ...options,
59
+ type: StickerTypes.ROUNDED
60
+ });
61
+ }
62
+
63
+ export { StickerTypes };
64
+
65
+ export default {
66
+ createSticker,
67
+ createFullSticker,
68
+ createCroppedSticker,
69
+ createCircleSticker,
70
+ createRoundedSticker,
71
+ StickerTypes
72
+ };
package/lib/index.js ADDED
@@ -0,0 +1,30 @@
1
+ // Main exports
2
+ export { Client } from './client/Client.js';
3
+ export { PluginHandler } from './handlers/PluginHandler.js';
4
+
5
+ // Helpers
6
+ export {
7
+ serialize,
8
+ Database,
9
+ Logger,
10
+ createSticker,
11
+ createFullSticker,
12
+ createCroppedSticker,
13
+ createCircleSticker,
14
+ createRoundedSticker,
15
+ StickerTypes,
16
+ sleep,
17
+ formatTime,
18
+ formatBytes,
19
+ parseCommand,
20
+ isUrl,
21
+ extractUrls,
22
+ randomString,
23
+ randomNumber,
24
+ pickRandom,
25
+ chunk
26
+ } from './helpers/index.js';
27
+
28
+ // Default export
29
+ import { Client } from './client/Client.js';
30
+ export default Client;
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@roidev/kachina-md",
3
+ "version": "1.0.0",
4
+ "description": "WhatsApp Bot Framework - Simple, Fast, and Modular",
5
+ "main": "lib/index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "node build.js",
9
+ "test": "node examples/basic-bot.js",
10
+ "prepublishOnly": "npm run build"
11
+ },
12
+ "keywords": [
13
+ "whatsapp",
14
+ "bot",
15
+ "baileys",
16
+ "wa-bot",
17
+ "whatsapp-bot",
18
+ "framework",
19
+ "kachina"
20
+ ],
21
+ "author": "Roynaldi",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/your-username/kachina-core.git"
26
+ },
27
+ "bugs": {
28
+ "url": "https://github.com/your-username/kachina-core/issues"
29
+ },
30
+ "homepage": "https://github.com/your-username/kachina-core#readme",
31
+ "dependencies": {
32
+ "@hapi/boom": "^10.0.1",
33
+ "axios": "^1.6.0",
34
+ "baileys": "npm:@whiskeysockets/baileys@latest",
35
+ "chalk": "^5.3.0",
36
+ "file-type": "^18.7.0",
37
+ "fs-extra": "^11.2.0",
38
+ "lowdb": "^7.0.1",
39
+ "node-cache": "^5.1.2",
40
+ "pino": "^8.16.0",
41
+ "qrcode-terminal": "^0.12.0",
42
+ "sharp": "^0.33.0",
43
+ "wa-sticker-formatter": "^4.4.4"
44
+ },
45
+ "devDependencies": {
46
+ "gradient-string": "^2.0.2"
47
+ },
48
+ "engines": {
49
+ "node": ">=16.0.0"
50
+ },
51
+ "exports": {
52
+ ".": {
53
+ "import": "./lib/index.js"
54
+ },
55
+ "./plugins": {
56
+ "import": "./lib/plugins/index.js"
57
+ },
58
+ "./helpers": {
59
+ "import": "./lib/helpers/index.js"
60
+ }
61
+ },
62
+ "files": [
63
+ "lib/**/*",
64
+ "README.md",
65
+ "LICENSE"
66
+ ]
67
+ }