@wabot-dev/framework 0.1.0-beta.2 → 0.1.0-beta.20
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/ai/claude/ClaudeChatBotAdapter.js +113 -0
- package/dist/src/ai/deepseek/DeepSeekChatBotAdapter.js +12 -13
- package/dist/src/ai/openia/OpenaiChatBotAdapter.js +9 -7
- package/dist/src/channels/cmd/@cmd.js +0 -4
- package/dist/src/channels/cmd/CmdChannel.js +0 -4
- package/dist/src/channels/express/ExpressProvider.js +46 -0
- package/dist/src/channels/http/HttpServerProvider.js +31 -0
- package/dist/src/channels/{socket-io → socket}/@socket.js +0 -4
- package/dist/src/channels/{socket-io → socket}/SocketChannel.js +12 -11
- package/dist/src/channels/socket/SocketServerProvider.js +50 -0
- package/dist/src/channels/telegram/@telegram.js +0 -4
- package/dist/src/channels/telegram/TelegramChannel.js +0 -4
- package/dist/src/channels/wabot/WabotDevConnection.js +57 -0
- package/dist/src/channels/{whatsapp/WhatsAppDevSocketContracts.js → wabot/WabotDevSocketContracts.js} +3 -3
- package/dist/src/channels/whatsapp/@whatsapp.js +0 -4
- package/dist/src/channels/whatsapp/EnvWhatsAppRepository.js +49 -0
- package/dist/src/channels/whatsapp/PgWhatsAppRepository.js +41 -0
- package/dist/src/channels/whatsapp/WhatsApp.js +32 -0
- package/dist/src/channels/whatsapp/WhatsAppChannel.js +33 -32
- package/dist/src/channels/whatsapp/{WhatsAppConnection.js → WhatsAppReceiver.js} +4 -6
- package/dist/src/channels/whatsapp/WhatsAppReceiverByDevConnection.js +32 -0
- package/dist/src/channels/whatsapp/WhatsAppReceiverByWebHook.js +63 -0
- package/dist/src/channels/whatsapp/WhatsAppRepository.js +10 -0
- package/dist/src/channels/whatsapp/WhatsAppSender.js +107 -20
- package/dist/src/channels/whatsapp/WhatsAppSenderByCloudApi.js +118 -0
- package/dist/src/channels/whatsapp/WhatsAppSenderByDevConnection.js +56 -0
- package/dist/src/chatbot/ChatBotAdapter.js +1 -5
- package/dist/src/chatbot/metadata/@chatBot.js +0 -5
- package/dist/src/chatbot/metadata/ChatBotMetadataStore.js +0 -5
- package/dist/src/controller/metadata/ControllerMetadataStore.js +0 -2
- package/dist/src/controller/metadata/controller/@chatController.js +0 -2
- package/dist/src/core/{Persistent.js → Entity.js} +24 -9
- package/dist/src/core/IMessageContext.js +0 -2
- package/dist/src/core/Storable.js +8 -0
- package/dist/src/core/chat/Chat.js +2 -2
- package/dist/src/core/chat/ChatItem.js +2 -2
- package/dist/src/core/user/User.js +2 -2
- package/dist/src/env/Env.js +39 -0
- package/dist/src/error/CustomError.js +15 -0
- package/dist/src/index.d.ts +539 -240
- package/dist/src/index.js +65 -34
- package/dist/src/mindset/MindsetOperator.js +1 -3
- package/dist/src/mindset/metadata/MindsetMetadataStore.js +0 -2
- package/dist/src/mindset/metadata/mindsets/@mindset.js +0 -2
- package/dist/src/mindset/metadata/modules/@mindsetModule.js +0 -2
- package/dist/src/pre-made/module/authentication/requests/SendOneTimePasswordRequest.js +0 -2
- package/dist/src/pre-made/module/authentication/requests/ValidateOneTimePasswordRequest.js +0 -2
- package/dist/src/pre-made/module/html/HtmlModule.js +70 -0
- package/dist/src/pre-made/module/register-user/requests/RegisterUserWithEmailRequest.js +0 -2
- package/dist/src/pre-made/repository/chat/pg/PgChatMemory.js +1 -7
- package/dist/src/pre-made/repository/chat/pg/PgChatRepository.js +0 -5
- package/dist/src/pre-made/repository/chat/ram/RamChatRepository.js +1 -1
- package/dist/src/pre-made/repository/user/pg/PgUserRepository.js +0 -5
- package/dist/src/repository/pg/PgCrudRepository.js +13 -3
- package/dist/src/repository/pg/PgRepositoryBase.js +2 -2
- package/dist/src/rest-controller/metadata/@get.js +19 -0
- package/dist/src/rest-controller/metadata/@middleware.js +16 -0
- package/dist/src/rest-controller/metadata/@post.js +19 -0
- package/dist/src/rest-controller/metadata/@restController.js +15 -0
- package/dist/src/rest-controller/metadata/RestControllerMetadataStore.js +50 -0
- package/dist/src/rest-controller/runRestControllers.js +93 -0
- package/dist/src/server/prepareChatContainer.js +6 -6
- package/dist/src/server/runChannel.js +2 -10
- package/dist/src/server/runServer.js +0 -43
- package/dist/src/validation/metadata/@isBoolean.js +17 -0
- package/dist/src/validation/metadata/@isDate.js +17 -0
- package/dist/src/validation/metadata/@isModel.js +18 -0
- package/dist/src/validation/metadata/@isNotEmpty.js +17 -0
- package/dist/src/validation/metadata/@isNumber.js +17 -0
- package/dist/src/validation/metadata/@isOptional.js +17 -0
- package/dist/src/validation/metadata/@isPresent.js +17 -0
- package/dist/src/validation/metadata/@isString.js +17 -0
- package/dist/src/validation/metadata/@max.js +18 -0
- package/dist/src/validation/metadata/@min.js +18 -0
- package/dist/src/validation/metadata/ValidationMetadataStore.js +70 -0
- package/dist/src/validation/validate.js +11 -0
- package/dist/src/validation/validators/validateIsBoolean.js +12 -0
- package/dist/src/validation/validators/validateIsDate.js +16 -0
- package/dist/src/validation/validators/validateIsNotEmpty.js +12 -0
- package/dist/src/validation/validators/validateIsNumber.js +12 -0
- package/dist/src/validation/validators/validateIsOptional.js +5 -0
- package/dist/src/validation/validators/validateIsPresent.js +12 -0
- package/dist/src/validation/validators/validateIsString.js +12 -0
- package/dist/src/validation/validators/validateMax.js +17 -0
- package/dist/src/validation/validators/validateMin.js +17 -0
- package/dist/src/validation/validators/validateModel.js +34 -0
- package/package.json +5 -6
- package/dist/src/channels/whatsapp/WhatsAppDevConnection.js +0 -69
- package/dist/src/channels/whatsapp/WhatsAppProdConnection.js +0 -39
- package/dist/src/controller/express/Express.js +0 -5
- package/dist/src/controller/socket.io/SocketIO.js +0 -5
- package/dist/src/env/WabotEnv.js +0 -21
- package/dist/src/mindset/metadata/params/@isOptional.js +0 -21
- package/dist/src/pre-made/repository/chat/sqlite/SqliteChatMemory.js +0 -23
- package/dist/src/pre-made/repository/chat/sqlite/SqliteChatRepository.js +0 -30
- package/dist/src/pre-made/repository/user/sqlite/SqliteUserRepository.js +0 -23
- package/dist/src/repository/sqlite/SqliteCrudRepository.js +0 -85
- package/dist/src/repository/sqlite/SqlitePersistentMapper.js +0 -17
- /package/dist/src/channels/{socket-io → socket}/SocketChannelConfig.js +0 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import '../../core/chat/repository/IChatRepository.js';
|
|
2
|
+
import { Entity } from '../../core/Entity.js';
|
|
3
|
+
import '../../core/user/IUserRepository.js';
|
|
4
|
+
|
|
5
|
+
class WhatsApp extends Entity {
|
|
6
|
+
getVerifyToken() {
|
|
7
|
+
return this.data.verifyToken;
|
|
8
|
+
}
|
|
9
|
+
getSlug() {
|
|
10
|
+
return this.data.slug;
|
|
11
|
+
}
|
|
12
|
+
getBusinessAccount() {
|
|
13
|
+
return this.data.businessAccount;
|
|
14
|
+
}
|
|
15
|
+
getAppSecret() {
|
|
16
|
+
return this.data.appSecret;
|
|
17
|
+
}
|
|
18
|
+
getBusinessNumbers() {
|
|
19
|
+
return this.data.businessNumbers;
|
|
20
|
+
}
|
|
21
|
+
getAccessToken() {
|
|
22
|
+
return this.data.accessToken;
|
|
23
|
+
}
|
|
24
|
+
hasBusinessNumber(number) {
|
|
25
|
+
return this.data.businessNumbers.some((x) => x.number === number);
|
|
26
|
+
}
|
|
27
|
+
getBussinessNumber(number) {
|
|
28
|
+
return this.data.businessNumbers.find((x) => x.number === number) ?? null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { WhatsApp };
|
|
@@ -2,52 +2,54 @@ import { __decorate, __metadata } from 'tslib';
|
|
|
2
2
|
import { ChatResolver } from '../../controller/channel/ChatResolver.js';
|
|
3
3
|
import { UserResolver } from '../../controller/channel/UserResolver.js';
|
|
4
4
|
import { injectable } from '../../injection/index.js';
|
|
5
|
-
import '../../core/chat/repository/IChatRepository.js';
|
|
6
|
-
import '../../core/user/IUserRepository.js';
|
|
7
5
|
import '../../controller/metadata/ControllerMetadataStore.js';
|
|
8
|
-
import 'express';
|
|
9
|
-
import 'socket.io';
|
|
10
|
-
import { WabotEnv } from '../../env/WabotEnv.js';
|
|
11
6
|
import { Logger } from '../../logger/Logger.js';
|
|
12
7
|
import { WhatsappChannelConfig } from './WhatsAppChannelConfig.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
8
|
+
import { WhatsAppReceiver } from './WhatsAppReceiver.js';
|
|
9
|
+
import { WhatsAppSender } from './WhatsAppSender.js';
|
|
15
10
|
|
|
16
11
|
let WhatsAppChannel = class WhatsAppChannel {
|
|
17
12
|
config;
|
|
18
13
|
chatResolver;
|
|
19
14
|
userResolver;
|
|
20
|
-
|
|
15
|
+
sender;
|
|
16
|
+
receiver;
|
|
21
17
|
logger = new Logger('wabot:whatsapp-channel');
|
|
22
|
-
|
|
23
|
-
constructor(config, chatResolver, userResolver, wabotEnv, devConnection, prodConnection) {
|
|
18
|
+
constructor(config, chatResolver, userResolver, sender, receiver) {
|
|
24
19
|
this.config = config;
|
|
25
20
|
this.chatResolver = chatResolver;
|
|
26
21
|
this.userResolver = userResolver;
|
|
27
|
-
this.
|
|
28
|
-
this.
|
|
22
|
+
this.sender = sender;
|
|
23
|
+
this.receiver = receiver;
|
|
29
24
|
}
|
|
30
25
|
listen(callback) {
|
|
31
|
-
this.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
26
|
+
this.receiver.listenMessage({
|
|
27
|
+
to: this.config.number,
|
|
28
|
+
listener: async (message) => {
|
|
29
|
+
try {
|
|
30
|
+
const chat = await this.chatResolver.resolve(message.chatConnection);
|
|
31
|
+
const user = await this.userResolver.resolve(message.userConnection);
|
|
32
|
+
callback({
|
|
33
|
+
chat,
|
|
34
|
+
user,
|
|
35
|
+
message,
|
|
36
|
+
reply: (replyMessage) => {
|
|
37
|
+
this.sender.sendWhatsApp({
|
|
38
|
+
from: this.config.number,
|
|
39
|
+
to: message.userConnection.id,
|
|
40
|
+
message: replyMessage,
|
|
41
|
+
});
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
this.logger.error(err);
|
|
47
|
+
}
|
|
48
|
+
},
|
|
47
49
|
});
|
|
48
50
|
}
|
|
49
51
|
connect() {
|
|
50
|
-
this.
|
|
52
|
+
this.receiver.connect();
|
|
51
53
|
}
|
|
52
54
|
};
|
|
53
55
|
WhatsAppChannel = __decorate([
|
|
@@ -55,9 +57,8 @@ WhatsAppChannel = __decorate([
|
|
|
55
57
|
__metadata("design:paramtypes", [WhatsappChannelConfig,
|
|
56
58
|
ChatResolver,
|
|
57
59
|
UserResolver,
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
WhatsAppProdConnection])
|
|
60
|
+
WhatsAppSender,
|
|
61
|
+
WhatsAppReceiver])
|
|
61
62
|
], WhatsAppChannel);
|
|
62
63
|
|
|
63
64
|
export { WhatsAppChannel };
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
class WhatsAppConnection {
|
|
1
|
+
class WhatsAppReceiver {
|
|
4
2
|
logger;
|
|
5
3
|
listeners = new Map();
|
|
6
4
|
constructor(logger) {
|
|
7
5
|
this.logger = logger;
|
|
8
6
|
}
|
|
9
|
-
listenMessage(
|
|
10
|
-
this.listeners.set(
|
|
7
|
+
listenMessage(request) {
|
|
8
|
+
this.listeners.set(request.to, request.listener);
|
|
11
9
|
}
|
|
12
10
|
async handlePayload(payload) {
|
|
13
11
|
try {
|
|
@@ -58,4 +56,4 @@ class WhatsAppConnection {
|
|
|
58
56
|
}
|
|
59
57
|
}
|
|
60
58
|
|
|
61
|
-
export {
|
|
59
|
+
export { WhatsAppReceiver };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import { Logger } from '../../logger/Logger.js';
|
|
3
|
+
import { WhatsAppReceiver } from './WhatsAppReceiver.js';
|
|
4
|
+
import { WabotDevConnection } from '../wabot/WabotDevConnection.js';
|
|
5
|
+
import { devListentEvent } from '../wabot/WabotDevSocketContracts.js';
|
|
6
|
+
import { singleton } from 'tsyringe';
|
|
7
|
+
import { container } from '../../injection/index.js';
|
|
8
|
+
|
|
9
|
+
let WhatsAppReceiverByDevConnection = class WhatsAppReceiverByDevConnection extends WhatsAppReceiver {
|
|
10
|
+
wabotDevConnection;
|
|
11
|
+
constructor(wabotDevConnection) {
|
|
12
|
+
super(new Logger('wabot:whatsapp-receiver-by-dev-connection'));
|
|
13
|
+
this.wabotDevConnection = wabotDevConnection;
|
|
14
|
+
}
|
|
15
|
+
async connect() {
|
|
16
|
+
const socket = await this.wabotDevConnection.getSocket();
|
|
17
|
+
socket.on(devListentEvent.DEV_WATSAPP_WEBHOOK, (payload) => {
|
|
18
|
+
this.handlePayload(payload);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
WhatsAppReceiverByDevConnection = __decorate([
|
|
23
|
+
singleton(),
|
|
24
|
+
__metadata("design:paramtypes", [WabotDevConnection])
|
|
25
|
+
], WhatsAppReceiverByDevConnection);
|
|
26
|
+
if (WabotDevConnection.isTokenAvailable()) {
|
|
27
|
+
container.register(WhatsAppReceiver, {
|
|
28
|
+
useClass: WhatsAppReceiverByDevConnection,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { WhatsAppReceiverByDevConnection };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import { Logger } from '../../logger/Logger.js';
|
|
3
|
+
import { WhatsAppReceiver } from './WhatsAppReceiver.js';
|
|
4
|
+
import { singleton } from 'tsyringe';
|
|
5
|
+
import { ExpressProvider } from '../express/ExpressProvider.js';
|
|
6
|
+
import { WhatsAppRepository } from './WhatsAppRepository.js';
|
|
7
|
+
import { WabotDevConnection } from '../wabot/WabotDevConnection.js';
|
|
8
|
+
import { container } from '../../injection/index.js';
|
|
9
|
+
|
|
10
|
+
let WhatsAppReceiverByWebHook = class WhatsAppReceiverByWebHook extends WhatsAppReceiver {
|
|
11
|
+
expressProvider;
|
|
12
|
+
whatsAppRepository;
|
|
13
|
+
expressApp;
|
|
14
|
+
webhookPath = '/whatsapp/web-hook/:slug';
|
|
15
|
+
constructor(expressProvider, whatsAppRepository) {
|
|
16
|
+
super(new Logger('wabot:whatsapp-receiver-by-webhook'));
|
|
17
|
+
this.expressProvider = expressProvider;
|
|
18
|
+
this.whatsAppRepository = whatsAppRepository;
|
|
19
|
+
this.expressApp = this.expressProvider.getExpress();
|
|
20
|
+
}
|
|
21
|
+
async connect() {
|
|
22
|
+
this.expressApp.get(this.webhookPath, async (req, res) => {
|
|
23
|
+
try {
|
|
24
|
+
let mode = req.query['hub.mode'];
|
|
25
|
+
let token = req.query['hub.verify_token'];
|
|
26
|
+
let challenge = req.query['hub.challenge'];
|
|
27
|
+
if (!mode || !token || !challenge) {
|
|
28
|
+
res.sendStatus(400);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const whatsApp = await this.whatsAppRepository.findBySlug(req.params.slug);
|
|
32
|
+
if (!whatsApp || mode !== 'subscribe' || token !== whatsApp.getVerifyToken()) {
|
|
33
|
+
res.sendStatus(403);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
res.status(200).send(challenge);
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
this.logger.error(e);
|
|
40
|
+
res.sendStatus(500);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
this.expressApp.post(this.webhookPath, (req, res) => {
|
|
45
|
+
const payload = req.body;
|
|
46
|
+
this.handlePayload(payload);
|
|
47
|
+
res.sendStatus(200);
|
|
48
|
+
});
|
|
49
|
+
this.expressProvider.listen();
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
WhatsAppReceiverByWebHook = __decorate([
|
|
53
|
+
singleton(),
|
|
54
|
+
__metadata("design:paramtypes", [ExpressProvider,
|
|
55
|
+
WhatsAppRepository])
|
|
56
|
+
], WhatsAppReceiverByWebHook);
|
|
57
|
+
if (!WabotDevConnection.isTokenAvailable()) {
|
|
58
|
+
container.register(WhatsAppReceiver, {
|
|
59
|
+
useClass: WhatsAppReceiverByWebHook,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export { WhatsAppReceiverByWebHook };
|
|
@@ -1,23 +1,110 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import '../../core/chat/repository/IChatRepository.js';
|
|
2
|
+
import { ChatItem } from '../../core/chat/ChatItem.js';
|
|
3
|
+
import '../../core/user/IUserRepository.js';
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
this.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
5
|
+
class WhatsAppSender {
|
|
6
|
+
logger;
|
|
7
|
+
chatRepository;
|
|
8
|
+
chatResolver;
|
|
9
|
+
whatsAppRepository;
|
|
10
|
+
constructor(logger, chatRepository, chatResolver, whatsAppRepository) {
|
|
11
|
+
this.logger = logger;
|
|
12
|
+
this.chatRepository = chatRepository;
|
|
13
|
+
this.chatResolver = chatResolver;
|
|
14
|
+
this.whatsAppRepository = whatsAppRepository;
|
|
15
|
+
}
|
|
16
|
+
handleSendRequest(request) {
|
|
17
|
+
throw new Error('Not implemented');
|
|
18
|
+
}
|
|
19
|
+
handleSendTemplateRequest(request) {
|
|
20
|
+
throw new Error('Not implemented');
|
|
21
|
+
}
|
|
22
|
+
handleGetWhatsAppTemplate(request) {
|
|
23
|
+
throw new Error('Not implemented');
|
|
24
|
+
}
|
|
25
|
+
async sendWhatsApp(request, options) {
|
|
26
|
+
try {
|
|
27
|
+
await this.handleSendRequest(request);
|
|
28
|
+
if (options?.writeChatMemory) {
|
|
29
|
+
await this.writePrivateChatMemory(request.message, request.to);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
this.logger.error(`Error sending WhatsApp message: ${error}`);
|
|
34
|
+
throw new Error(`Error sending WhatsApp message: ${error}`, { cause: error });
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
async sendWhatsAppTemplate(request, options) {
|
|
38
|
+
try {
|
|
39
|
+
await this.handleSendTemplateRequest(request);
|
|
40
|
+
if (options?.writeChatMemory) {
|
|
41
|
+
const message = await this.resolveTemplateToChatMessage(request);
|
|
42
|
+
await this.writePrivateChatMemory(message, request.to);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.logger.error(`Error sending WhatsApp message: ${error}`);
|
|
47
|
+
throw new Error(`Error sending WhatsApp message: ${error}`, { cause: error });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async getWhatsAppTemplate(request) {
|
|
51
|
+
try {
|
|
52
|
+
const template = await this.handleGetWhatsAppTemplate(request);
|
|
53
|
+
return template;
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.logger.error(error);
|
|
57
|
+
throw new Error('Error getting WhatsApp template:', { cause: error });
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async resolveTemplateToChatMessage(request) {
|
|
61
|
+
const template = await this.handleGetWhatsAppTemplate({
|
|
62
|
+
from: request.from,
|
|
63
|
+
templateName: request.templateMessage.templateName,
|
|
64
|
+
languageCode: request.templateMessage.languageCode,
|
|
65
|
+
});
|
|
66
|
+
if (!template) {
|
|
67
|
+
throw new Error(`WhatsAppTemplate with name ${request.templateMessage.templateName} and language ${request.templateMessage.languageCode} not found`);
|
|
68
|
+
}
|
|
69
|
+
const components = template.components
|
|
70
|
+
.filter((x) => x.text != null)
|
|
71
|
+
.map((x) => x.text)
|
|
72
|
+
.join('\n');
|
|
73
|
+
return {
|
|
74
|
+
text: this.replaceTemplateParameters(components, request.templateMessage.parameters),
|
|
75
|
+
senderName: request.senderName,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async writePrivateChatMemory(message, to) {
|
|
79
|
+
const chatConnection = {
|
|
80
|
+
id: to,
|
|
81
|
+
chatType: 'PRIVATE',
|
|
82
|
+
channelName: 'WhatsAppChannel',
|
|
83
|
+
};
|
|
84
|
+
const chat = await this.chatResolver.resolve(chatConnection);
|
|
85
|
+
const chatMemory = await this.chatRepository.findMemory(chat.id);
|
|
86
|
+
const chatItem = new ChatItem({
|
|
87
|
+
type: 'BOT_MESSAGE',
|
|
88
|
+
content: message,
|
|
89
|
+
});
|
|
90
|
+
await chatMemory.create(chatItem);
|
|
91
|
+
}
|
|
92
|
+
replaceTemplateParameters(template, data) {
|
|
93
|
+
let result = template;
|
|
94
|
+
data.forEach((param) => {
|
|
95
|
+
if (param.type === 'text' && param.parameter_name) {
|
|
96
|
+
const tag = `{{${param.parameter_name}}}`;
|
|
97
|
+
result = result.split(tag).join(param.text);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
data.forEach((param, index) => {
|
|
101
|
+
if (param.type === 'text') {
|
|
102
|
+
const tag = `{{${index + 1}}}`;
|
|
103
|
+
result = result.split(tag).join(param.text);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
22
109
|
|
|
23
110
|
export { WhatsAppSender };
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import { Logger } from '../../logger/Logger.js';
|
|
3
|
+
import { WhatsAppSender } from './WhatsAppSender.js';
|
|
4
|
+
import { ChatResolver } from '../../controller/channel/ChatResolver.js';
|
|
5
|
+
import '../../controller/channel/UserResolver.js';
|
|
6
|
+
import { singleton } from '../../injection/index.js';
|
|
7
|
+
import '../../controller/metadata/ControllerMetadataStore.js';
|
|
8
|
+
import { ChatRepository } from '../../core/chat/repository/IChatRepository.js';
|
|
9
|
+
import '../../core/user/IUserRepository.js';
|
|
10
|
+
import { WhatsAppRepository } from './WhatsAppRepository.js';
|
|
11
|
+
|
|
12
|
+
let WhatsAppSenderByCloudApi = class WhatsAppSenderByCloudApi extends WhatsAppSender {
|
|
13
|
+
constructor(chatRepository, chatResolver, whatsAppRepository) {
|
|
14
|
+
super(new Logger('wabot:whatsapp-sender-by-cloud-api'), chatRepository, chatResolver, whatsAppRepository);
|
|
15
|
+
}
|
|
16
|
+
async handleSendRequest(request) {
|
|
17
|
+
const whatsApp = await this.whatsAppRepository.findByBusinessNumber(request.from);
|
|
18
|
+
if (!whatsApp) {
|
|
19
|
+
throw new Error(`not found WhatsApp with bussiness number '${request.from}'`);
|
|
20
|
+
}
|
|
21
|
+
const businessNumber = whatsApp.getBussinessNumber(request.from);
|
|
22
|
+
const url = `https://graph.facebook.com/v23.0/${businessNumber.id}/messages`;
|
|
23
|
+
const payload = {
|
|
24
|
+
messaging_product: 'whatsapp',
|
|
25
|
+
recipient_type: 'individual',
|
|
26
|
+
to: request.to,
|
|
27
|
+
type: 'text',
|
|
28
|
+
text: {
|
|
29
|
+
preview_url: false,
|
|
30
|
+
body: request.message.text,
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
const response = await fetch(url, {
|
|
34
|
+
method: 'POST',
|
|
35
|
+
headers: {
|
|
36
|
+
Authorization: `Bearer ${whatsApp.getAccessToken()}`,
|
|
37
|
+
'Content-Type': 'application/json',
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify(payload),
|
|
40
|
+
});
|
|
41
|
+
const data = await response.json();
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
throw new Error(JSON.stringify(data));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async handleSendTemplateRequest(request) {
|
|
47
|
+
const whatsApp = await this.whatsAppRepository.findByBusinessNumber(request.from);
|
|
48
|
+
if (!whatsApp) {
|
|
49
|
+
throw new Error(`not found WhatsApp with bussiness number '${request.from}'`);
|
|
50
|
+
}
|
|
51
|
+
const businessNumber = whatsApp.getBussinessNumber(request.from);
|
|
52
|
+
const payload = {
|
|
53
|
+
messaging_product: 'whatsapp',
|
|
54
|
+
recipient_type: 'individual',
|
|
55
|
+
to: request.to,
|
|
56
|
+
type: 'template',
|
|
57
|
+
template: {
|
|
58
|
+
name: request.templateMessage.templateName,
|
|
59
|
+
language: {
|
|
60
|
+
code: request.templateMessage.languageCode,
|
|
61
|
+
},
|
|
62
|
+
components: [
|
|
63
|
+
{
|
|
64
|
+
type: 'body',
|
|
65
|
+
parameters: request.templateMessage.parameters,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
const response = await fetch(`https://graph.facebook.com/v23.0/${businessNumber.id}/messages`, {
|
|
71
|
+
method: 'POST',
|
|
72
|
+
headers: {
|
|
73
|
+
Authorization: `Bearer ${whatsApp.getAccessToken()}`,
|
|
74
|
+
'Content-Type': 'application/json',
|
|
75
|
+
},
|
|
76
|
+
body: JSON.stringify(payload),
|
|
77
|
+
});
|
|
78
|
+
const data = await response.json();
|
|
79
|
+
if (!response.ok) {
|
|
80
|
+
throw new Error(JSON.stringify(data));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async handleGetWhatsAppTemplate(request) {
|
|
84
|
+
const whatsApp = await this.whatsAppRepository.findByBusinessNumber(request.from);
|
|
85
|
+
if (!whatsApp) {
|
|
86
|
+
throw new Error(`not found WhatsApp with bussiness number '${request.from}'`);
|
|
87
|
+
}
|
|
88
|
+
const businessAccount = whatsApp.getBusinessAccount();
|
|
89
|
+
try {
|
|
90
|
+
// Make API call to WhatsApp Cloud API to get templates
|
|
91
|
+
const response = await fetch(`https://graph.facebook.com/v23.0/${businessAccount.id}/message_templates?name=${request.templateName}&language=${request.languageCode}&limit=1`, {
|
|
92
|
+
method: 'GET',
|
|
93
|
+
headers: {
|
|
94
|
+
Authorization: `Bearer ${whatsApp.getAccessToken()}`,
|
|
95
|
+
'Content-Type': 'application/json',
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
const data = (await response.json());
|
|
99
|
+
if (!response.ok) {
|
|
100
|
+
throw new Error(JSON.stringify(data));
|
|
101
|
+
}
|
|
102
|
+
const template = data.data[0] ?? null;
|
|
103
|
+
return template;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error('Failed to get WhatsApp template:', error);
|
|
107
|
+
throw error;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
WhatsAppSenderByCloudApi = __decorate([
|
|
112
|
+
singleton(),
|
|
113
|
+
__metadata("design:paramtypes", [ChatRepository,
|
|
114
|
+
ChatResolver,
|
|
115
|
+
WhatsAppRepository])
|
|
116
|
+
], WhatsAppSenderByCloudApi);
|
|
117
|
+
|
|
118
|
+
export { WhatsAppSenderByCloudApi };
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { __decorate, __metadata } from 'tslib';
|
|
2
|
+
import { WhatsAppSender } from './WhatsAppSender.js';
|
|
3
|
+
import { ChatResolver } from '../../controller/channel/ChatResolver.js';
|
|
4
|
+
import '../../controller/channel/UserResolver.js';
|
|
5
|
+
import { singleton } from '../../injection/index.js';
|
|
6
|
+
import '../../controller/metadata/ControllerMetadataStore.js';
|
|
7
|
+
import { ChatRepository } from '../../core/chat/repository/IChatRepository.js';
|
|
8
|
+
import '../../core/user/IUserRepository.js';
|
|
9
|
+
import { Logger } from '../../logger/Logger.js';
|
|
10
|
+
import { WabotDevConnection } from '../wabot/WabotDevConnection.js';
|
|
11
|
+
import { devEmitEvent } from '../wabot/WabotDevSocketContracts.js';
|
|
12
|
+
import { WhatsAppRepository } from './WhatsAppRepository.js';
|
|
13
|
+
|
|
14
|
+
let WhatsAppSenderByDevConnection = class WhatsAppSenderByDevConnection extends WhatsAppSender {
|
|
15
|
+
wabotDevConnection;
|
|
16
|
+
constructor(wabotDevConnection, chatRepository, chatResolver, whatsAppRepository) {
|
|
17
|
+
super(new Logger('wabot:whatsapp-sender-by-dev-connection'), chatRepository, chatResolver, whatsAppRepository);
|
|
18
|
+
this.wabotDevConnection = wabotDevConnection;
|
|
19
|
+
}
|
|
20
|
+
async handleSendRequest(request) {
|
|
21
|
+
const socket = await this.wabotDevConnection.getSocket();
|
|
22
|
+
const req = {
|
|
23
|
+
from: request.from,
|
|
24
|
+
to: request.to,
|
|
25
|
+
message: request.message,
|
|
26
|
+
};
|
|
27
|
+
const ack = await socket.emitWithAck(devEmitEvent.DEV_SEND_WHATSAPP, req);
|
|
28
|
+
if (ack != 'OK') {
|
|
29
|
+
throw new Error(`Error sending WhatsApp template: ${ack}`);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async handleSendTemplateRequest(request) {
|
|
33
|
+
const socket = await this.wabotDevConnection.getSocket();
|
|
34
|
+
const req = {
|
|
35
|
+
from: request.from,
|
|
36
|
+
to: request.to,
|
|
37
|
+
message: request.templateMessage,
|
|
38
|
+
};
|
|
39
|
+
const ack = await socket.emitWithAck(devEmitEvent.DEV_SEND_WHATSAPP_TEMPLATE, req);
|
|
40
|
+
if (ack != 'OK') {
|
|
41
|
+
throw new Error(`Error sending WhatsApp template: ${ack}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async handleGetWhatsAppTemplate(request) {
|
|
45
|
+
throw new Error('Not implemented');
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
WhatsAppSenderByDevConnection = __decorate([
|
|
49
|
+
singleton(),
|
|
50
|
+
__metadata("design:paramtypes", [WabotDevConnection,
|
|
51
|
+
ChatRepository,
|
|
52
|
+
ChatResolver,
|
|
53
|
+
WhatsAppRepository])
|
|
54
|
+
], WhatsAppSenderByDevConnection);
|
|
55
|
+
|
|
56
|
+
export { WhatsAppSenderByDevConnection };
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
import { ChatItem } from '../core/chat/ChatItem.js';
|
|
2
1
|
import '../core/chat/repository/IChatRepository.js';
|
|
2
|
+
import { ChatItem } from '../core/chat/ChatItem.js';
|
|
3
3
|
import '../core/user/IUserRepository.js';
|
|
4
|
-
import 'reflect-metadata';
|
|
5
|
-
import '../injection/index.js';
|
|
6
|
-
import '../mindset/metadata/MindsetMetadataStore.js';
|
|
7
|
-
import '../mindset/MindsetOperator.js';
|
|
8
4
|
|
|
9
5
|
class ChatBotAdapter {
|
|
10
6
|
mindset;
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import 'reflect-metadata';
|
|
2
1
|
import { container, inject } from '../../injection/index.js';
|
|
3
|
-
import '../../mindset/metadata/MindsetMetadataStore.js';
|
|
4
|
-
import '../../core/chat/repository/IChatRepository.js';
|
|
5
|
-
import '../../core/user/IUserRepository.js';
|
|
6
|
-
import '../../mindset/MindsetOperator.js';
|
|
7
2
|
import { v4 } from 'uuid';
|
|
8
3
|
import { ChatBotMetadataStore } from './ChatBotMetadataStore.js';
|
|
9
4
|
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
2
|
import { singleton } from '../../injection/index.js';
|
|
3
|
-
import 'reflect-metadata';
|
|
4
|
-
import '../../mindset/metadata/MindsetMetadataStore.js';
|
|
5
|
-
import '../../core/chat/repository/IChatRepository.js';
|
|
6
|
-
import '../../core/user/IUserRepository.js';
|
|
7
|
-
import '../../mindset/MindsetOperator.js';
|
|
8
3
|
|
|
9
4
|
let ChatBotMetadataStore = class ChatBotMetadataStore {
|
|
10
5
|
chatBots = [];
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { __decorate } from 'tslib';
|
|
2
2
|
import { singleton } from '../../injection/index.js';
|
|
3
|
-
import '../../core/chat/repository/IChatRepository.js';
|
|
4
|
-
import '../../core/user/IUserRepository.js';
|
|
5
3
|
|
|
6
4
|
let ControllerMetadataStore = class ControllerMetadataStore {
|
|
7
5
|
channels = new Map();
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { container, injectable } from '../../../injection/index.js';
|
|
2
|
-
import '../../../core/chat/repository/IChatRepository.js';
|
|
3
|
-
import '../../../core/user/IUserRepository.js';
|
|
4
2
|
import { ControllerMetadataStore } from '../ControllerMetadataStore.js';
|
|
5
3
|
|
|
6
4
|
function chatController(config) {
|
|
@@ -1,22 +1,32 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
6
|
-
getId() {
|
|
1
|
+
import { Storable } from './Storable.js';
|
|
2
|
+
|
|
3
|
+
class Entity extends Storable {
|
|
4
|
+
get id() {
|
|
7
5
|
if (!this.data.id) {
|
|
8
6
|
throw new Error('id is required');
|
|
9
7
|
}
|
|
10
8
|
return this.data.id;
|
|
11
9
|
}
|
|
12
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated use id
|
|
12
|
+
*/
|
|
13
|
+
getId() {
|
|
14
|
+
return this.id;
|
|
15
|
+
}
|
|
16
|
+
get createdAt() {
|
|
13
17
|
if (!this.data.createdAt) {
|
|
14
18
|
throw new Error('createdAt is required');
|
|
15
19
|
}
|
|
16
20
|
return new Date(this.data.createdAt);
|
|
17
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated use createdAt
|
|
24
|
+
*/
|
|
25
|
+
getCreatedAt() {
|
|
26
|
+
return this.createdAt;
|
|
27
|
+
}
|
|
18
28
|
update(newData) {
|
|
19
|
-
this.data = newData;
|
|
29
|
+
this.data = { ...this.data, ...newData, updatedAt: new Date().getTime() };
|
|
20
30
|
}
|
|
21
31
|
wasCreated() {
|
|
22
32
|
return !!this.data.createdAt || !!this.data.id;
|
|
@@ -33,5 +43,10 @@ class Persistent {
|
|
|
33
43
|
this.data.discardedAt = new Date().getTime();
|
|
34
44
|
}
|
|
35
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Should use Entity
|
|
48
|
+
*/
|
|
49
|
+
class Persistent extends Entity {
|
|
50
|
+
}
|
|
36
51
|
|
|
37
|
-
export { Persistent };
|
|
52
|
+
export { Entity, Persistent };
|