@wabot-dev/framework 0.5.13 → 0.5.15
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/dist/src/addon/auth/api-key/PgApiKeyRepository.js +1 -1
- package/dist/src/addon/chat-bot/openrouter/OpenRouterChatAdapter.js +158 -0
- package/dist/src/addon/chat-controller/telegram/TelegramChannel.js +1 -0
- package/dist/src/core/error/CustomError.js +11 -1
- package/dist/src/core/logger/Logger.js +2 -5
- package/dist/src/core/validation/validators/is-boolean/@isBoolean.js +1 -1
- package/dist/src/feature/async/Async.js +6 -1
- package/dist/src/feature/async/Job.js +8 -9
- package/dist/src/feature/async/JobExecutor.js +5 -2
- package/dist/src/feature/async/JobRunner.js +7 -2
- package/dist/src/feature/rest-controller/runRestControllers.js +3 -7
- package/dist/src/feature/socket-controller/runSocketControllers.js +3 -7
- package/dist/src/index.d.ts +16 -1
- package/dist/src/index.js +2 -1
- package/package.json +3 -2
- package/dist/src/addon/chat-controller/whatsapp-by-wasender/@whatsAppByWasender.js +0 -20
- package/dist/src/addon/chat-controller/whatsapp-by-wasender/WhatsAppByWasenderChannel.js +0 -52
- package/dist/src/addon/chat-controller/whatsapp-by-wasender/WhatsAppByWasenderChannelConfig.js +0 -16
- package/dist/src/addon/chat-controller/whatsapp-by-wasender/WhatsAppReceiverByWasender.js +0 -106
- package/dist/src/addon/chat-controller/whatsapp-by-wasender/WhatsAppSenderByWasender.js +0 -40
- package/dist/src/addon/chat-controller/whatsapp-by-wasender/extractNumberFromWasenderKey.js +0 -5
|
@@ -2,12 +2,12 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { PgCrudRepository } from '../../../feature/pg/PgCrudRepository.js';
|
|
3
3
|
import '../../../feature/pg/PgLocker.js';
|
|
4
4
|
import 'debug';
|
|
5
|
+
import { CustomError } from '../../../core/error/CustomError.js';
|
|
5
6
|
import 'node:crypto';
|
|
6
7
|
import '../../../feature/pg/withPgClient.js';
|
|
7
8
|
import '../../../feature/pg/pgStorage.js';
|
|
8
9
|
import { Pool } from 'pg';
|
|
9
10
|
import { ApiKey } from './ApiKey.js';
|
|
10
|
-
import { CustomError } from '../../../core/error/CustomError.js';
|
|
11
11
|
import '../../../core/error/setupErrorHandlers.js';
|
|
12
12
|
import { singleton } from '../../../core/injection/index.js';
|
|
13
13
|
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import { Env } from '../../../core/env/Env.js';
|
|
3
|
+
import { singleton } from '../../../core/injection/index.js';
|
|
4
|
+
import { Logger } from '../../../core/logger/Logger.js';
|
|
5
|
+
import '../../../feature/chat-bot/ChatBot.js';
|
|
6
|
+
import 'uuid';
|
|
7
|
+
import '../../../feature/chat-bot/metadata/ChatBotMetadataStore.js';
|
|
8
|
+
import '../../../core/error/setupErrorHandlers.js';
|
|
9
|
+
import { extractChatMessageText } from '../../../feature/chat-bot/extractChatMessageText.js';
|
|
10
|
+
import { OpenRouter } from '@openrouter/sdk';
|
|
11
|
+
|
|
12
|
+
let OpenRouterChatAdapter = class OpenRouterChatAdapter {
|
|
13
|
+
env;
|
|
14
|
+
openRouter;
|
|
15
|
+
logger = new Logger('wabot:openrouter-chat-adapter');
|
|
16
|
+
constructor(env) {
|
|
17
|
+
this.env = env;
|
|
18
|
+
const apiKey = this.env.requireString('OPENROUTER_API_KEY');
|
|
19
|
+
this.openRouter = new OpenRouter({ apiKey });
|
|
20
|
+
}
|
|
21
|
+
async nextItems(req) {
|
|
22
|
+
const messages = [];
|
|
23
|
+
messages.push({ role: 'system', content: req.systemPrompt });
|
|
24
|
+
messages.push(...this.mapChatItems(req.prevItems));
|
|
25
|
+
const tools = req.tools.map((x) => this.mapTool(x));
|
|
26
|
+
this.logger.debug(`Call OpenRouter with model: ${req.model}, messages: ${messages.length}, tools: ${tools.length}`);
|
|
27
|
+
const response = await this.openRouter.chat.send({
|
|
28
|
+
chatRequest: {
|
|
29
|
+
model: req.model,
|
|
30
|
+
messages,
|
|
31
|
+
tools: tools.length > 0 ? tools : undefined,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
return this.mapResponse(response);
|
|
35
|
+
}
|
|
36
|
+
mapChatItems(chatItems) {
|
|
37
|
+
const messages = [];
|
|
38
|
+
for (const chatItem of chatItems) {
|
|
39
|
+
switch (chatItem.type) {
|
|
40
|
+
case 'humanMessage':
|
|
41
|
+
messages.push(this.mapHumanMessage(chatItem.humanMessage));
|
|
42
|
+
break;
|
|
43
|
+
case 'botMessage':
|
|
44
|
+
messages.push(this.mapBotMessage(chatItem.botMessage));
|
|
45
|
+
break;
|
|
46
|
+
case 'functionCall':
|
|
47
|
+
messages.push(...this.mapFunctionCall(chatItem.functionCall));
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return messages;
|
|
52
|
+
}
|
|
53
|
+
mapHumanMessage(item) {
|
|
54
|
+
const contentParts = [];
|
|
55
|
+
if (item.text)
|
|
56
|
+
contentParts.push(extractChatMessageText(item));
|
|
57
|
+
if (item.images) {
|
|
58
|
+
for (const image of item.images) {
|
|
59
|
+
const imageUrl = image.publicUrl ?? image.base64Url;
|
|
60
|
+
if (imageUrl) {
|
|
61
|
+
contentParts.push(imageUrl);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (contentParts.length === 0) {
|
|
66
|
+
throw new Error('User message content is empty');
|
|
67
|
+
}
|
|
68
|
+
return { role: 'user', content: contentParts.join('\n') };
|
|
69
|
+
}
|
|
70
|
+
mapBotMessage(item) {
|
|
71
|
+
if (!item.text) {
|
|
72
|
+
throw new Error('Assistant message content is empty');
|
|
73
|
+
}
|
|
74
|
+
return { role: 'assistant', content: item.text };
|
|
75
|
+
}
|
|
76
|
+
mapFunctionCall(item) {
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
role: 'assistant',
|
|
80
|
+
toolCalls: [
|
|
81
|
+
{
|
|
82
|
+
id: item.id,
|
|
83
|
+
type: 'function',
|
|
84
|
+
function: {
|
|
85
|
+
name: item.name,
|
|
86
|
+
arguments: item.arguments || '{}',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
role: 'tool',
|
|
93
|
+
toolCallId: item.id,
|
|
94
|
+
content: item.result ?? 'No result',
|
|
95
|
+
},
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
mapTool(tool) {
|
|
99
|
+
return {
|
|
100
|
+
type: 'function',
|
|
101
|
+
function: {
|
|
102
|
+
name: tool.name,
|
|
103
|
+
description: tool.description,
|
|
104
|
+
parameters: {
|
|
105
|
+
type: 'object',
|
|
106
|
+
properties: tool.parameters.reduce((prev, param) => ({
|
|
107
|
+
...prev,
|
|
108
|
+
[param.name]: { type: param.type, description: param.description },
|
|
109
|
+
}), {}),
|
|
110
|
+
required: tool.parameters.map((param) => param.name),
|
|
111
|
+
additionalProperties: false,
|
|
112
|
+
},
|
|
113
|
+
strict: true,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
mapResponse(response) {
|
|
118
|
+
const { toolCalls: responseToolCalls, content: responseText } = response.choices?.[0]?.message ?? {};
|
|
119
|
+
const nextItems = [];
|
|
120
|
+
if (responseText) {
|
|
121
|
+
nextItems.push({ type: 'botMessage', botMessage: { text: responseText } });
|
|
122
|
+
}
|
|
123
|
+
if (responseToolCalls && responseToolCalls.length > 0) {
|
|
124
|
+
for (const toolCall of responseToolCalls) {
|
|
125
|
+
if (toolCall.type === 'function') {
|
|
126
|
+
nextItems.push({
|
|
127
|
+
type: 'functionCall',
|
|
128
|
+
functionCall: {
|
|
129
|
+
id: toolCall.id,
|
|
130
|
+
name: toolCall.function.name,
|
|
131
|
+
arguments: toolCall.function.arguments,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (nextItems.length === 0) {
|
|
138
|
+
throw new Error('Not supported OpenRouter Response');
|
|
139
|
+
}
|
|
140
|
+
let usage;
|
|
141
|
+
if (response.usage) {
|
|
142
|
+
usage = {
|
|
143
|
+
inputTokens: response.usage.promptTokens,
|
|
144
|
+
outputTokens: response.usage.completionTokens,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
throw new Error('Unable to found usage info');
|
|
149
|
+
}
|
|
150
|
+
return { nextItems, usage };
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
OpenRouterChatAdapter = __decorate([
|
|
154
|
+
singleton(),
|
|
155
|
+
__metadata("design:paramtypes", [Env])
|
|
156
|
+
], OpenRouterChatAdapter);
|
|
157
|
+
|
|
158
|
+
export { OpenRouterChatAdapter };
|
|
@@ -11,5 +11,15 @@ class CustomError extends Error {
|
|
|
11
11
|
this.info = data.info;
|
|
12
12
|
}
|
|
13
13
|
}
|
|
14
|
+
function errorToPlainObject(error) {
|
|
15
|
+
const { name, message, stack } = error;
|
|
16
|
+
const extra = {};
|
|
17
|
+
for (const key of Object.keys(error)) {
|
|
18
|
+
if (key === 'message' || key === 'stack')
|
|
19
|
+
continue;
|
|
20
|
+
extra[key] = error[key];
|
|
21
|
+
}
|
|
22
|
+
return { name, message, stack, ...extra };
|
|
23
|
+
}
|
|
14
24
|
|
|
15
|
-
export { CustomError };
|
|
25
|
+
export { CustomError, errorToPlainObject };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import debug from 'debug';
|
|
2
|
+
import { errorToPlainObject } from '../error/CustomError.js';
|
|
2
3
|
|
|
3
4
|
const levelColors = {
|
|
4
5
|
trace: 0,
|
|
@@ -127,11 +128,7 @@ class Logger {
|
|
|
127
128
|
formatArgs(args) {
|
|
128
129
|
return args.map((arg) => {
|
|
129
130
|
if (arg instanceof Error) {
|
|
130
|
-
return JSON.stringify(
|
|
131
|
-
name: arg.name,
|
|
132
|
-
message: arg.message,
|
|
133
|
-
stack: arg.stack,
|
|
134
|
-
});
|
|
131
|
+
return JSON.stringify(errorToPlainObject(arg));
|
|
135
132
|
}
|
|
136
133
|
if (arg === null) {
|
|
137
134
|
return 'null';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { __decorate, __metadata } from 'tslib';
|
|
2
2
|
import { singleton } from '../../core/injection/index.js';
|
|
3
|
+
import { CustomError } from '../../core/error/CustomError.js';
|
|
4
|
+
import '../../core/error/setupErrorHandlers.js';
|
|
3
5
|
import { AsyncMetadataStore } from './AsyncMetadataStore.js';
|
|
4
6
|
import { Job } from './Job.js';
|
|
5
7
|
import { JobRepository } from './JobRepository.js';
|
|
@@ -28,7 +30,10 @@ let Async = class Async {
|
|
|
28
30
|
}
|
|
29
31
|
const { error, value: commandData } = validateAndTransform(data, ctor);
|
|
30
32
|
if (error) {
|
|
31
|
-
throw new
|
|
33
|
+
throw new CustomError({
|
|
34
|
+
message: `Validation failed: ${error.description}`,
|
|
35
|
+
info: error,
|
|
36
|
+
});
|
|
32
37
|
}
|
|
33
38
|
const scheduledDate = this.resolveScheduledDate(scheduledAt);
|
|
34
39
|
const job = new Job({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Entity } from '../../core/entity/Entity.js';
|
|
2
|
-
import {
|
|
2
|
+
import { errorToPlainObject } from '../../core/error/CustomError.js';
|
|
3
3
|
import '../../core/error/setupErrorHandlers.js';
|
|
4
4
|
|
|
5
5
|
class Job extends Entity {
|
|
@@ -78,22 +78,21 @@ class Job extends Entity {
|
|
|
78
78
|
setAsFailed(error) {
|
|
79
79
|
if (this.hasFinished())
|
|
80
80
|
throw new Error(`job ${this.id} Can't be set as failed because has be finished previously`);
|
|
81
|
-
if (!this.isRunning())
|
|
82
|
-
throw new Error(`job ${this.id} can't be set as failed because is no running`);
|
|
83
81
|
const now = new Date().getTime();
|
|
82
|
+
const { name: _name, message, stack, ...extra } = errorToPlainObject(error);
|
|
84
83
|
this.data.error = {
|
|
85
84
|
time: now,
|
|
86
|
-
message
|
|
87
|
-
stack
|
|
88
|
-
info:
|
|
85
|
+
message,
|
|
86
|
+
stack,
|
|
87
|
+
info: Object.keys(extra).length > 0 ? extra : undefined,
|
|
89
88
|
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const currentReintentDelay = (this.data.reintentsDelaysInSeconds ?? []).at(this.data.intentNumber);
|
|
89
|
+
const intentNumber = this.data.intentNumber ?? 0;
|
|
90
|
+
const currentReintentDelay = (this.data.reintentsDelaysInSeconds ?? []).at(intentNumber);
|
|
93
91
|
if (currentReintentDelay == null) {
|
|
94
92
|
this.data.failedAt = now;
|
|
95
93
|
}
|
|
96
94
|
else {
|
|
95
|
+
this.data.intentNumber = intentNumber + 1;
|
|
97
96
|
this.data.scheduledAt = now + currentReintentDelay * 1000;
|
|
98
97
|
this.data.startedAt = undefined;
|
|
99
98
|
}
|
|
@@ -37,8 +37,11 @@ let JobExecutor = class JobExecutor {
|
|
|
37
37
|
catch (e) {
|
|
38
38
|
this.logger.error(`Job ${job.id} execution error:`, e);
|
|
39
39
|
try {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
const fresh = await this.repo.findOrThrow(job.id);
|
|
41
|
+
if (!fresh.hasFinished()) {
|
|
42
|
+
fresh.setAsFailed(e instanceof Error ? e : new Error('Job execution error'));
|
|
43
|
+
await this.repo.update(fresh);
|
|
44
|
+
}
|
|
42
45
|
}
|
|
43
46
|
catch (updateError) {
|
|
44
47
|
this.logger.error(`Failed to update job ${job.id} status:`, updateError);
|
|
@@ -3,6 +3,8 @@ import { AsyncMetadataStore } from './AsyncMetadataStore.js';
|
|
|
3
3
|
import { JobRepository } from './JobRepository.js';
|
|
4
4
|
import { Job } from './Job.js';
|
|
5
5
|
import { singleton, container } from '../../core/injection/index.js';
|
|
6
|
+
import { CustomError } from '../../core/error/CustomError.js';
|
|
7
|
+
import '../../core/error/setupErrorHandlers.js';
|
|
6
8
|
import { Logger } from '../../core/logger/Logger.js';
|
|
7
9
|
import '../../core/validation/metadata/ValidationMetadataStore.js';
|
|
8
10
|
import { validateAndTransform } from '../../core/validation/validateAndTransform.js';
|
|
@@ -34,8 +36,11 @@ let JobRunner = class JobRunner {
|
|
|
34
36
|
let command = undefined;
|
|
35
37
|
if (commandConstructor) {
|
|
36
38
|
const validationResult = validateAndTransform(commandData, commandConstructor);
|
|
37
|
-
if (
|
|
38
|
-
throw new
|
|
39
|
+
if (validationResult.error) {
|
|
40
|
+
throw new CustomError({
|
|
41
|
+
message: `Invalid command data: ${validationResult.error.description}`,
|
|
42
|
+
info: validationResult.error,
|
|
43
|
+
});
|
|
39
44
|
}
|
|
40
45
|
command = validationResult.value;
|
|
41
46
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomError } from '../../core/error/CustomError.js';
|
|
1
|
+
import { CustomError, errorToPlainObject } from '../../core/error/CustomError.js';
|
|
2
2
|
import '../../core/error/setupErrorHandlers.js';
|
|
3
3
|
import { container } from '../../core/injection/index.js';
|
|
4
4
|
import { Logger } from '../../core/logger/Logger.js';
|
|
@@ -76,14 +76,10 @@ function runRestControllers(controllers) {
|
|
|
76
76
|
catch (err) {
|
|
77
77
|
logger.error(`${method.toUpperCase()} ${route} failed`, err);
|
|
78
78
|
if (err instanceof Error) {
|
|
79
|
-
const
|
|
80
|
-
const { httpCode, ...info } = keys.reduce((acc, key) => {
|
|
81
|
-
acc[key] = err[key];
|
|
82
|
-
return acc;
|
|
83
|
-
}, {});
|
|
79
|
+
const { name: _name, stack, httpCode, ...info } = errorToPlainObject(err);
|
|
84
80
|
res
|
|
85
81
|
.status(httpCode ?? 500)
|
|
86
|
-
.json(removeCircular({ error: { message: err.message, stack
|
|
82
|
+
.json(removeCircular({ error: { message: err.message, stack, ...info } }));
|
|
87
83
|
}
|
|
88
84
|
else {
|
|
89
85
|
res.status(500).json({ error: { message: 'Unknown error' } });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CustomError } from '../../core/error/CustomError.js';
|
|
1
|
+
import { CustomError, errorToPlainObject } from '../../core/error/CustomError.js';
|
|
2
2
|
import '../../core/error/setupErrorHandlers.js';
|
|
3
3
|
import { container } from '../../core/injection/index.js';
|
|
4
4
|
import { Logger } from '../../core/logger/Logger.js';
|
|
@@ -72,13 +72,9 @@ function runSocketControllers(controllers) {
|
|
|
72
72
|
catch (err) {
|
|
73
73
|
logger.error(`Event '${event.config.event}' on '${namespace}' failed`, err);
|
|
74
74
|
if (err instanceof Error) {
|
|
75
|
-
const
|
|
76
|
-
const { httpCode, ...info } = keys.reduce((acc, key) => {
|
|
77
|
-
acc[key] = err[key];
|
|
78
|
-
return acc;
|
|
79
|
-
}, {});
|
|
75
|
+
const { name: _name, httpCode: _httpCode, ...info } = errorToPlainObject(err);
|
|
80
76
|
if (typeof callback === 'function') {
|
|
81
|
-
callback({ error:
|
|
77
|
+
callback({ error: info });
|
|
82
78
|
}
|
|
83
79
|
}
|
|
84
80
|
else {
|
package/dist/src/index.d.ts
CHANGED
|
@@ -117,6 +117,7 @@ declare class CustomError extends Error {
|
|
|
117
117
|
info?: any;
|
|
118
118
|
constructor(data: ICustomErrorData);
|
|
119
119
|
}
|
|
120
|
+
declare function errorToPlainObject(error: Error): Record<string, any>;
|
|
120
121
|
|
|
121
122
|
type ErrorSeverity = 'warning' | 'error' | 'fatal';
|
|
122
123
|
interface IErrorMonitorContext {
|
|
@@ -1559,6 +1560,20 @@ declare class OpenaiChatAdapter implements IChatAdapter {
|
|
|
1559
1560
|
private mapResponse;
|
|
1560
1561
|
}
|
|
1561
1562
|
|
|
1563
|
+
declare class OpenRouterChatAdapter implements IChatAdapter {
|
|
1564
|
+
private env;
|
|
1565
|
+
private openRouter;
|
|
1566
|
+
private logger;
|
|
1567
|
+
constructor(env: Env);
|
|
1568
|
+
nextItems(req: IChatAdapterNextItemsReq): Promise<IChatAdapterNextItemsRes>;
|
|
1569
|
+
private mapChatItems;
|
|
1570
|
+
private mapHumanMessage;
|
|
1571
|
+
private mapBotMessage;
|
|
1572
|
+
private mapFunctionCall;
|
|
1573
|
+
private mapTool;
|
|
1574
|
+
private mapResponse;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1562
1577
|
declare class PgChatRepository extends PgCrudRepository<Chat> implements IChatRepository {
|
|
1563
1578
|
constructor(pool: Pool);
|
|
1564
1579
|
findByConnection(query: IChatConnection): Promise<Chat | null>;
|
|
@@ -2163,4 +2178,4 @@ declare function HtmlModule(options: IHtmlModuleOptions): {
|
|
|
2163
2178
|
new (): {};
|
|
2164
2179
|
};
|
|
2165
2180
|
|
|
2166
|
-
export { AnthropicChatAdapter, ApiKey, ApiKeyGuardMiddleware, ApiKeyHandshakeGuardMiddleware, ApiKeyRepository, Async, AsyncMetadataStore, Auth, Chat, ChatAdapter, ChatBot, ChatBotMetadataStore, ChatItem, ChatMemory, ChatRepository, ChatResolver, type ClientMap, CmdChannel, Container, ControllerMetadataStore, CronJob, CronJobRepository, CustomError, DeepSeekChatAdapter, DescriptionMetadataStore, EXPRESS_REQ, EXPRESS_RES, Entity, Env, EnvWhatsAppRepository, type ErrorSeverity, ExpressProvider, GoogleChatAdapter, type GoogleChatAdapterV2Options, HtmlModule, HttpServerProvider, type IApiKeyData, type IApiKeyRepository, type IArrayValidationError, type IArrayValidationResult, type IBotMessageItem, type IChannelMessage, type IChannelMetadata, type IChatAdapter, type IChatAdapterNextItemsReq, type IChatAdapterNextItemsRes, type IChatAssociation, type IChatBot, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatItem, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatRepository, type IChatType, type ICmdChannelMessage, type ICmdReceivedMessage, type ICommandConfig, type ICommandHandler, type ICommandHandlerConfig, type IConstructor, type ICronConfig, type ICronJobData, type ICrudRepository, type ICustomErrorData, type IDescriptionMetadata, type IEndPointConfig, type IEndPointMetadata, type IEntityData, type IEnvType, type IErrorHandlersConfig, type IErrorMonitor, type IErrorMonitorContext, type IFunctionCall, type IFunctionCallItem, type IGenerateApiKeyReq, type IGenerateApiKeyRes, type IGetWhatsAppTemplateRequest, type IHandshakeMiddleware, type IHandshakeMiddlewareMetadata, type IHtmlModuleOptions, type IHumanMessageItem, type IJobData, type IJobRepository, type IJwtRefreshTokenData, type IJwtRefreshTokenRepository, type ILanguageModelUsage, type IListenWhatsAppMessageRequest, type ILockKey, type ILocker, type ILockerKey, type IMessageContext, type IMiddleware, type IMiddlewareMetadata, type IMindset, type IMindsetConfig, type IMindsetIdentity, type IMindsetLlm, type IMindsetMetadata, type IMindsetModuleConfig, type IMindsetModuleMetadata, type IMindsetTool, type IMindsetToolParameter, type IModelValidationError, type IModelValidationResult, type IModelValidatorsInfo, type IMoneyData, type IPersistentData, type IPgRepositoryConfig, type IPropertyValidatorInfo, type IReceivedMessage, type IRemoteApiKeyFetcher, type IRestControllerConfig, type IRestControllerMetadata, type IScheduleAt, type IScheduleDelay, type ISendByWasenderRequest, type ISendWhatsAppRequest, type ISendWhatsAppTemplateRequest, type ISocketChannelConfig, type ISocketChannelMessage, type ISocketChannelReceivedMessage, type ISocketControllerConfig, type ISocketControllerMetadata, type ISocketEventConfig, type ISocketEventMetadata, type ISocketReceivedMessage, type IStorableData, type ITelegramChannelConfig, type ITelegramChannelMessage, type ITelegramReceivedMessage, type IValidateArrayOptions, type IValidateArrayOptionsWithItemsValidators, type IValidateInputShape, type IValidateIsInOptions, type IValidateIsRecordOptions, type IValidateMaxOptions, type IValidateMinOptions, type IValidationError, type IValidationResult, type IValidator, type IValidatorMetadata, type IWasenderChannelMessageListener, type IWasenderDeviceListMetadata, type IWasenderEvent, type IWasenderMessageContent, type IWasenderMessageContextInfo, type IWasenderMessageKey, type IWasenderMessageReceivedData, type IWasenderMessageReceivedEvent, type IWasenderQrUpdatedEvent, type IWhatsAppBusinessAccount, type IWhatsAppBusinessNumber, type IWhatsAppByWasenderChannelConfig, type IWhatsAppByWasenderReceivedMessage, type IWhatsAppChannelMessage, type IWhatsAppCloudContact, type IWhatsAppCloudMessage, type IWhatsAppCloudMessageMetadata, type IWhatsAppCloudTemplate, type IWhatsAppCloudTemplateComponent, type IWhatsAppCloudTemplateMessage, type IWhatsAppCloudTemplateParameter, type IWhatsAppCloudTemplateResponse, type IWhatsAppCloudWebhookPayload, type IWhatsAppData, type IWhatsAppMessageListener, type IWhatsAppProxyListenMessageEventData, type IWhatsAppProxyListenMessageEventReq, type IWhatsAppProxyMessage, type IWhatsAppProxyMessageContent, type IWhatsAppProxyMessageEventReq, type IWhatsAppProxySendMessageEventReq, type IWhatsAppReceivedMessage, type IWhatsAppRepository, type IWhatsAppSenderOptions, type IWhatsappChannelConfig, type IchatControllerConfig, Job, JobRepository, JobRunner, Jwt, JwtAccessAndRefreshTokenDto, JwtConfig, JwtGuardMiddleware, JwtHandshakeGuardMiddleware, JwtRefreshToken, JwtRefreshTokenRepository, JwtSigner, JwtTokenDto, Lifecycle, Locker, Logger, Mapper, Mindset, MindsetMetadataStore, MindsetOperator, Money, MoneyDto, OpenaiChatAdapter, Password, type PasswordHashOptions, Persistent, PgApiKeyRepository, PgChatMemory, PgChatRepository, PgCronJobRepository, PgCrudRepository, PgJobRepository, PgJwtRefreshTokenRepository, PgLockKey, PgLocker, PgRepositoryBase, PgWhatsAppRepository, RamChatMemory, RamChatRepository, Random, RemoteApiKeyRepository, RestControllerMetadataStore, RestRequest, SocketChannel, SocketChannelConfig, SocketChannelReceivedMessage, SocketControllerMetadataStore, SocketServerConfig, SocketServerProvider, Storable, TelegramChannel, TelegramChannelConfig, ValidationMetadataStore, WHATSAPP_MESSAGE_EVENT, WHATSAPP_PROXY_LISTEN_MESSAGE_EVENT, WHATSAPP_PROXY_SEND_MESSAGE_EVENT, WabotChatAdapter, WasenderWebhookController, WhatsApp, WhatsAppByWasenderChannel, WhatsAppByWasenderChannelConfig, WhatsAppChannel, WhatsAppReceiver, WhatsAppReceiverByCloudApi, WhatsAppReceiverByWabotProxy, WhatsAppReceiverByWasender, WhatsAppRepository, WhatsAppSender, WhatsAppSenderByCloudApi, WhatsAppSenderByWabotProxy, WhatsAppSenderByWasender, WhatsAppWabotProxyConnection, WhatsappChannelConfig, apiKeyGuard, apiKeyHandshakeGuard, chatBot, chatController, chatItemTypeOptions, cmd, cmdChannelName, command, commandHandler, container, cron, description, extractChatMessageText, extractNumberFromWasenderMessageKey, getClientMap, getPgClient, handshakeMiddlewares, inject, injectable, isArray, isBoolean, isDate, isIn, isModel, isNotEmpty, isNumber, isOptional, isPresent, isRecord, isString, jwtGuard, jwtHandshakeGuard, max, middleware, min, mindset, mindsetModule, modelInfo, onDelete, onGet, onPost, onPut, onSocketEvent, pgStorage, readJsonFromFile, restController, runChatControllers, runCommandHandlers, runCronHandlers, runRestControllers, runSocketControllers, safeJsonParse, scoped, setupErrorHandlers, singleton, socket, socketChannelName, socketController, stopCommandHandlers, stopCronHandlers, telegram, telegramChannelName, validateAndTransform, validateArray, validateIsBoolean, validateIsDate, validateIsIn, validateIsNotEmpty, validateIsNumber, validateIsPresent, validateIsRecord, validateIsString, validateMax, validateMin, validateModel, whatsApp, whatsAppByWasender, whatsAppByWasenderChannelName, whatsAppChannelName, withPgClient, withPgTransaction, writeJsonToFile };
|
|
2181
|
+
export { AnthropicChatAdapter, ApiKey, ApiKeyGuardMiddleware, ApiKeyHandshakeGuardMiddleware, ApiKeyRepository, Async, AsyncMetadataStore, Auth, Chat, ChatAdapter, ChatBot, ChatBotMetadataStore, ChatItem, ChatMemory, ChatRepository, ChatResolver, type ClientMap, CmdChannel, Container, ControllerMetadataStore, CronJob, CronJobRepository, CustomError, DeepSeekChatAdapter, DescriptionMetadataStore, EXPRESS_REQ, EXPRESS_RES, Entity, Env, EnvWhatsAppRepository, type ErrorSeverity, ExpressProvider, GoogleChatAdapter, type GoogleChatAdapterV2Options, HtmlModule, HttpServerProvider, type IApiKeyData, type IApiKeyRepository, type IArrayValidationError, type IArrayValidationResult, type IBotMessageItem, type IChannelMessage, type IChannelMetadata, type IChatAdapter, type IChatAdapterNextItemsReq, type IChatAdapterNextItemsRes, type IChatAssociation, type IChatBot, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatItem, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatRepository, type IChatType, type ICmdChannelMessage, type ICmdReceivedMessage, type ICommandConfig, type ICommandHandler, type ICommandHandlerConfig, type IConstructor, type ICronConfig, type ICronJobData, type ICrudRepository, type ICustomErrorData, type IDescriptionMetadata, type IEndPointConfig, type IEndPointMetadata, type IEntityData, type IEnvType, type IErrorHandlersConfig, type IErrorMonitor, type IErrorMonitorContext, type IFunctionCall, type IFunctionCallItem, type IGenerateApiKeyReq, type IGenerateApiKeyRes, type IGetWhatsAppTemplateRequest, type IHandshakeMiddleware, type IHandshakeMiddlewareMetadata, type IHtmlModuleOptions, type IHumanMessageItem, type IJobData, type IJobRepository, type IJwtRefreshTokenData, type IJwtRefreshTokenRepository, type ILanguageModelUsage, type IListenWhatsAppMessageRequest, type ILockKey, type ILocker, type ILockerKey, type IMessageContext, type IMiddleware, type IMiddlewareMetadata, type IMindset, type IMindsetConfig, type IMindsetIdentity, type IMindsetLlm, type IMindsetMetadata, type IMindsetModuleConfig, type IMindsetModuleMetadata, type IMindsetTool, type IMindsetToolParameter, type IModelValidationError, type IModelValidationResult, type IModelValidatorsInfo, type IMoneyData, type IPersistentData, type IPgRepositoryConfig, type IPropertyValidatorInfo, type IReceivedMessage, type IRemoteApiKeyFetcher, type IRestControllerConfig, type IRestControllerMetadata, type IScheduleAt, type IScheduleDelay, type ISendByWasenderRequest, type ISendWhatsAppRequest, type ISendWhatsAppTemplateRequest, type ISocketChannelConfig, type ISocketChannelMessage, type ISocketChannelReceivedMessage, type ISocketControllerConfig, type ISocketControllerMetadata, type ISocketEventConfig, type ISocketEventMetadata, type ISocketReceivedMessage, type IStorableData, type ITelegramChannelConfig, type ITelegramChannelMessage, type ITelegramReceivedMessage, type IValidateArrayOptions, type IValidateArrayOptionsWithItemsValidators, type IValidateInputShape, type IValidateIsInOptions, type IValidateIsRecordOptions, type IValidateMaxOptions, type IValidateMinOptions, type IValidationError, type IValidationResult, type IValidator, type IValidatorMetadata, type IWasenderChannelMessageListener, type IWasenderDeviceListMetadata, type IWasenderEvent, type IWasenderMessageContent, type IWasenderMessageContextInfo, type IWasenderMessageKey, type IWasenderMessageReceivedData, type IWasenderMessageReceivedEvent, type IWasenderQrUpdatedEvent, type IWhatsAppBusinessAccount, type IWhatsAppBusinessNumber, type IWhatsAppByWasenderChannelConfig, type IWhatsAppByWasenderReceivedMessage, type IWhatsAppChannelMessage, type IWhatsAppCloudContact, type IWhatsAppCloudMessage, type IWhatsAppCloudMessageMetadata, type IWhatsAppCloudTemplate, type IWhatsAppCloudTemplateComponent, type IWhatsAppCloudTemplateMessage, type IWhatsAppCloudTemplateParameter, type IWhatsAppCloudTemplateResponse, type IWhatsAppCloudWebhookPayload, type IWhatsAppData, type IWhatsAppMessageListener, type IWhatsAppProxyListenMessageEventData, type IWhatsAppProxyListenMessageEventReq, type IWhatsAppProxyMessage, type IWhatsAppProxyMessageContent, type IWhatsAppProxyMessageEventReq, type IWhatsAppProxySendMessageEventReq, type IWhatsAppReceivedMessage, type IWhatsAppRepository, type IWhatsAppSenderOptions, type IWhatsappChannelConfig, type IchatControllerConfig, Job, JobRepository, JobRunner, Jwt, JwtAccessAndRefreshTokenDto, JwtConfig, JwtGuardMiddleware, JwtHandshakeGuardMiddleware, JwtRefreshToken, JwtRefreshTokenRepository, JwtSigner, JwtTokenDto, Lifecycle, Locker, Logger, Mapper, Mindset, MindsetMetadataStore, MindsetOperator, Money, MoneyDto, OpenRouterChatAdapter, OpenaiChatAdapter, Password, type PasswordHashOptions, Persistent, PgApiKeyRepository, PgChatMemory, PgChatRepository, PgCronJobRepository, PgCrudRepository, PgJobRepository, PgJwtRefreshTokenRepository, PgLockKey, PgLocker, PgRepositoryBase, PgWhatsAppRepository, RamChatMemory, RamChatRepository, Random, RemoteApiKeyRepository, RestControllerMetadataStore, RestRequest, SocketChannel, SocketChannelConfig, SocketChannelReceivedMessage, SocketControllerMetadataStore, SocketServerConfig, SocketServerProvider, Storable, TelegramChannel, TelegramChannelConfig, ValidationMetadataStore, WHATSAPP_MESSAGE_EVENT, WHATSAPP_PROXY_LISTEN_MESSAGE_EVENT, WHATSAPP_PROXY_SEND_MESSAGE_EVENT, WabotChatAdapter, WasenderWebhookController, WhatsApp, WhatsAppByWasenderChannel, WhatsAppByWasenderChannelConfig, WhatsAppChannel, WhatsAppReceiver, WhatsAppReceiverByCloudApi, WhatsAppReceiverByWabotProxy, WhatsAppReceiverByWasender, WhatsAppRepository, WhatsAppSender, WhatsAppSenderByCloudApi, WhatsAppSenderByWabotProxy, WhatsAppSenderByWasender, WhatsAppWabotProxyConnection, WhatsappChannelConfig, apiKeyGuard, apiKeyHandshakeGuard, chatBot, chatController, chatItemTypeOptions, cmd, cmdChannelName, command, commandHandler, container, cron, description, errorToPlainObject, extractChatMessageText, extractNumberFromWasenderMessageKey, getClientMap, getPgClient, handshakeMiddlewares, inject, injectable, isArray, isBoolean, isDate, isIn, isModel, isNotEmpty, isNumber, isOptional, isPresent, isRecord, isString, jwtGuard, jwtHandshakeGuard, max, middleware, min, mindset, mindsetModule, modelInfo, onDelete, onGet, onPost, onPut, onSocketEvent, pgStorage, readJsonFromFile, restController, runChatControllers, runCommandHandlers, runCronHandlers, runRestControllers, runSocketControllers, safeJsonParse, scoped, setupErrorHandlers, singleton, socket, socketChannelName, socketController, stopCommandHandlers, stopCronHandlers, telegram, telegramChannelName, validateAndTransform, validateArray, validateIsBoolean, validateIsDate, validateIsIn, validateIsNotEmpty, validateIsNumber, validateIsPresent, validateIsRecord, validateIsString, validateMax, validateMin, validateModel, whatsApp, whatsAppByWasender, whatsAppByWasenderChannelName, whatsAppChannelName, withPgClient, withPgTransaction, writeJsonToFile };
|
package/dist/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { Auth } from './core/auth/Auth.js';
|
|
2
2
|
export { Entity, Persistent } from './core/entity/Entity.js';
|
|
3
3
|
export { Env } from './core/env/Env.js';
|
|
4
|
-
export { CustomError } from './core/error/CustomError.js';
|
|
4
|
+
export { CustomError, errorToPlainObject } from './core/error/CustomError.js';
|
|
5
5
|
export { setupErrorHandlers } from './core/error/setupErrorHandlers.js';
|
|
6
6
|
export { Lifecycle, container, inject, injectable, scoped, singleton } from './core/injection/index.js';
|
|
7
7
|
export { Logger } from './core/logger/Logger.js';
|
|
@@ -126,6 +126,7 @@ export { AnthropicChatAdapter } from './addon/chat-bot/anthropic/AnthropicChatAd
|
|
|
126
126
|
export { DeepSeekChatAdapter } from './addon/chat-bot/deepseek/DeepSeekChatAdapter.js';
|
|
127
127
|
export { GoogleChatAdapter } from './addon/chat-bot/google/GoogleChatAdapter.js';
|
|
128
128
|
export { OpenaiChatAdapter } from './addon/chat-bot/openia/OpenaiChatAdapter.js';
|
|
129
|
+
export { OpenRouterChatAdapter } from './addon/chat-bot/openrouter/OpenRouterChatAdapter.js';
|
|
129
130
|
export { PgChatRepository } from './addon/chat-bot/pg/PgChatRepository.js';
|
|
130
131
|
export { PgChatMemory } from './addon/chat-bot/pg/PgChatMemory.js';
|
|
131
132
|
export { RamChatMemory } from './addon/chat-bot/ram/RamChatMemory.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wabot-dev/framework",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
4
4
|
"description": "Framework for IA Chat Bots",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"tslib": "^2.8.1",
|
|
67
67
|
"tsyringe": "^4.9.1",
|
|
68
68
|
"uuid": "^11.1.0",
|
|
69
|
-
"wasenderapi": "^0.1.5"
|
|
69
|
+
"wasenderapi": "^0.1.5",
|
|
70
|
+
"@openrouter/sdk": "^0.12.2"
|
|
70
71
|
}
|
|
71
72
|
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { container } from '../../../core/injection/index.js';
|
|
2
|
-
import { WhatsAppByWasenderChannelConfig } from './WhatsAppByWasenderChannelConfig.js';
|
|
3
|
-
import { ControllerMetadataStore } from '../../../feature/chat-controller/metadata/ControllerMetadataStore.js';
|
|
4
|
-
import '../../../feature/chat-controller/ChatResolver.js';
|
|
5
|
-
import '../../../feature/chat-controller/runChatControllers.js';
|
|
6
|
-
import { WhatsAppByWasenderChannel } from './WhatsAppByWasenderChannel.js';
|
|
7
|
-
|
|
8
|
-
function whatsAppByWasender(config) {
|
|
9
|
-
return function (target, propertyKey) {
|
|
10
|
-
const store = container.resolve(ControllerMetadataStore);
|
|
11
|
-
store.saveChannelMetadata({
|
|
12
|
-
channelConstructor: WhatsAppByWasenderChannel,
|
|
13
|
-
functionName: propertyKey.toString(),
|
|
14
|
-
controllerConstructor: target.constructor,
|
|
15
|
-
channelConfig: new WhatsAppByWasenderChannelConfig(config),
|
|
16
|
-
});
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export { whatsAppByWasender };
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { __decorate, __metadata } from 'tslib';
|
|
2
|
-
import { injectable } from '../../../core/injection/index.js';
|
|
3
|
-
import { Logger } from '../../../core/logger/Logger.js';
|
|
4
|
-
import { WhatsAppByWasenderChannelConfig } from './WhatsAppByWasenderChannelConfig.js';
|
|
5
|
-
import { WhatsAppReceiverByWasender } from './WhatsAppReceiverByWasender.js';
|
|
6
|
-
import { WhatsAppSenderByWasender } from './WhatsAppSenderByWasender.js';
|
|
7
|
-
|
|
8
|
-
let WhatsAppByWasenderChannel = class WhatsAppByWasenderChannel {
|
|
9
|
-
config;
|
|
10
|
-
sender;
|
|
11
|
-
receiver;
|
|
12
|
-
logger = new Logger('wabot:whatsapp-by-wasender-channel');
|
|
13
|
-
constructor(config, sender, receiver) {
|
|
14
|
-
this.config = config;
|
|
15
|
-
this.sender = sender;
|
|
16
|
-
this.receiver = receiver;
|
|
17
|
-
}
|
|
18
|
-
listen(callback) {
|
|
19
|
-
this.receiver.listenMessage(async (message) => {
|
|
20
|
-
try {
|
|
21
|
-
await callback({
|
|
22
|
-
chatConnection: message.chatConnection,
|
|
23
|
-
message: message.message,
|
|
24
|
-
reply: async (replyMessage) => {
|
|
25
|
-
await this.sender.send({
|
|
26
|
-
from: this.config.phoneNumber,
|
|
27
|
-
to: message.chatConnection.id,
|
|
28
|
-
message: replyMessage,
|
|
29
|
-
});
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
catch (err) {
|
|
34
|
-
this.logger.error('Failed to handle WhatsApp message', err);
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
connect() {
|
|
39
|
-
this.receiver.connect();
|
|
40
|
-
}
|
|
41
|
-
disconnect() {
|
|
42
|
-
this.receiver.disconnect();
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
WhatsAppByWasenderChannel = __decorate([
|
|
46
|
-
injectable(),
|
|
47
|
-
__metadata("design:paramtypes", [WhatsAppByWasenderChannelConfig,
|
|
48
|
-
WhatsAppSenderByWasender,
|
|
49
|
-
WhatsAppReceiverByWasender])
|
|
50
|
-
], WhatsAppByWasenderChannel);
|
|
51
|
-
|
|
52
|
-
export { WhatsAppByWasenderChannel };
|
package/dist/src/addon/chat-controller/whatsapp-by-wasender/WhatsAppByWasenderChannelConfig.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
class WhatsAppByWasenderChannelConfig {
|
|
2
|
-
apiKey;
|
|
3
|
-
webhookSecret;
|
|
4
|
-
phoneNumber;
|
|
5
|
-
webhookPath;
|
|
6
|
-
retryOptions;
|
|
7
|
-
constructor(config) {
|
|
8
|
-
this.apiKey = config.apiKey;
|
|
9
|
-
this.webhookSecret = config.webhookSecret;
|
|
10
|
-
this.phoneNumber = config.phoneNumber;
|
|
11
|
-
this.webhookPath = config.webhookPath ?? '/wasender/hook';
|
|
12
|
-
this.retryOptions = config.retryOptions ?? { enabled: true, maxRetries: 3 };
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { WhatsAppByWasenderChannelConfig };
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { __decorate, __metadata } from 'tslib';
|
|
2
|
-
import { Logger } from '../../../core/logger/Logger.js';
|
|
3
|
-
import { injectable } from '../../../core/injection/index.js';
|
|
4
|
-
import { ExpressProvider } from '../../../feature/express/ExpressProvider.js';
|
|
5
|
-
import { createWasender } from '../../../node_modules/wasenderapi/dist/index.js';
|
|
6
|
-
import { WhatsAppByWasenderChannelConfig } from './WhatsAppByWasenderChannelConfig.js';
|
|
7
|
-
import { extractNumberFromWasenderMessageKey } from './extractNumberFromWasenderKey.js';
|
|
8
|
-
|
|
9
|
-
let WhatsAppReceiverByWasender = class WhatsAppReceiverByWasender {
|
|
10
|
-
expressProvider;
|
|
11
|
-
config;
|
|
12
|
-
wasender;
|
|
13
|
-
listener = null;
|
|
14
|
-
logger = new Logger('wabot:whatsapp-receiver-by-wasender');
|
|
15
|
-
constructor(expressProvider, config) {
|
|
16
|
-
this.expressProvider = expressProvider;
|
|
17
|
-
this.config = config;
|
|
18
|
-
this.wasender = createWasender(config.apiKey, undefined, undefined, undefined, config.retryOptions, config.webhookSecret);
|
|
19
|
-
}
|
|
20
|
-
listenMessage(listener) {
|
|
21
|
-
this.listener = listener;
|
|
22
|
-
}
|
|
23
|
-
connect() {
|
|
24
|
-
const expressApp = this.expressProvider.getExpress();
|
|
25
|
-
expressApp.post(this.config.webhookPath, async (req, res) => {
|
|
26
|
-
try {
|
|
27
|
-
const rawBody = await this.getRawBody(req);
|
|
28
|
-
const event = await this.parseEvent(req, rawBody);
|
|
29
|
-
this.logger.trace(`received event ${event.event}`);
|
|
30
|
-
switch (event.event) {
|
|
31
|
-
case 'messages.received':
|
|
32
|
-
const messages = Array.isArray(event.data.messages)
|
|
33
|
-
? event.data.messages
|
|
34
|
-
: [event.data.messages];
|
|
35
|
-
await this.handleMessages(messages);
|
|
36
|
-
break;
|
|
37
|
-
default:
|
|
38
|
-
this.logger.warn(`unhandled event type ${event.event}`);
|
|
39
|
-
}
|
|
40
|
-
res.sendStatus(200);
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
this.logger.error('Failed to handle Wasender webhook', err);
|
|
44
|
-
res.sendStatus(500);
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
this.expressProvider.listen();
|
|
48
|
-
}
|
|
49
|
-
disconnect() {
|
|
50
|
-
// Nothing to disconnect
|
|
51
|
-
}
|
|
52
|
-
async handleMessages(messages) {
|
|
53
|
-
if (!this.listener) {
|
|
54
|
-
this.logger.warn('No listener registered, ignoring messages');
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
for (const message of messages) {
|
|
58
|
-
const from = extractNumberFromWasenderMessageKey(message.key);
|
|
59
|
-
this.logger.trace(`new message from '${from}' to '${this.config.phoneNumber}'`);
|
|
60
|
-
if (message.message.conversation) {
|
|
61
|
-
const chatConnection = {
|
|
62
|
-
chatType: 'PRIVATE',
|
|
63
|
-
channelName: 'WhatsAppByWasenderChannel',
|
|
64
|
-
id: from,
|
|
65
|
-
};
|
|
66
|
-
await this.listener({
|
|
67
|
-
chatConnection,
|
|
68
|
-
message: {
|
|
69
|
-
text: message.message.conversation,
|
|
70
|
-
senderName: message.pushName,
|
|
71
|
-
senderId: from,
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
async parseEvent(req, rawBody) {
|
|
78
|
-
const adapter = {
|
|
79
|
-
getHeader: (name) => req.header(name),
|
|
80
|
-
getRawBody: () => rawBody,
|
|
81
|
-
};
|
|
82
|
-
const event = await this.wasender.handleWebhookEvent(adapter);
|
|
83
|
-
return event;
|
|
84
|
-
}
|
|
85
|
-
getRawBody(req) {
|
|
86
|
-
return new Promise((resolve, reject) => {
|
|
87
|
-
let data = '';
|
|
88
|
-
req.on('data', (chunk) => {
|
|
89
|
-
data += chunk;
|
|
90
|
-
});
|
|
91
|
-
req.on('end', () => {
|
|
92
|
-
resolve(data);
|
|
93
|
-
});
|
|
94
|
-
req.on('error', (err) => {
|
|
95
|
-
reject(err);
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
WhatsAppReceiverByWasender = __decorate([
|
|
101
|
-
injectable(),
|
|
102
|
-
__metadata("design:paramtypes", [ExpressProvider,
|
|
103
|
-
WhatsAppByWasenderChannelConfig])
|
|
104
|
-
], WhatsAppReceiverByWasender);
|
|
105
|
-
|
|
106
|
-
export { WhatsAppReceiverByWasender };
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { __decorate, __metadata } from 'tslib';
|
|
2
|
-
import { Logger } from '../../../core/logger/Logger.js';
|
|
3
|
-
import { injectable } from '../../../core/injection/index.js';
|
|
4
|
-
import { createWasender } from '../../../node_modules/wasenderapi/dist/index.js';
|
|
5
|
-
import { WhatsAppByWasenderChannelConfig } from './WhatsAppByWasenderChannelConfig.js';
|
|
6
|
-
|
|
7
|
-
let WhatsAppSenderByWasender = class WhatsAppSenderByWasender {
|
|
8
|
-
wasender;
|
|
9
|
-
logger = new Logger('wabot:whatsapp-sender-by-wasender');
|
|
10
|
-
constructor(config) {
|
|
11
|
-
this.wasender = createWasender(config.apiKey, undefined, undefined, undefined, config.retryOptions, undefined);
|
|
12
|
-
}
|
|
13
|
-
async send(request) {
|
|
14
|
-
try {
|
|
15
|
-
const textPayload = {
|
|
16
|
-
messageType: 'text',
|
|
17
|
-
to: `+${request.to.replace(/\D+/g, '')}`,
|
|
18
|
-
text: request.message.text ?? 'No Text',
|
|
19
|
-
};
|
|
20
|
-
const result = await this.wasender.send(textPayload);
|
|
21
|
-
this.logger.trace(`message sent from '${request.from}' to '${request.to}'`);
|
|
22
|
-
this.logger.trace(`rate limit remaining: ${result.rateLimit?.remaining}`);
|
|
23
|
-
}
|
|
24
|
-
catch (error) {
|
|
25
|
-
this.logger.error(`Failed to send message from '${request.from}' to '${request.to}'`, error);
|
|
26
|
-
if (error instanceof Error) {
|
|
27
|
-
throw new Error(error.message, { cause: error });
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
throw new Error('error sending message');
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
WhatsAppSenderByWasender = __decorate([
|
|
36
|
-
injectable(),
|
|
37
|
-
__metadata("design:paramtypes", [WhatsAppByWasenderChannelConfig])
|
|
38
|
-
], WhatsAppSenderByWasender);
|
|
39
|
-
|
|
40
|
-
export { WhatsAppSenderByWasender };
|