@wabot-dev/framework 0.1.0-beta.2 → 0.1.0-beta.4

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.
Files changed (59) hide show
  1. package/dist/src/ai/deepseek/DeepSeekChatBotAdapter.js +3 -5
  2. package/dist/src/ai/openia/OpenaiChatBotAdapter.js +3 -5
  3. package/dist/src/channels/cmd/@cmd.js +0 -4
  4. package/dist/src/channels/cmd/CmdChannel.js +0 -4
  5. package/dist/src/channels/express/ExpressProvider.js +46 -0
  6. package/dist/src/channels/http/HttpServerProvider.js +31 -0
  7. package/dist/src/channels/{socket-io → socket}/@socket.js +0 -4
  8. package/dist/src/channels/{socket-io → socket}/SocketChannel.js +12 -11
  9. package/dist/src/channels/socket/SocketServerProvider.js +50 -0
  10. package/dist/src/channels/telegram/@telegram.js +0 -4
  11. package/dist/src/channels/telegram/TelegramChannel.js +0 -4
  12. package/dist/src/channels/wabot/WabotDevConnection.js +57 -0
  13. package/dist/src/channels/{whatsapp/WhatsAppDevSocketContracts.js → wabot/WabotDevSocketContracts.js} +3 -3
  14. package/dist/src/channels/whatsapp/@whatsapp.js +0 -4
  15. package/dist/src/channels/whatsapp/EnvWhatsAppRepository.js +49 -0
  16. package/dist/src/channels/whatsapp/PgWhatsAppRepository.js +41 -0
  17. package/dist/src/channels/whatsapp/WhatsApp.js +32 -0
  18. package/dist/src/channels/whatsapp/WhatsAppChannel.js +33 -32
  19. package/dist/src/channels/whatsapp/{WhatsAppConnection.js → WhatsAppReceiver.js} +4 -6
  20. package/dist/src/channels/whatsapp/WhatsAppReceiverByDevConnection.js +32 -0
  21. package/dist/src/channels/whatsapp/WhatsAppReceiverByWebHook.js +63 -0
  22. package/dist/src/channels/whatsapp/WhatsAppRepository.js +10 -0
  23. package/dist/src/channels/whatsapp/WhatsAppSender.js +76 -17
  24. package/dist/src/channels/whatsapp/WhatsAppSenderByCloudApi.js +124 -0
  25. package/dist/src/channels/whatsapp/WhatsAppSenderByDevConnection.js +61 -0
  26. package/dist/src/chatbot/ChatBotAdapter.js +1 -5
  27. package/dist/src/chatbot/metadata/@chatBot.js +0 -5
  28. package/dist/src/chatbot/metadata/ChatBotMetadataStore.js +0 -5
  29. package/dist/src/controller/metadata/ControllerMetadataStore.js +0 -2
  30. package/dist/src/controller/metadata/controller/@chatController.js +0 -2
  31. package/dist/src/core/IMessageContext.js +0 -2
  32. package/dist/src/env/WabotEnv.js +6 -0
  33. package/dist/src/index.d.ts +270 -202
  34. package/dist/src/index.js +28 -27
  35. package/dist/src/mindset/MindsetOperator.js +0 -2
  36. package/dist/src/mindset/metadata/MindsetMetadataStore.js +0 -2
  37. package/dist/src/mindset/metadata/mindsets/@mindset.js +0 -2
  38. package/dist/src/mindset/metadata/modules/@mindsetModule.js +0 -2
  39. package/dist/src/pre-made/module/authentication/requests/SendOneTimePasswordRequest.js +0 -2
  40. package/dist/src/pre-made/module/authentication/requests/ValidateOneTimePasswordRequest.js +0 -2
  41. package/dist/src/pre-made/module/register-user/requests/RegisterUserWithEmailRequest.js +0 -2
  42. package/dist/src/pre-made/repository/chat/pg/PgChatMemory.js +1 -7
  43. package/dist/src/pre-made/repository/chat/pg/PgChatRepository.js +0 -5
  44. package/dist/src/pre-made/repository/user/pg/PgUserRepository.js +0 -5
  45. package/dist/src/repository/pg/PgCrudRepository.js +0 -1
  46. package/dist/src/server/prepareChatContainer.js +4 -4
  47. package/dist/src/server/runChannel.js +2 -10
  48. package/dist/src/server/runServer.js +0 -43
  49. package/package.json +2 -4
  50. package/dist/src/channels/whatsapp/WhatsAppDevConnection.js +0 -69
  51. package/dist/src/channels/whatsapp/WhatsAppProdConnection.js +0 -39
  52. package/dist/src/controller/express/Express.js +0 -5
  53. package/dist/src/controller/socket.io/SocketIO.js +0 -5
  54. package/dist/src/pre-made/repository/chat/sqlite/SqliteChatMemory.js +0 -23
  55. package/dist/src/pre-made/repository/chat/sqlite/SqliteChatRepository.js +0 -30
  56. package/dist/src/pre-made/repository/user/sqlite/SqliteUserRepository.js +0 -23
  57. package/dist/src/repository/sqlite/SqliteCrudRepository.js +0 -85
  58. package/dist/src/repository/sqlite/SqlitePersistentMapper.js +0 -17
  59. /package/dist/src/channels/{socket-io → socket}/SocketChannelConfig.js +0 -0
@@ -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 };
@@ -0,0 +1,10 @@
1
+ class WhatsAppRepository {
2
+ findBySlug(slug) {
3
+ throw new Error('Method not implemented.');
4
+ }
5
+ findByBusinessNumber(number) {
6
+ throw new Error('Method not implemented.');
7
+ }
8
+ }
9
+
10
+ export { WhatsAppRepository };
@@ -1,23 +1,82 @@
1
- import { __decorate, __metadata } from 'tslib';
2
- import { singleton } from 'tsyringe';
1
+ import '../../core/chat/repository/IChatRepository.js';
2
+ import { ChatItem } from '../../core/chat/ChatItem.js';
3
+ import '../../core/user/IUserRepository.js';
3
4
 
4
- let WhatsAppSender = class WhatsAppSender {
5
- wabotEnv;
6
- whatsAppConection;
7
- constructor(wabotEnv, devConnection, prodConnection) {
8
- this.wabotEnv = wabotEnv;
9
- this.whatsAppConection = this.wabotEnv.isProduction() ? prodConnection : devConnection;
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;
10
15
  }
11
- async send(businessNumber, to, message) {
12
- this.whatsAppConection.sendWhatsApp(businessNumber, to, message);
16
+ async sendWhatsApp(request, options) {
17
+ try {
18
+ await this.handleSendRequest(request);
19
+ if (options?.writeChatMemory) {
20
+ await this.writePrivateChatMemory(request.message, request.to);
21
+ }
22
+ }
23
+ catch (error) {
24
+ this.logger.error(`Error sending WhatsApp message: ${error}`);
25
+ }
13
26
  }
14
- async sendTemplate(businessNumber, to, templateMessage) {
15
- this.whatsAppConection.sendWhatsAppTemplate(businessNumber, to, templateMessage);
27
+ async sendWhatsAppTemplate(request, options) {
28
+ try {
29
+ await this.handleSendTemplateRequest(request);
30
+ if (options?.writeChatMemory) {
31
+ const message = await this.resolveTemplateToChatMessage(request);
32
+ await this.writePrivateChatMemory(message, request.to);
33
+ }
34
+ }
35
+ catch (error) {
36
+ this.logger.error(`Error sending WhatsApp message: ${error}`);
37
+ }
16
38
  }
17
- };
18
- WhatsAppSender = __decorate([
19
- singleton(),
20
- __metadata("design:paramtypes", [Function, Function, Function])
21
- ], WhatsAppSender);
39
+ async getWhatsAppTemplate(request) {
40
+ try {
41
+ const template = await this.handleGetWhatsAppTemplate(request);
42
+ return template;
43
+ }
44
+ catch (error) {
45
+ this.logger.error(error);
46
+ throw new Error('Error getting WhatsApp template:', { cause: error });
47
+ }
48
+ }
49
+ async resolveTemplateToChatMessage(request) {
50
+ const template = await this.handleGetWhatsAppTemplate({
51
+ from: request.from,
52
+ templateName: request.templateMessage.templateName,
53
+ languageCode: request.templateMessage.languageCode,
54
+ });
55
+ if (!template) {
56
+ throw new Error(`WhatsAppTemplate with name ${request.templateMessage.templateName} and language ${request.templateMessage.languageCode} not found`);
57
+ }
58
+ return {
59
+ text: template.components
60
+ .filter((x) => x.text != null)
61
+ .map((x) => x.text)
62
+ .join('\n'),
63
+ senderName: request.senderName,
64
+ };
65
+ }
66
+ async writePrivateChatMemory(message, to) {
67
+ const chatConnection = {
68
+ id: to,
69
+ chatType: 'PRIVATE',
70
+ channelName: 'WhatsAppChannel',
71
+ };
72
+ const chat = await this.chatResolver.resolve(chatConnection);
73
+ const chatMemory = await this.chatRepository.findMemory(chat.getId());
74
+ const chatItem = new ChatItem({
75
+ type: 'BOT_MESSAGE',
76
+ content: message,
77
+ });
78
+ await chatMemory.create(chatItem);
79
+ }
80
+ }
22
81
 
23
82
  export { WhatsAppSender };
@@ -0,0 +1,124 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { Logger } from '../../logger/Logger.js';
3
+ import { WhatsAppSender } from './WhatsAppSender.js';
4
+ import { ChatRepository } from '../../core/chat/repository/IChatRepository.js';
5
+ import '../../core/user/IUserRepository.js';
6
+ import { ChatResolver } from '../../controller/channel/ChatResolver.js';
7
+ import '../../controller/channel/UserResolver.js';
8
+ import { singleton, container } from '../../injection/index.js';
9
+ import '../../controller/metadata/ControllerMetadataStore.js';
10
+ import { WhatsAppRepository } from './WhatsAppRepository.js';
11
+ import { WabotDevConnection } from '../wabot/WabotDevConnection.js';
12
+
13
+ let WhatsAppSenderByCloudApi = class WhatsAppSenderByCloudApi extends WhatsAppSender {
14
+ constructor(chatRepository, chatResolver, whatsAppRepository) {
15
+ super(new Logger('wabot:whatsapp-sender-by-cloud-api'), chatRepository, chatResolver, whatsAppRepository);
16
+ }
17
+ async handleSendRequest(request) {
18
+ const whatsApp = await this.whatsAppRepository.findByBusinessNumber(request.from);
19
+ if (!whatsApp) {
20
+ throw new Error(`not found WhatsApp with bussiness number '${request.from}'`);
21
+ }
22
+ const businessNumber = whatsApp.getBussinessNumber(request.from);
23
+ const url = `https://graph.facebook.com/v23.0/${businessNumber.id}/messages`;
24
+ const payload = {
25
+ messaging_product: 'whatsapp',
26
+ recipient_type: 'individual',
27
+ to: request.to,
28
+ type: 'text',
29
+ text: {
30
+ preview_url: false,
31
+ body: request.message.text,
32
+ },
33
+ };
34
+ const response = await fetch(url, {
35
+ method: 'POST',
36
+ headers: {
37
+ Authorization: `Bearer ${whatsApp.getAccessToken()}`,
38
+ 'Content-Type': 'application/json',
39
+ },
40
+ body: JSON.stringify(payload),
41
+ });
42
+ const data = await response.json();
43
+ if (!response.ok) {
44
+ throw new Error(JSON.stringify(data));
45
+ }
46
+ }
47
+ async handleSendTemplateRequest(request) {
48
+ const whatsApp = await this.whatsAppRepository.findByBusinessNumber(request.from);
49
+ if (!whatsApp) {
50
+ throw new Error(`not found WhatsApp with bussiness number '${request.from}'`);
51
+ }
52
+ const businessNumber = whatsApp.getBussinessNumber(request.from);
53
+ const payload = {
54
+ messaging_product: 'whatsapp',
55
+ recipient_type: 'individual',
56
+ to: request.to,
57
+ type: 'template',
58
+ template: {
59
+ name: request.templateMessage.templateName,
60
+ language: {
61
+ code: request.templateMessage.languageCode,
62
+ },
63
+ components: [
64
+ {
65
+ type: 'body',
66
+ parameters: request.templateMessage.parameters,
67
+ },
68
+ ],
69
+ },
70
+ };
71
+ const response = await fetch(`https://graph.facebook.com/v23.0/${businessNumber.id}/messages`, {
72
+ method: 'POST',
73
+ headers: {
74
+ Authorization: `Bearer ${whatsApp.getAccessToken()}`,
75
+ 'Content-Type': 'application/json',
76
+ },
77
+ body: JSON.stringify(payload),
78
+ });
79
+ const data = await response.json();
80
+ if (!response.ok) {
81
+ throw new Error(JSON.stringify(data));
82
+ }
83
+ }
84
+ async handleGetWhatsAppTemplate(request) {
85
+ const whatsApp = await this.whatsAppRepository.findByBusinessNumber(request.from);
86
+ if (!whatsApp) {
87
+ throw new Error(`not found WhatsApp with bussiness number '${request.from}'`);
88
+ }
89
+ const businessAccount = whatsApp.getBusinessAccount();
90
+ try {
91
+ // Make API call to WhatsApp Cloud API to get templates
92
+ const response = await fetch(`https://graph.facebook.com/v23.0/${businessAccount.id}/message_templates?name=${request.templateName}&language=${request.languageCode}&limit=1`, {
93
+ method: 'GET',
94
+ headers: {
95
+ Authorization: `Bearer ${whatsApp.getAccessToken()}`,
96
+ 'Content-Type': 'application/json',
97
+ },
98
+ });
99
+ const data = (await response.json());
100
+ if (!response.ok) {
101
+ throw new Error(JSON.stringify(data));
102
+ }
103
+ const template = data.data[0] ?? null;
104
+ return template;
105
+ }
106
+ catch (error) {
107
+ console.error('Failed to get WhatsApp template:', error);
108
+ throw error;
109
+ }
110
+ }
111
+ };
112
+ WhatsAppSenderByCloudApi = __decorate([
113
+ singleton(),
114
+ __metadata("design:paramtypes", [ChatRepository,
115
+ ChatResolver,
116
+ WhatsAppRepository])
117
+ ], WhatsAppSenderByCloudApi);
118
+ if (!WabotDevConnection.isTokenAvailable()) {
119
+ container.register(WhatsAppSender, {
120
+ useClass: WhatsAppSenderByCloudApi,
121
+ });
122
+ }
123
+
124
+ export { WhatsAppSenderByCloudApi };
@@ -0,0 +1,61 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { WhatsAppSender } from './WhatsAppSender.js';
3
+ import { WabotDevConnection } from '../wabot/WabotDevConnection.js';
4
+ import { devEmitEvent } from '../wabot/WabotDevSocketContracts.js';
5
+ import { Logger } from '../../logger/Logger.js';
6
+ import { ChatRepository } from '../../core/chat/repository/IChatRepository.js';
7
+ import '../../core/user/IUserRepository.js';
8
+ import { singleton, container } from '../../injection/index.js';
9
+ import { ChatResolver } from '../../controller/channel/ChatResolver.js';
10
+ import '../../controller/channel/UserResolver.js';
11
+ import '../../controller/metadata/ControllerMetadataStore.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
+ if (WabotDevConnection.isTokenAvailable()) {
56
+ container.register(WhatsAppSender, {
57
+ useClass: WhatsAppSenderByDevConnection,
58
+ });
59
+ }
60
+
61
+ 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,5 +1,3 @@
1
- import './user/IUserRepository.js';
2
-
3
1
  class MessageContext {
4
2
  message;
5
3
  chat;
@@ -12,6 +12,12 @@ let WabotEnv = class WabotEnv {
12
12
  isProduction() {
13
13
  return this.envType === 'production';
14
14
  }
15
+ requireString(varName) {
16
+ const value = process.env[varName];
17
+ if (!value)
18
+ throw new Error(`Env Variable ${varName} is required`);
19
+ return value;
20
+ }
15
21
  };
16
22
  WabotEnv = __decorate([
17
23
  singleton(),