@gamastudio/sendwave-provider 0.0.2-dev
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.
- package/.claude/settings.local.json +9 -0
- package/.github/workflows/build.yml +31 -0
- package/README.md +374 -0
- package/build/constants/html/connect.d.ts +1 -0
- package/build/constants/html/connect.js +37 -0
- package/build/constants/html/error.d.ts +1 -0
- package/build/constants/html/error.js +42 -0
- package/build/constants/html/home.d.ts +1 -0
- package/build/constants/html/home.js +30 -0
- package/build/constants/svg/logo.d.ts +1 -0
- package/build/constants/svg/logo.js +4 -0
- package/build/constants/svg/wave-error.d.ts +1 -0
- package/build/constants/svg/wave-error.js +92 -0
- package/build/constants/svg/wave.d.ts +1 -0
- package/build/constants/svg/wave.js +92 -0
- package/build/core/interface/index.d.ts +3 -0
- package/build/core/interface/index.js +19 -0
- package/build/core/interface/parser.interface.d.ts +10 -0
- package/build/core/interface/parser.interface.js +2 -0
- package/build/core/interface/provider.interface.d.ts +16 -0
- package/build/core/interface/provider.interface.js +2 -0
- package/build/core/interface/types.d.ts +89 -0
- package/build/core/interface/types.js +2 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +12 -0
- package/build/package.json +48 -0
- package/build/provider/core.d.ts +22 -0
- package/build/provider/core.js +169 -0
- package/build/provider/index.d.ts +1 -0
- package/build/provider/index.js +17 -0
- package/build/provider/provider.d.ts +85 -0
- package/build/provider/provider.js +375 -0
- package/build/provider/sender.d.ts +16 -0
- package/build/provider/sender.js +203 -0
- package/build/utils/detectorMedia.d.ts +24 -0
- package/build/utils/detectorMedia.js +92 -0
- package/build/utils/parserMsg.d.ts +2 -0
- package/build/utils/parserMsg.js +104 -0
- package/build/utils/queueFlow.d.ts +36 -0
- package/build/utils/queueFlow.js +82 -0
- package/package.json +48 -0
- package/public/assets/logo.png +0 -0
- package/queue.class.log +0 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SendWaveCore = void 0;
|
|
4
|
+
const node_events_1 = require("node:events");
|
|
5
|
+
const parserMsg_1 = require("../utils/parserMsg");
|
|
6
|
+
const home_1 = require("../constants/html/home");
|
|
7
|
+
const connect_1 = require("../constants/html/connect");
|
|
8
|
+
const error_1 = require("../constants/html/error");
|
|
9
|
+
class SendWaveCore extends node_events_1.EventEmitter {
|
|
10
|
+
constructor(port, queue, globalVendorArgs) {
|
|
11
|
+
super();
|
|
12
|
+
this.codeQR = "";
|
|
13
|
+
this.indexHome = (_, res) => {
|
|
14
|
+
res.setHeader("Content-Type", "text/html");
|
|
15
|
+
res.end(home_1.htmlHome);
|
|
16
|
+
};
|
|
17
|
+
this.indexConnect = (_, res) => {
|
|
18
|
+
const html = (0, connect_1.htmlConnect)(this.codeQR);
|
|
19
|
+
res.setHeader("Content-Type", "text/html");
|
|
20
|
+
res.end(html);
|
|
21
|
+
};
|
|
22
|
+
this.indexError = (_, res) => {
|
|
23
|
+
res.setHeader("Content-Type", "text/html");
|
|
24
|
+
res.end((0, error_1.htmlError)("Failed to connect to Instance"));
|
|
25
|
+
};
|
|
26
|
+
this.handlerLocalMedia = (_, res) => {
|
|
27
|
+
res.end("Media handler not implemented yet");
|
|
28
|
+
};
|
|
29
|
+
this.emitQR = (qr) => {
|
|
30
|
+
this.codeQR = qr;
|
|
31
|
+
};
|
|
32
|
+
this.incomingMsg = (req, res) => {
|
|
33
|
+
var _a;
|
|
34
|
+
try {
|
|
35
|
+
const { body } = req;
|
|
36
|
+
if (!["messages.upsert", "send_message"].includes(body.event)) {
|
|
37
|
+
return res.end("Message queued");
|
|
38
|
+
}
|
|
39
|
+
const data = (0, parserMsg_1.parseIncomingMsg)(body);
|
|
40
|
+
if (!data)
|
|
41
|
+
return res.end("Message queued");
|
|
42
|
+
this.flowMessage(data);
|
|
43
|
+
if (!(data === null || data === void 0 ? void 0 : data.fromMe)) {
|
|
44
|
+
// Emit message event for queue flow system integration
|
|
45
|
+
this.emit("user-message", data);
|
|
46
|
+
if ((_a = this.globalVendorArgs.message) === null || _a === void 0 ? void 0 : _a.mergeMessage) {
|
|
47
|
+
this.bufferMessage(data);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
this.messageQueue.enqueue(() => this.processMessage(data));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return res.end("Message queued");
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
console.error("[IncomingMsg Error]:", e);
|
|
57
|
+
res.statusCode = 500;
|
|
58
|
+
return res.end("Internal Server Error");
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
this.messageBuffers = {};
|
|
62
|
+
this.port = port;
|
|
63
|
+
this.messageQueue = queue;
|
|
64
|
+
this.globalVendorArgs = globalVendorArgs;
|
|
65
|
+
}
|
|
66
|
+
processMessage(message) {
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
try {
|
|
69
|
+
this.emit("message", message);
|
|
70
|
+
resolve();
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
reject(error);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
bufferMessage(data) {
|
|
78
|
+
var _a;
|
|
79
|
+
const user = data.from;
|
|
80
|
+
const now = Date.now();
|
|
81
|
+
if (!this.messageBuffers[user]) {
|
|
82
|
+
this.messageBuffers[user] = {
|
|
83
|
+
messages: [],
|
|
84
|
+
messageTimeout: null,
|
|
85
|
+
maxWaitTimeout: null,
|
|
86
|
+
lastData: null,
|
|
87
|
+
lastMessageTime: now,
|
|
88
|
+
messageCount: 0,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
const buffer = this.messageBuffers[user];
|
|
92
|
+
buffer.messages.push(data.body);
|
|
93
|
+
buffer.lastData = data;
|
|
94
|
+
buffer.messageCount++;
|
|
95
|
+
// Calculate time between messages
|
|
96
|
+
const timeBetweenMessages = now - buffer.lastMessageTime;
|
|
97
|
+
buffer.lastMessageTime = now;
|
|
98
|
+
// Clear existing timeout
|
|
99
|
+
if (buffer.messageTimeout) {
|
|
100
|
+
clearTimeout(buffer.messageTimeout);
|
|
101
|
+
buffer.messageTimeout = null;
|
|
102
|
+
}
|
|
103
|
+
// Set max wait timeout only on first message
|
|
104
|
+
if (buffer.messages.length === 1) {
|
|
105
|
+
const maxWaitTime = ((_a = this.globalVendorArgs.message) === null || _a === void 0 ? void 0 : _a.maxWaitTime) || 30;
|
|
106
|
+
buffer.maxWaitTimeout = setTimeout(() => {
|
|
107
|
+
this.processBufferedMessages(user);
|
|
108
|
+
}, maxWaitTime * 1000);
|
|
109
|
+
}
|
|
110
|
+
// Smart timeout calculation
|
|
111
|
+
let timeout = this.calculateSmartTimeout(data.body, timeBetweenMessages, buffer.messageCount);
|
|
112
|
+
buffer.messageTimeout = setTimeout(() => {
|
|
113
|
+
this.processBufferedMessages(user);
|
|
114
|
+
}, timeout);
|
|
115
|
+
}
|
|
116
|
+
calculateSmartTimeout(messageText, timeBetweenMessages, messageCount) {
|
|
117
|
+
var _a, _b, _c, _d;
|
|
118
|
+
const baseTimeout = (((_a = this.globalVendorArgs.message) === null || _a === void 0 ? void 0 : _a.timeMergeMessage) || 3) * 1000;
|
|
119
|
+
const shortThreshold = ((_b = this.globalVendorArgs.message) === null || _b === void 0 ? void 0 : _b.shortMessageThreshold) || 10;
|
|
120
|
+
const adaptiveTimer = (_d = (_c = this.globalVendorArgs.message) === null || _c === void 0 ? void 0 : _c.adaptiveTimer) !== null && _d !== void 0 ? _d : true;
|
|
121
|
+
let timeout = baseTimeout;
|
|
122
|
+
// If message is very short, assume more are coming
|
|
123
|
+
if (messageText.length < shortThreshold) {
|
|
124
|
+
timeout = Math.max(1000, timeout * 0.5); // Reduce timeout by 50%
|
|
125
|
+
}
|
|
126
|
+
// If adaptive timer is enabled
|
|
127
|
+
if (adaptiveTimer) {
|
|
128
|
+
// If messages are coming very fast (< 2 seconds), extend timeout
|
|
129
|
+
if (timeBetweenMessages < 2000 && messageCount > 1) {
|
|
130
|
+
timeout = Math.max(timeout, 4000); // At least 4 seconds
|
|
131
|
+
}
|
|
132
|
+
// If it's the first few messages, be more aggressive
|
|
133
|
+
if (messageCount <= 2) {
|
|
134
|
+
timeout = Math.max(2000, timeout * 0.7); // Reduce by 30%
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return timeout;
|
|
138
|
+
}
|
|
139
|
+
processBufferedMessages(user) {
|
|
140
|
+
const buffer = this.messageBuffers[user];
|
|
141
|
+
if (!buffer || buffer.messages.length === 0)
|
|
142
|
+
return;
|
|
143
|
+
// Clear all timeouts
|
|
144
|
+
if (buffer.messageTimeout)
|
|
145
|
+
clearTimeout(buffer.messageTimeout);
|
|
146
|
+
if (buffer.maxWaitTimeout)
|
|
147
|
+
clearTimeout(buffer.maxWaitTimeout);
|
|
148
|
+
const fullMessage = buffer.messages.join(" ");
|
|
149
|
+
// Process the merged message
|
|
150
|
+
this.messageQueue.enqueue(() => this.processMessage({
|
|
151
|
+
...buffer.lastData,
|
|
152
|
+
body: fullMessage,
|
|
153
|
+
}));
|
|
154
|
+
// Clean up buffer
|
|
155
|
+
delete this.messageBuffers[user];
|
|
156
|
+
}
|
|
157
|
+
flowMessage(message) {
|
|
158
|
+
return new Promise((resolve, reject) => {
|
|
159
|
+
try {
|
|
160
|
+
this.emit("flow-message", message);
|
|
161
|
+
resolve();
|
|
162
|
+
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
reject(error);
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
exports.SendWaveCore = SendWaveCore;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './provider';
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./provider"), exports);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ProviderClass } from "@builderbot/bot";
|
|
2
|
+
import Queue from "queue-promise";
|
|
3
|
+
import { SendWaveCore } from "./core";
|
|
4
|
+
import { BotContext, BotCtxMiddlewareOptions } from "@builderbot/bot/dist/types";
|
|
5
|
+
import { GlobalVendorArgs } from "../core/interface/types";
|
|
6
|
+
import { SenderMessage } from "./sender";
|
|
7
|
+
import { ParsedMessage } from "../core/interface";
|
|
8
|
+
export declare class SendWaveProvider extends ProviderClass<SendWaveCore> {
|
|
9
|
+
queue: Queue;
|
|
10
|
+
vendor: SendWaveCore;
|
|
11
|
+
private sendwaveApi?;
|
|
12
|
+
state: Boolean;
|
|
13
|
+
instanceConnected: Boolean;
|
|
14
|
+
sender: SenderMessage;
|
|
15
|
+
globalVendorArgs: GlobalVendorArgs;
|
|
16
|
+
constructor(args: Partial<GlobalVendorArgs>);
|
|
17
|
+
protected initVendor(): Promise<any>;
|
|
18
|
+
protected beforeHttpServerInit: () => Promise<void>;
|
|
19
|
+
protected getApiQrConnect: () => Promise<void>;
|
|
20
|
+
protected afterHttpServerInit(): Promise<void>;
|
|
21
|
+
saveFile(_: any, options?: {
|
|
22
|
+
path: string;
|
|
23
|
+
}): Promise<string>;
|
|
24
|
+
createInstance(): void;
|
|
25
|
+
busEvents: () => ({
|
|
26
|
+
event: string;
|
|
27
|
+
func: (payload: BotContext) => void;
|
|
28
|
+
} | {
|
|
29
|
+
event: string;
|
|
30
|
+
func: (payload: ParsedMessage) => void;
|
|
31
|
+
})[];
|
|
32
|
+
listenOnEvents(vendor: SendWaveCore): Promise<void>;
|
|
33
|
+
sendFlow(data: {
|
|
34
|
+
event: string;
|
|
35
|
+
name: string;
|
|
36
|
+
from: string;
|
|
37
|
+
}): void;
|
|
38
|
+
initAll: (port: number, opts?: Pick<BotCtxMiddlewareOptions, "blacklist">) => void;
|
|
39
|
+
sendMessage(from: string, text: any, options?: any): Promise<any>;
|
|
40
|
+
sendText(...args: Parameters<SenderMessage["sendText"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
41
|
+
sendList(...args: Parameters<SenderMessage["sendList"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
42
|
+
sendImage(...args: Parameters<SenderMessage["sendImage"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
43
|
+
sendVideo(...args: Parameters<SenderMessage["sendVideo"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
44
|
+
sendAudio(...args: Parameters<SenderMessage["sendAudio"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
45
|
+
sendFile(...args: Parameters<SenderMessage["sendFile"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
46
|
+
sendPresence(...args: Parameters<SenderMessage["sendPresence"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
47
|
+
sendVoice(...args: Parameters<SenderMessage["sendVoice"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
48
|
+
sendButton(...args: Parameters<SenderMessage["sendButton"]>): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
49
|
+
/**
|
|
50
|
+
* Reset user timeout for queue flow system
|
|
51
|
+
*/
|
|
52
|
+
resetUserTimeout(from: string, name?: string): {
|
|
53
|
+
isActive: boolean;
|
|
54
|
+
from: string;
|
|
55
|
+
name: string | undefined;
|
|
56
|
+
} | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Clear user timeout manually
|
|
59
|
+
*/
|
|
60
|
+
clearUserTimeout(from: string): void;
|
|
61
|
+
/**
|
|
62
|
+
* Force clear all user data from queue flow
|
|
63
|
+
*/
|
|
64
|
+
forceClearUser(from: string): void;
|
|
65
|
+
/**
|
|
66
|
+
* Check if user is ignored by queue flow system
|
|
67
|
+
*/
|
|
68
|
+
isUserIgnored(from: string): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Get queue flow statistics
|
|
71
|
+
*/
|
|
72
|
+
getQueueFlowStats(): {
|
|
73
|
+
activeTimeouts: number;
|
|
74
|
+
ignoredUsers: number;
|
|
75
|
+
config: Required<import("../utils/queueFlow").QueueFlowConfig>;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Listen to queue flow events
|
|
79
|
+
*/
|
|
80
|
+
onQueueFlowEvent(event: string, callback: (data: any) => void): void;
|
|
81
|
+
/**
|
|
82
|
+
* Remove queue flow event listeners
|
|
83
|
+
*/
|
|
84
|
+
offQueueFlowEvent(event: string, callback?: (data: any) => void): void;
|
|
85
|
+
}
|
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SendWaveProvider = void 0;
|
|
7
|
+
const bot_1 = require("@builderbot/bot");
|
|
8
|
+
const queue_promise_1 = __importDefault(require("queue-promise"));
|
|
9
|
+
const core_1 = require("./core");
|
|
10
|
+
const axios_1 = __importDefault(require("axios"));
|
|
11
|
+
const https_1 = require("https");
|
|
12
|
+
const sender_1 = require("./sender");
|
|
13
|
+
const detectorMedia_1 = require("../utils/detectorMedia");
|
|
14
|
+
const queueFlow_1 = require("../utils/queueFlow");
|
|
15
|
+
const body_parser_1 = __importDefault(require("body-parser"));
|
|
16
|
+
const cors_1 = __importDefault(require("cors"));
|
|
17
|
+
const sirv_1 = __importDefault(require("sirv"));
|
|
18
|
+
const assets = (0, sirv_1.default)("public/assets", { dev: true });
|
|
19
|
+
class SendWaveProvider extends bot_1.ProviderClass {
|
|
20
|
+
constructor(args) {
|
|
21
|
+
var _a;
|
|
22
|
+
super();
|
|
23
|
+
this.queue = new queue_promise_1.default();
|
|
24
|
+
this.state = false;
|
|
25
|
+
this.instanceConnected = false;
|
|
26
|
+
this.globalVendorArgs = {
|
|
27
|
+
name: "bot",
|
|
28
|
+
url: "https://sendwave-api.gamastudio.co",
|
|
29
|
+
port: 3000,
|
|
30
|
+
apiKey: "",
|
|
31
|
+
delay: 0,
|
|
32
|
+
linkPreview: true,
|
|
33
|
+
message: {
|
|
34
|
+
mergeMessage: false,
|
|
35
|
+
timeMergeMessage: 3,
|
|
36
|
+
},
|
|
37
|
+
queueFlow: {
|
|
38
|
+
enabled: false,
|
|
39
|
+
warningTimeout: 30 * 60 * 1000, // 30 minutes
|
|
40
|
+
endTimeout: 2 * 60 * 1000, // 2 minutes
|
|
41
|
+
warningMessage: "⏳ Parece que has estado inactivo. ¿Sigues ahí?",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
this.beforeHttpServerInit = async () => {
|
|
45
|
+
this.server = this.server
|
|
46
|
+
.use(body_parser_1.default.json())
|
|
47
|
+
.use((req, _, next) => {
|
|
48
|
+
req["globalVendorArgs"] = this.globalVendorArgs;
|
|
49
|
+
return next();
|
|
50
|
+
})
|
|
51
|
+
.use((0, cors_1.default)({ origin: "*", methods: "GET,POST" }))
|
|
52
|
+
.use("/assets", assets)
|
|
53
|
+
.get("/", async (req, res) => {
|
|
54
|
+
if (this.state && this.instanceConnected) {
|
|
55
|
+
await this.afterHttpServerInit();
|
|
56
|
+
return this.vendor.indexHome(req, res);
|
|
57
|
+
}
|
|
58
|
+
else if (!this.state && this.instanceConnected) {
|
|
59
|
+
await this.afterHttpServerInit();
|
|
60
|
+
this.getApiQrConnect();
|
|
61
|
+
return this.vendor.indexConnect(req, res);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
}
|
|
65
|
+
return this.vendor.indexError(req, res);
|
|
66
|
+
})
|
|
67
|
+
.post("/webhook", this.vendor.incomingMsg);
|
|
68
|
+
};
|
|
69
|
+
this.getApiQrConnect = async () => {
|
|
70
|
+
var _a;
|
|
71
|
+
try {
|
|
72
|
+
const { data } = await ((_a = this.sendwaveApi) === null || _a === void 0 ? void 0 : _a.get(`/instance/connect/${this.globalVendorArgs.name}`));
|
|
73
|
+
this.vendor.emitQR(data === null || data === void 0 ? void 0 : data.base64);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.log(error === null || error === void 0 ? void 0 : error.response.data);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
this.busEvents = () => [
|
|
81
|
+
{
|
|
82
|
+
event: "auth_failure",
|
|
83
|
+
func: (payload) => this.emit("auth_failure", payload),
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
event: "notice",
|
|
87
|
+
func: ({ instructions, title }) => this.emit("notice", { instructions, title }),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
event: "ready",
|
|
91
|
+
func: () => this.emit("ready", true),
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
event: "message",
|
|
95
|
+
func: (payload) => {
|
|
96
|
+
var _a;
|
|
97
|
+
// Auto-reset timeout for queue flow when user sends a message (AUTOMATIC)
|
|
98
|
+
if (((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled) && !payload.from.includes("@")) {
|
|
99
|
+
this.resetUserTimeout(payload.from, payload.name);
|
|
100
|
+
}
|
|
101
|
+
this.emit("message", payload);
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
event: "flow-message",
|
|
106
|
+
func: (payload) => {
|
|
107
|
+
this.emit("flow-message", payload);
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
event: "host",
|
|
112
|
+
func: (payload) => {
|
|
113
|
+
this.emit("host", payload);
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
this.initAll = (port, opts) => {
|
|
118
|
+
this.globalVendorArgs.port = port;
|
|
119
|
+
const methods = {
|
|
120
|
+
sendMessage: this.sendMessage,
|
|
121
|
+
sendList: this.sendList,
|
|
122
|
+
sendText: this.sendText,
|
|
123
|
+
sendImage: this.sendImage,
|
|
124
|
+
sendVideo: this.sendVideo,
|
|
125
|
+
sendAudio: this.sendAudio,
|
|
126
|
+
sendFile: this.sendFile,
|
|
127
|
+
sendVoice: this.sendVoice,
|
|
128
|
+
sendPresence: this.sendPresence,
|
|
129
|
+
sendButton: this.sendButton,
|
|
130
|
+
provider: this,
|
|
131
|
+
blacklist: opts === null || opts === void 0 ? void 0 : opts.blacklist,
|
|
132
|
+
dispatch: (customEvent, payload) => {
|
|
133
|
+
this.emit("message", {
|
|
134
|
+
...payload,
|
|
135
|
+
body: bot_1.utils.setEvent(customEvent),
|
|
136
|
+
name: payload.name,
|
|
137
|
+
from: bot_1.utils.removePlus(payload.from),
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
this.initVendor()
|
|
142
|
+
.then((v) => this.listenOnEvents(v))
|
|
143
|
+
.then(() => {
|
|
144
|
+
this.beforeHttpServerInit();
|
|
145
|
+
this.start(methods, (routes) => {
|
|
146
|
+
this.emit("notice", {
|
|
147
|
+
title: "🛜 HTTP Server ON ",
|
|
148
|
+
instructions: routes,
|
|
149
|
+
});
|
|
150
|
+
this.afterHttpServerInit();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
return;
|
|
154
|
+
};
|
|
155
|
+
const cleanArgs = Object.fromEntries(Object.entries(args).filter(([_, v]) => v !== undefined));
|
|
156
|
+
this.globalVendorArgs = { ...this.globalVendorArgs, ...cleanArgs };
|
|
157
|
+
this.queue = new queue_promise_1.default({
|
|
158
|
+
concurrent: 50,
|
|
159
|
+
interval: 100,
|
|
160
|
+
start: true,
|
|
161
|
+
});
|
|
162
|
+
// Initialize queue flow system if enabled
|
|
163
|
+
if ((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled) {
|
|
164
|
+
queueFlow_1.queueFlow.updateConfig({
|
|
165
|
+
warningTimeout: this.globalVendorArgs.queueFlow.warningTimeout,
|
|
166
|
+
endTimeout: this.globalVendorArgs.queueFlow.endTimeout,
|
|
167
|
+
warningMessage: this.globalVendorArgs.queueFlow.warningMessage,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
this.createInstance();
|
|
171
|
+
this.on("ready", (isReady) => {
|
|
172
|
+
console.log("Instance connection status:", isReady ? "Connected to server" : "Disconnected from server");
|
|
173
|
+
// Puedes emitir eventos a websockets aquí, notificar a frontends, etc.
|
|
174
|
+
});
|
|
175
|
+
this.sender = new sender_1.SenderMessage(this.globalVendorArgs);
|
|
176
|
+
}
|
|
177
|
+
initVendor() {
|
|
178
|
+
const vendor = new core_1.SendWaveCore(this.globalVendorArgs.port, this.queue, this.globalVendorArgs);
|
|
179
|
+
this.vendor = vendor;
|
|
180
|
+
return Promise.resolve(this.vendor);
|
|
181
|
+
}
|
|
182
|
+
async afterHttpServerInit() {
|
|
183
|
+
var _a, _b, _c;
|
|
184
|
+
try {
|
|
185
|
+
await ((_a = this.sendwaveApi) === null || _a === void 0 ? void 0 : _a.get(`/instance/connectionState/${this.globalVendorArgs.name}`).then((res) => {
|
|
186
|
+
var _a;
|
|
187
|
+
const data = res.data;
|
|
188
|
+
if (((_a = data === null || data === void 0 ? void 0 : data.instance) === null || _a === void 0 ? void 0 : _a.state) === "open") {
|
|
189
|
+
this.instanceConnected = true;
|
|
190
|
+
this.state = true;
|
|
191
|
+
this.emit("ready", true);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
this.instanceConnected = true;
|
|
195
|
+
this.emit("ready", false);
|
|
196
|
+
this.getApiQrConnect();
|
|
197
|
+
this.state = false;
|
|
198
|
+
}
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
this.instanceConnected = false;
|
|
203
|
+
this.emit("auth_failure", {
|
|
204
|
+
instructions: `Error al autenticar: ${(_c = (_b = error === null || error === void 0 ? void 0 : error.response) === null || _b === void 0 ? void 0 : _b.data) === null || _c === void 0 ? void 0 : _c.error}`,
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
saveFile(_, options) {
|
|
209
|
+
return new Promise((resolve, reject) => {
|
|
210
|
+
try {
|
|
211
|
+
const { path } = options || { path: "" };
|
|
212
|
+
resolve(path);
|
|
213
|
+
}
|
|
214
|
+
catch (e) {
|
|
215
|
+
reject(e);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
createInstance() {
|
|
220
|
+
var _a;
|
|
221
|
+
const url = typeof ((_a = this.globalVendorArgs) === null || _a === void 0 ? void 0 : _a.url) === "string" &&
|
|
222
|
+
this.globalVendorArgs.url.trim()
|
|
223
|
+
? this.globalVendorArgs.url.trim()
|
|
224
|
+
: "https://sendwave-api.gamastudio.co";
|
|
225
|
+
this.sendwaveApi = axios_1.default.create({
|
|
226
|
+
baseURL: url,
|
|
227
|
+
httpsAgent: new https_1.Agent({ rejectUnauthorized: false }),
|
|
228
|
+
headers: {
|
|
229
|
+
"Content-Type": "application/json",
|
|
230
|
+
apikey: this.globalVendorArgs.apiKey,
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
async listenOnEvents(vendor) {
|
|
235
|
+
const listEvents = this.busEvents();
|
|
236
|
+
for (const { event, func } of listEvents) {
|
|
237
|
+
vendor.on(event, func);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
sendFlow(data) {
|
|
241
|
+
this.emit("message", {
|
|
242
|
+
body: bot_1.utils.setEvent(data.event),
|
|
243
|
+
name: data.name,
|
|
244
|
+
from: data.from,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async sendMessage(from, text, options) {
|
|
248
|
+
options = { ...options["options"] };
|
|
249
|
+
let mss = { from, text, options };
|
|
250
|
+
if (options.media) {
|
|
251
|
+
const { media, mediaType, fileName } = await detectorMedia_1.detectorMedia.processMedia(options.media);
|
|
252
|
+
switch (mediaType) {
|
|
253
|
+
case "image":
|
|
254
|
+
return await this.sender.sendImage({
|
|
255
|
+
...mss,
|
|
256
|
+
url: media,
|
|
257
|
+
text: text,
|
|
258
|
+
});
|
|
259
|
+
case "video":
|
|
260
|
+
return await this.sender.sendVideo({
|
|
261
|
+
...mss,
|
|
262
|
+
url: media,
|
|
263
|
+
text: text,
|
|
264
|
+
});
|
|
265
|
+
case "audio":
|
|
266
|
+
return await this.sender.sendVoice({ ...mss, url: media });
|
|
267
|
+
case "document":
|
|
268
|
+
return await this.sender.sendFile({
|
|
269
|
+
...mss,
|
|
270
|
+
url: media,
|
|
271
|
+
fileName,
|
|
272
|
+
text: text,
|
|
273
|
+
});
|
|
274
|
+
default:
|
|
275
|
+
return await this.sender.sendText(mss);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
return await this.sender.sendText(mss);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
// Métodos de conveniencia para mantener la API limpia
|
|
283
|
+
sendText(...args) {
|
|
284
|
+
return this.sender.sendText(...args);
|
|
285
|
+
}
|
|
286
|
+
sendList(...args) {
|
|
287
|
+
return this.sender.sendList(...args);
|
|
288
|
+
}
|
|
289
|
+
sendImage(...args) {
|
|
290
|
+
return this.sender.sendImage(...args);
|
|
291
|
+
}
|
|
292
|
+
sendVideo(...args) {
|
|
293
|
+
return this.sender.sendVideo(...args);
|
|
294
|
+
}
|
|
295
|
+
sendAudio(...args) {
|
|
296
|
+
return this.sender.sendAudio(...args);
|
|
297
|
+
}
|
|
298
|
+
sendFile(...args) {
|
|
299
|
+
return this.sender.sendFile(...args);
|
|
300
|
+
}
|
|
301
|
+
sendPresence(...args) {
|
|
302
|
+
return this.sender.sendPresence(...args);
|
|
303
|
+
}
|
|
304
|
+
sendVoice(...args) {
|
|
305
|
+
return this.sender.sendVoice(...args);
|
|
306
|
+
}
|
|
307
|
+
sendButton(...args) {
|
|
308
|
+
return this.sender.sendButton(...args);
|
|
309
|
+
}
|
|
310
|
+
// Queue Flow Management Methods
|
|
311
|
+
/**
|
|
312
|
+
* Reset user timeout for queue flow system
|
|
313
|
+
*/
|
|
314
|
+
resetUserTimeout(from, name) {
|
|
315
|
+
var _a;
|
|
316
|
+
if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
317
|
+
return;
|
|
318
|
+
return queueFlow_1.queueFlow.resetUserTimeout({
|
|
319
|
+
provider: this,
|
|
320
|
+
from,
|
|
321
|
+
name,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Clear user timeout manually
|
|
326
|
+
*/
|
|
327
|
+
clearUserTimeout(from) {
|
|
328
|
+
var _a;
|
|
329
|
+
if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
330
|
+
return;
|
|
331
|
+
queueFlow_1.queueFlow.clearUserTimeout(from);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Force clear all user data from queue flow
|
|
335
|
+
*/
|
|
336
|
+
forceClearUser(from) {
|
|
337
|
+
var _a;
|
|
338
|
+
if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
339
|
+
return;
|
|
340
|
+
queueFlow_1.queueFlow.forceClearUser(from);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Check if user is ignored by queue flow system
|
|
344
|
+
*/
|
|
345
|
+
isUserIgnored(from) {
|
|
346
|
+
var _a;
|
|
347
|
+
if (!((_a = this.globalVendorArgs.queueFlow) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
348
|
+
return false;
|
|
349
|
+
return queueFlow_1.queueFlow.isUserIgnored(from);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Get queue flow statistics
|
|
353
|
+
*/
|
|
354
|
+
getQueueFlowStats() {
|
|
355
|
+
return queueFlow_1.queueFlow.getUserStats();
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Listen to queue flow events
|
|
359
|
+
*/
|
|
360
|
+
onQueueFlowEvent(event, callback) {
|
|
361
|
+
queueFlow_1.queueFlow.on(event, callback);
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Remove queue flow event listeners
|
|
365
|
+
*/
|
|
366
|
+
offQueueFlowEvent(event, callback) {
|
|
367
|
+
if (callback) {
|
|
368
|
+
queueFlow_1.queueFlow.off(event, callback);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
queueFlow_1.queueFlow.removeAllListeners(event);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
exports.SendWaveProvider = SendWaveProvider;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { GlobalVendorArgs, ProviderInterface, SendButton, SendList, SendMedia, SendMessage, SendPresence } from "../core/interface";
|
|
2
|
+
export declare class SenderMessage implements ProviderInterface {
|
|
3
|
+
private sendwaveApi?;
|
|
4
|
+
private globalVendorArgs?;
|
|
5
|
+
constructor(args: Partial<GlobalVendorArgs>);
|
|
6
|
+
sendPresence(data: SendPresence): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
7
|
+
sendText(data: SendMessage): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
8
|
+
sendList(data: SendList): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
9
|
+
sendMedia(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
10
|
+
sendFile(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
11
|
+
sendImage(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
12
|
+
sendAudio(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
13
|
+
sendVideo(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
14
|
+
sendVoice(data: SendMedia): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
15
|
+
sendButton(data: SendButton): Promise<import("axios").AxiosResponse<any, any, {}> | undefined>;
|
|
16
|
+
}
|