@wabot-dev/framework 0.0.13 → 0.0.16

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.
@@ -4,6 +4,8 @@ import { container } from '../../injection/index.js';
4
4
  import '../../core/chat/repository/IChatRepository.js';
5
5
  import '../../core/user/IUserRepository.js';
6
6
  import { ControllerMetadataStore } from '../../controller/metadata/ControllerMetadataStore.js';
7
+ import 'express';
8
+ import 'socket.io';
7
9
  import { CmdChannel } from './CmdChannel.js';
8
10
 
9
11
  function cmd() {
@@ -5,6 +5,8 @@ import { injectable } from '../../injection/index.js';
5
5
  import '../../core/chat/repository/IChatRepository.js';
6
6
  import '../../core/user/IUserRepository.js';
7
7
  import '../../controller/metadata/ControllerMetadataStore.js';
8
+ import 'express';
9
+ import 'socket.io';
8
10
  import * as readline from 'readline';
9
11
 
10
12
  var CmdChannel_1;
@@ -4,6 +4,8 @@ import '../../controller/channel/UserResolver.js';
4
4
  import '../../core/chat/repository/IChatRepository.js';
5
5
  import '../../core/user/IUserRepository.js';
6
6
  import { ControllerMetadataStore } from '../../controller/metadata/ControllerMetadataStore.js';
7
+ import 'express';
8
+ import 'socket.io';
7
9
  import { TelegramChannel } from './TelegramChannel.js';
8
10
  import { TelegramChannelConfig } from './TelegramChannelConfig.js';
9
11
 
@@ -5,6 +5,8 @@ import { injectable } from '../../injection/index.js';
5
5
  import '../../core/chat/repository/IChatRepository.js';
6
6
  import '../../core/user/IUserRepository.js';
7
7
  import '../../controller/metadata/ControllerMetadataStore.js';
8
+ import 'express';
9
+ import 'socket.io';
8
10
  import { Bot } from 'grammy';
9
11
  import { TelegramChannelConfig } from './TelegramChannelConfig.js';
10
12
 
@@ -0,0 +1,24 @@
1
+ import { container } from '../../injection/index.js';
2
+ import { WhatsappChannelConfig } from './WhatsAppChannelConfig.js';
3
+ import '../../controller/channel/ChatResolver.js';
4
+ import '../../controller/channel/UserResolver.js';
5
+ import '../../core/chat/repository/IChatRepository.js';
6
+ import '../../core/user/IUserRepository.js';
7
+ import { ControllerMetadataStore } from '../../controller/metadata/ControllerMetadataStore.js';
8
+ import 'express';
9
+ import 'socket.io';
10
+ import { WhatsAppChannel } from './WhatsAppChannel.js';
11
+
12
+ function whatsapp(config) {
13
+ return function (target, propertyKey) {
14
+ const store = container.resolve(ControllerMetadataStore);
15
+ store.saveChannelMetadata({
16
+ channelConstructor: WhatsAppChannel,
17
+ functionName: propertyKey.toString(),
18
+ controllerConstructor: target.constructor,
19
+ channelConfig: new WhatsappChannelConfig(config.number),
20
+ });
21
+ };
22
+ }
23
+
24
+ export { whatsapp };
@@ -0,0 +1,63 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { ChatResolver } from '../../controller/channel/ChatResolver.js';
3
+ import { UserResolver } from '../../controller/channel/UserResolver.js';
4
+ import { injectable } from '../../injection/index.js';
5
+ import '../../core/chat/repository/IChatRepository.js';
6
+ import '../../core/user/IUserRepository.js';
7
+ import '../../controller/metadata/ControllerMetadataStore.js';
8
+ import 'express';
9
+ import 'socket.io';
10
+ import { WabotEnv } from '../../env/WabotEnv.js';
11
+ import { Logger } from '../../logger/Logger.js';
12
+ import { WhatsappChannelConfig } from './WhatsAppChannelConfig.js';
13
+ import { WhatsAppDevConnection } from './WhatsAppDevConnection.js';
14
+ import { WhatsAppProdConnection } from './WhatsAppProdConnection.js';
15
+
16
+ let WhatsAppChannel = class WhatsAppChannel {
17
+ config;
18
+ chatResolver;
19
+ userResolver;
20
+ wabotEnv;
21
+ logger = new Logger('wabot:whatsapp-channel');
22
+ whatsAppConection;
23
+ constructor(config, chatResolver, userResolver, wabotEnv, devConnection, prodConnection) {
24
+ this.config = config;
25
+ this.chatResolver = chatResolver;
26
+ this.userResolver = userResolver;
27
+ this.wabotEnv = wabotEnv;
28
+ this.whatsAppConection = this.wabotEnv.isProduction() ? prodConnection : devConnection;
29
+ }
30
+ listen(callback) {
31
+ this.whatsAppConection.listenMessage(this.config.number, async (message) => {
32
+ try {
33
+ const chat = await this.chatResolver.resolve(message.chatConnection);
34
+ const user = await this.userResolver.resolve(message.userConnection);
35
+ callback({
36
+ chat,
37
+ user,
38
+ message,
39
+ reply: (replyMessage) => {
40
+ this.whatsAppConection.sendWhatsApp(this.config.number, message.userConnection.id, replyMessage);
41
+ },
42
+ });
43
+ }
44
+ catch (err) {
45
+ this.logger.error(err);
46
+ }
47
+ });
48
+ }
49
+ connect() {
50
+ this.whatsAppConection.connect();
51
+ }
52
+ };
53
+ WhatsAppChannel = __decorate([
54
+ injectable(),
55
+ __metadata("design:paramtypes", [WhatsappChannelConfig,
56
+ ChatResolver,
57
+ UserResolver,
58
+ WabotEnv,
59
+ WhatsAppDevConnection,
60
+ WhatsAppProdConnection])
61
+ ], WhatsAppChannel);
62
+
63
+ export { WhatsAppChannel };
@@ -0,0 +1,8 @@
1
+ class WhatsappChannelConfig {
2
+ number;
3
+ constructor(number) {
4
+ this.number = number;
5
+ }
6
+ }
7
+
8
+ export { WhatsappChannelConfig };
@@ -0,0 +1,61 @@
1
+ import 'debug';
2
+
3
+ class WhatsAppConnection {
4
+ logger;
5
+ listeners = new Map();
6
+ constructor(logger) {
7
+ this.logger = logger;
8
+ }
9
+ listenMessage(businessNumber, listener) {
10
+ this.listeners.set(businessNumber, listener);
11
+ }
12
+ async handlePayload(payload) {
13
+ try {
14
+ for (const entry of payload.entry) {
15
+ for (const change of entry.changes) {
16
+ if (change.field !== 'messages' || !change.value.messages || !change.value.contacts) {
17
+ continue;
18
+ }
19
+ for (const message of change.value.messages) {
20
+ const contact = change.value.contacts.find((x) => x.wa_id === message.from);
21
+ if (!contact) {
22
+ continue;
23
+ }
24
+ await this.emmitMessage(change.value.metadata, message, contact);
25
+ }
26
+ }
27
+ }
28
+ }
29
+ catch (err) {
30
+ this.logger.error(err);
31
+ }
32
+ }
33
+ async emmitMessage(metadata, message, contact) {
34
+ const listener = this.listeners.get(metadata.display_phone_number);
35
+ if (!listener) {
36
+ return;
37
+ }
38
+ if (message.type !== 'text') {
39
+ this.logger.error(`message type ${message.type} is not supported yet`);
40
+ return;
41
+ }
42
+ const channelName = 'WhatsAppChannel';
43
+ const chatConnection = {
44
+ id: contact.wa_id,
45
+ chatType: 'PRIVATE',
46
+ channelName,
47
+ };
48
+ const userConnection = {
49
+ id: contact.wa_id,
50
+ channelName,
51
+ };
52
+ await listener({
53
+ chatConnection,
54
+ userConnection,
55
+ senderName: contact.profile.name,
56
+ text: message.text.body,
57
+ });
58
+ }
59
+ }
60
+
61
+ export { WhatsAppConnection };
@@ -0,0 +1,61 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { singleton } from '../../injection/index.js';
3
+ import { Logger } from '../../logger/Logger.js';
4
+ import { io } from 'socket.io-client';
5
+ import { WhatsAppConnection } from './WhatsAppConnection.js';
6
+ import { devWhatsappEmitEvent, devWhatsAppListentEvent } from './whatsAppDevSocketContracts.js';
7
+
8
+ let WhatsAppDevConnection = class WhatsAppDevConnection extends WhatsAppConnection {
9
+ devProxy;
10
+ devProxySocket;
11
+ devToken;
12
+ connected = false;
13
+ constructor() {
14
+ super(new Logger('wabot:whatsapp-dev-connection'));
15
+ this.devProxy = process.env.WABOT_DEV_PROXY ?? 'https://proxy.wabot.dev';
16
+ this.devToken = process.env.WABOT_DEV_TOKEN;
17
+ this.devProxySocket = io(this.devProxy, { autoConnect: false });
18
+ }
19
+ async sendWhatsApp(businessNumber, to, chatMessage) {
20
+ const req = {
21
+ from: businessNumber,
22
+ to,
23
+ message: chatMessage,
24
+ };
25
+ await this.devProxySocket.emitWithAck(devWhatsappEmitEvent.DEV_SEND_WHATSAPP, req);
26
+ }
27
+ connect() {
28
+ if (this.connected) {
29
+ return;
30
+ }
31
+ this.connected = true;
32
+ this.devProxySocket.connect();
33
+ this.devProxySocket.on('connect', async () => {
34
+ if (!this.devToken) {
35
+ return;
36
+ }
37
+ try {
38
+ const req = {
39
+ token: this.devToken,
40
+ };
41
+ const ack = await this.devProxySocket.emitWithAck(devWhatsappEmitEvent.DEV_CONNECTION, req);
42
+ if (ack != 'OK') {
43
+ return this.logger.debug('dev connection fails');
44
+ }
45
+ this.devProxySocket.on(devWhatsAppListentEvent.DEV_WATSAPP_WEBHOOK, async (payload) => {
46
+ await this.handlePayload(payload);
47
+ });
48
+ return this.logger.debug('success dev connection');
49
+ }
50
+ catch (err) {
51
+ this.logger.error(err);
52
+ }
53
+ });
54
+ }
55
+ };
56
+ WhatsAppDevConnection = __decorate([
57
+ singleton(),
58
+ __metadata("design:paramtypes", [])
59
+ ], WhatsAppDevConnection);
60
+
61
+ export { WhatsAppDevConnection };
@@ -0,0 +1,36 @@
1
+ import { __decorate, __param, __metadata } from 'tslib';
2
+ import '../../controller/channel/ChatResolver.js';
3
+ import '../../controller/channel/UserResolver.js';
4
+ import { inject } from '../../injection/index.js';
5
+ import '../../core/chat/repository/IChatRepository.js';
6
+ import '../../core/user/IUserRepository.js';
7
+ import '../../controller/metadata/ControllerMetadataStore.js';
8
+ import { ExpressApp } from '../../controller/express/Express.js';
9
+ import 'socket.io';
10
+ import { singleton } from 'tsyringe';
11
+
12
+ let WhatsAppProdConnection = class WhatsAppProdConnection {
13
+ express;
14
+ constructor(express) {
15
+ this.express = express;
16
+ this.express.get('/try-express', (req, res) => {
17
+ res.status(200).json({ success: true });
18
+ });
19
+ }
20
+ listenMessage(businessNumber, listener) {
21
+ throw new Error('Method not implemented.');
22
+ }
23
+ sendWhatsApp(businessNumber, to, replyMessage) {
24
+ throw new Error('Method not implemented.');
25
+ }
26
+ connect() {
27
+ throw new Error('Method not implemented.');
28
+ }
29
+ };
30
+ WhatsAppProdConnection = __decorate([
31
+ singleton(),
32
+ __param(0, inject(ExpressApp)),
33
+ __metadata("design:paramtypes", [Function])
34
+ ], WhatsAppProdConnection);
35
+
36
+ export { WhatsAppProdConnection };
@@ -0,0 +1,9 @@
1
+ const devWhatsAppListentEvent = {
2
+ DEV_WATSAPP_WEBHOOK: 'dev-whatsapp-webhook',
3
+ };
4
+ const devWhatsappEmitEvent = {
5
+ DEV_CONNECTION: 'dev-connection',
6
+ DEV_SEND_WHATSAPP: 'dev-send-whatsapp',
7
+ };
8
+
9
+ export { devWhatsAppListentEvent, devWhatsappEmitEvent };
@@ -0,0 +1,5 @@
1
+ import 'express';
2
+
3
+ const ExpressApp = Symbol.for('ExpressApp');
4
+
5
+ export { ExpressApp };
@@ -0,0 +1,5 @@
1
+ import 'socket.io';
2
+
3
+ const SocketIoApp = Symbol.for('SocketIoApp');
4
+
5
+ export { SocketIoApp };
@@ -0,0 +1,21 @@
1
+ import { __decorate, __metadata } from 'tslib';
2
+ import { singleton } from 'tsyringe';
3
+
4
+ let WabotEnv = class WabotEnv {
5
+ envType;
6
+ constructor() {
7
+ this.envType = process.env.WABOT_ENV ?? 'development';
8
+ }
9
+ isDevelopment() {
10
+ return this.envType === 'development';
11
+ }
12
+ isProduction() {
13
+ return this.envType === 'production';
14
+ }
15
+ };
16
+ WabotEnv = __decorate([
17
+ singleton(),
18
+ __metadata("design:paramtypes", [])
19
+ ], WabotEnv);
20
+
21
+ export { WabotEnv };
@@ -1,12 +1,15 @@
1
1
  import InjectionToken from 'tsyringe/dist/typings/providers/injection-token';
2
2
  import DependencyContainer, { PreResolutionInterceptorCallback, PostResolutionInterceptorCallback } from 'tsyringe/dist/typings/types/dependency-container';
3
3
  import InterceptionOptions from 'tsyringe/dist/typings/types/interceptor-options';
4
+ import { Express } from 'express';
5
+ export { Express } from 'express';
4
6
  import * as tsyringe from 'tsyringe';
5
7
  import { DependencyContainer as DependencyContainer$1 } from 'tsyringe';
6
8
  export { DependencyContainer } from 'tsyringe';
7
9
  import { Pool } from 'pg';
8
10
  import { Database } from 'sqlite';
9
11
  import sqlite3 from 'sqlite3';
12
+ export { Server as SocketIo } from 'socket.io';
10
13
 
11
14
  interface IMindsetFunctionConfig {
12
15
  description: string;
@@ -423,6 +426,10 @@ declare class ControllerMetadataStore {
423
426
  } | null;
424
427
  }
425
428
 
429
+ declare const ExpressApp: unique symbol;
430
+
431
+ declare const SocketIoApp: unique symbol;
432
+
426
433
  declare class CmdChannel implements IChatChannel {
427
434
  private chatResolver;
428
435
  private userResolver;
@@ -453,6 +460,153 @@ declare class TelegramChannel implements IChatChannel {
453
460
  connect(): void;
454
461
  }
455
462
 
463
+ interface IWhatsappChannelConfig {
464
+ number: string;
465
+ proxy?: string;
466
+ }
467
+ declare class WhatsappChannelConfig implements IWhatsappChannelConfig {
468
+ number: string;
469
+ constructor(number: string);
470
+ }
471
+
472
+ declare function whatsapp(config: IWhatsappChannelConfig): (target: object, propertyKey: string | symbol) => void;
473
+
474
+ interface IWhatsAppWebhookPayload {
475
+ object: 'whatsapp_business_account';
476
+ entry: IEntry[];
477
+ }
478
+ interface IEntry {
479
+ id: string;
480
+ changes: IChange[];
481
+ }
482
+ type IChange = IMessagesChange;
483
+ interface IMessagesChange {
484
+ value: IMessagesChangeValue;
485
+ field: 'messages';
486
+ }
487
+ interface IMessagesChangeValue {
488
+ messaging_product: 'whatsapp';
489
+ metadata: IMessageMetadata;
490
+ contacts?: IWhatsAppContact[];
491
+ messages?: IWhatsAppMessage[];
492
+ }
493
+ interface IMessageMetadata {
494
+ display_phone_number: string;
495
+ phone_number_id: string;
496
+ }
497
+ interface IWhatsAppContact {
498
+ profile: {
499
+ name: string;
500
+ };
501
+ wa_id: string;
502
+ }
503
+ type IWhatsAppMessage = ITextMessage | IAudioMessage;
504
+ interface IBaseMessage {
505
+ from: string;
506
+ id: string;
507
+ timestamp: string;
508
+ type: string;
509
+ }
510
+ interface ITextMessage extends IBaseMessage {
511
+ type: 'text';
512
+ text: {
513
+ body: string;
514
+ };
515
+ }
516
+ interface IAudioMessage extends IBaseMessage {
517
+ type: 'audio';
518
+ audio: {
519
+ mime_type: string;
520
+ sha256: string;
521
+ id: string;
522
+ voice: boolean;
523
+ };
524
+ }
525
+
526
+ type IWabotEnvType = 'development' | 'staging' | 'testing' | 'production';
527
+ declare class WabotEnv {
528
+ private envType;
529
+ constructor();
530
+ isDevelopment(): boolean;
531
+ isProduction(): boolean;
532
+ }
533
+
534
+ type IWhatsAppMessageListener = (message: IConnectionChatMessage) => Promise<void>;
535
+ interface IWhatsAppConnection {
536
+ listenMessage(businessNumber: string, listener: IWhatsAppMessageListener): void;
537
+ sendWhatsApp(businessNumber: string, to: string, replyMessage: IChatMessage): Promise<void>;
538
+ connect(): void;
539
+ }
540
+
541
+ declare class Logger {
542
+ private debuggers;
543
+ constructor(name: string);
544
+ trace(...args: any[]): void;
545
+ debug(...args: any[]): void;
546
+ info(...args: any[]): void;
547
+ warn(...args: any[]): void;
548
+ error(...args: any[]): void;
549
+ fatal(...args: any[]): void;
550
+ private log;
551
+ }
552
+
553
+ declare abstract class WhatsAppConnection implements IWhatsAppConnection {
554
+ protected logger: Logger;
555
+ private listeners;
556
+ constructor(logger: Logger);
557
+ abstract sendWhatsApp(businessNumber: string, to: string, chatMessage: IChatMessage): Promise<void>;
558
+ abstract connect(): void;
559
+ listenMessage(businessNumber: string, listener: IWhatsAppMessageListener): void;
560
+ protected handlePayload(payload: IWhatsAppWebhookPayload): Promise<void>;
561
+ private emmitMessage;
562
+ }
563
+
564
+ declare class WhatsAppDevConnection extends WhatsAppConnection implements IWhatsAppConnection {
565
+ private devProxy;
566
+ private devProxySocket;
567
+ private devToken?;
568
+ private connected;
569
+ constructor();
570
+ sendWhatsApp(businessNumber: string, to: string, chatMessage: IChatMessage): Promise<void>;
571
+ connect(): void;
572
+ }
573
+
574
+ declare class WhatsAppProdConnection implements IWhatsAppConnection {
575
+ private express;
576
+ constructor(express: Express);
577
+ listenMessage(businessNumber: string, listener: IWhatsAppMessageListener): void;
578
+ sendWhatsApp(businessNumber: string, to: string, replyMessage: IChatMessage): Promise<void>;
579
+ connect(): void;
580
+ }
581
+
582
+ declare class WhatsAppChannel implements IChatChannel {
583
+ private config;
584
+ private chatResolver;
585
+ private userResolver;
586
+ private wabotEnv;
587
+ private logger;
588
+ private whatsAppConection;
589
+ constructor(config: WhatsappChannelConfig, chatResolver: ChatResolver, userResolver: UserResolver, wabotEnv: WabotEnv, devConnection: WhatsAppDevConnection, prodConnection: WhatsAppProdConnection);
590
+ listen(callback: (message: IReceivedMessage) => void): void;
591
+ connect(): void;
592
+ }
593
+
594
+ declare const devWhatsAppListentEvent: {
595
+ readonly DEV_WATSAPP_WEBHOOK: "dev-whatsapp-webhook";
596
+ };
597
+ declare const devWhatsappEmitEvent: {
598
+ readonly DEV_CONNECTION: "dev-connection";
599
+ readonly DEV_SEND_WHATSAPP: "dev-send-whatsapp";
600
+ };
601
+ interface IDevConnectionRequest {
602
+ token: string;
603
+ }
604
+ interface IDevSendWhatsappRequest {
605
+ from: string;
606
+ to: string;
607
+ message: IChatMessage;
608
+ }
609
+
456
610
  declare function prepareChatContainer(container: DependencyContainer$1, context: IMessageContext, mindsetCtor?: IConstructor<IMindset>): Promise<DependencyContainer$1>;
457
611
 
458
612
  interface IrunChannelProps {
@@ -674,4 +828,4 @@ declare class RamChatRepository implements IChatRepository {
674
828
  private getMemory;
675
829
  }
676
830
 
677
- export { AuthenticationModule, Chat, ChatBot, ChatBotAdapter, ChatBotMetadataStore, ChatItem, ChatMemory, ChatRepository, ChatResolver, CmdChannel, Container, ControllerMetadataStore, EmailService, type IChannelMetadata, type IChatBot, type IChatBotAdapter, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatFunctionCall, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatRepository, type IChatType, type IConnectionChatMessage, type IConstructor, type ICrudRepository, type IEmailService, type IMessageContext, type IMindset, type IMindsetDecoration, type IMindsetFunctionConfig, type IMindsetFunctionDecoration, type IMindsetFunctionMetadata, type IMindsetFunctionParamMetadata, type IMindsetIdentity, type IMindsetMetadata, type IMindsetModuleConfig, type IMindsetModuleDecoration, type IMindsetModuleMetadata, type IOtpService, type IParamConfig, type IParamDecoration, type IPersistent, type IPgRepositoryConfig, type IReceivedMessage, type IReceivedMessageItem, type IReversibleMapper, type ISendEmailRequest, type IServerConfig, type IServerProvider, type ISqliteRecord, type ISystemFunctionCallItem, type ISystemMessageItem, type ITelegramChannelConfig, type IUserConnection, type IUserData, type IUserRepository, type IchatControllerConfig, type IrunChannelProps, MINDSET_DECORATION_MINDSET, MINDSET_FUNCTION_DECORATION_FUNCTION, MINDSET_MODULE_DECORATION_MODULE, MessageContext, Mindset, MindsetMetadataStore, MindsetOperator, OpenaiChatBotAdapter, OtpService, PARAM_DECORATION_IS_OPTIONAL, PARAM_DECORATION_PARAM, Persistent, PgChatMemory, PgChatRepository, PgCrudRepository, PgRepositoryBase, PgUserRepository, RamChatMemory, RamChatRepository, RamUserRepository, RegisterUserModule, RegisterUserWithEmailRequest, SendOneTimePasswordRequest, SqliteChatMemory, SqliteChatRepository, SqliteCrudRepository, SqlitePersistentMapper, SqliteUserRepository, TelegramChannel, TelegramChannelConfig, User, UserRepository, UserResolver, ValidateOneTimePasswordRequest, chatBot, chatController, cmd, container, inject, injectable, isOptional, mindset, mindsetFunction, mindsetModule, param, prepareChatContainer, runChannel, runServer, singleton, sqliteMapperFor, telegram };
831
+ export { AuthenticationModule, Chat, ChatBot, ChatBotAdapter, ChatBotMetadataStore, ChatItem, ChatMemory, ChatRepository, ChatResolver, CmdChannel, Container, ControllerMetadataStore, EmailService, ExpressApp, type IChannelMetadata, type IChatBot, type IChatBotAdapter, type IChatBotMetadata, type IChatChannel, type IChatConnection, type IChatControllerMetadata, type IChatData, type IChatFunctionCall, type IChatItemData, type IChatItemType, type IChatMemory, type IChatMessage, type IChatRepository, type IChatType, type IConnectionChatMessage, type IConstructor, type ICrudRepository, type IDevConnectionRequest, type IDevSendWhatsappRequest, type IEmailService, type IMessageContext, type IMessageMetadata, type IMindset, type IMindsetDecoration, type IMindsetFunctionConfig, type IMindsetFunctionDecoration, type IMindsetFunctionMetadata, type IMindsetFunctionParamMetadata, type IMindsetIdentity, type IMindsetMetadata, type IMindsetModuleConfig, type IMindsetModuleDecoration, type IMindsetModuleMetadata, type IOtpService, type IParamConfig, type IParamDecoration, type IPersistent, type IPgRepositoryConfig, type IReceivedMessage, type IReceivedMessageItem, type IReversibleMapper, type ISendEmailRequest, type IServerConfig, type IServerProvider, type ISqliteRecord, type ISystemFunctionCallItem, type ISystemMessageItem, type ITelegramChannelConfig, type IUserConnection, type IUserData, type IUserRepository, type IWabotEnvType, type IWhatsAppContact, type IWhatsAppMessage, type IWhatsAppWebhookPayload, type IWhatsappChannelConfig, type IchatControllerConfig, type IrunChannelProps, Logger, MINDSET_DECORATION_MINDSET, MINDSET_FUNCTION_DECORATION_FUNCTION, MINDSET_MODULE_DECORATION_MODULE, MessageContext, Mindset, MindsetMetadataStore, MindsetOperator, OpenaiChatBotAdapter, OtpService, PARAM_DECORATION_IS_OPTIONAL, PARAM_DECORATION_PARAM, Persistent, PgChatMemory, PgChatRepository, PgCrudRepository, PgRepositoryBase, PgUserRepository, RamChatMemory, RamChatRepository, RamUserRepository, RegisterUserModule, RegisterUserWithEmailRequest, SendOneTimePasswordRequest, SocketIoApp, SqliteChatMemory, SqliteChatRepository, SqliteCrudRepository, SqlitePersistentMapper, SqliteUserRepository, TelegramChannel, TelegramChannelConfig, User, UserRepository, UserResolver, ValidateOneTimePasswordRequest, WabotEnv, WhatsAppChannel, WhatsappChannelConfig, chatBot, chatController, cmd, container, devWhatsAppListentEvent, devWhatsappEmitEvent, inject, injectable, isOptional, mindset, mindsetFunction, mindsetModule, param, prepareChatContainer, runChannel, runServer, singleton, sqliteMapperFor, telegram, whatsapp };
package/dist/src/index.js CHANGED
@@ -4,6 +4,10 @@ export { CmdChannel } from './channels/cmd/CmdChannel.js';
4
4
  export { telegram } from './channels/telegram/@telegram.js';
5
5
  export { TelegramChannelConfig } from './channels/telegram/TelegramChannelConfig.js';
6
6
  export { TelegramChannel } from './channels/telegram/TelegramChannel.js';
7
+ export { whatsapp } from './channels/whatsapp/@whatsapp.js';
8
+ export { WhatsAppChannel } from './channels/whatsapp/WhatsAppChannel.js';
9
+ export { WhatsappChannelConfig } from './channels/whatsapp/WhatsAppChannelConfig.js';
10
+ export { devWhatsAppListentEvent, devWhatsappEmitEvent } from './channels/whatsapp/whatsAppDevSocketContracts.js';
7
11
  export { chatBot } from './chatbot/metadata/@chatBot.js';
8
12
  export { ChatBotMetadataStore } from './chatbot/metadata/ChatBotMetadataStore.js';
9
13
  export { mindsetFunction } from './mindset/metadata/functions/@mindsetFunction.js';
@@ -32,6 +36,8 @@ export { ChatResolver } from './controller/channel/ChatResolver.js';
32
36
  export { UserResolver } from './controller/channel/UserResolver.js';
33
37
  export { chatController } from './controller/metadata/controller/@chatController.js';
34
38
  export { ControllerMetadataStore } from './controller/metadata/ControllerMetadataStore.js';
39
+ export { ExpressApp } from './controller/express/Express.js';
40
+ export { SocketIoApp } from './controller/socket.io/SocketIO.js';
35
41
  export { container, inject, injectable, singleton } from './injection/index.js';
36
42
  export { prepareChatContainer } from './server/prepareChatContainer.js';
37
43
  export { runChannel } from './server/runChannel.js';
@@ -56,4 +62,6 @@ export { PgCrudRepository } from './repository/pg/PgCrudRepository.js';
56
62
  export { PgRepositoryBase } from './repository/pg/PgRepositoryBase.js';
57
63
  export { SqliteCrudRepository } from './repository/sqlite/SqliteCrudRepository.js';
58
64
  export { SqlitePersistentMapper, sqliteMapperFor } from './repository/sqlite/SqlitePersistentMapper.js';
65
+ export { Logger } from './logger/Logger.js';
66
+ export { WabotEnv } from './env/WabotEnv.js';
59
67
  export { Container } from './injection/Container.js';
@@ -0,0 +1,65 @@
1
+ import debug from 'debug';
2
+
3
+ const levelColors = {
4
+ trace: 0,
5
+ debug: 0,
6
+ info: 0,
7
+ warn: 5,
8
+ error: 1,
9
+ fatal: 1,
10
+ };
11
+ class Logger {
12
+ debuggers;
13
+ constructor(name) {
14
+ this.debuggers = {};
15
+ for (const level of Object.keys(levelColors)) {
16
+ const dbg = debug(`${name}:${level}`);
17
+ dbg.color = '' + levelColors[level];
18
+ this.debuggers[level] = dbg;
19
+ }
20
+ }
21
+ trace(...args) {
22
+ this.log(this.debuggers['trace'], args);
23
+ }
24
+ debug(...args) {
25
+ this.log(this.debuggers['debug'], args);
26
+ }
27
+ info(...args) {
28
+ this.log(this.debuggers['info'], args);
29
+ }
30
+ warn(...args) {
31
+ this.log(this.debuggers['warn'], args);
32
+ }
33
+ error(...args) {
34
+ this.log(this.debuggers['error'], args);
35
+ }
36
+ fatal(...args) {
37
+ this.log(this.debuggers['fatal'], args);
38
+ }
39
+ log(debugg, args) {
40
+ const _args = args.map((arg) => {
41
+ if (arg instanceof Error) {
42
+ return JSON.stringify({
43
+ name: arg.name,
44
+ message: arg.message,
45
+ stack: arg.stack,
46
+ });
47
+ }
48
+ if (arg === null) {
49
+ return 'null';
50
+ }
51
+ if (typeof arg === 'object') {
52
+ try {
53
+ return JSON.stringify(arg);
54
+ }
55
+ catch (e) {
56
+ return '[Circular]';
57
+ }
58
+ }
59
+ return arg;
60
+ });
61
+ debugg(..._args);
62
+ }
63
+ }
64
+
65
+ export { Logger };
@@ -1,20 +1,20 @@
1
- import dotenv from 'dotenv';
2
- import '../controller/channel/ChatResolver.js';
3
- import '../controller/channel/UserResolver.js';
1
+ import 'reflect-metadata';
4
2
  import { container } from '../injection/index.js';
3
+ import '../mindset/metadata/MindsetMetadataStore.js';
5
4
  import { ChatRepository } from '../core/chat/repository/IChatRepository.js';
6
5
  import '../core/user/IUserRepository.js';
7
- import '../controller/metadata/ControllerMetadataStore.js';
8
- import 'reflect-metadata';
9
- import '../mindset/metadata/MindsetMetadataStore.js';
10
6
  import '../mindset/MindsetOperator.js';
11
- import { prepareChatContainer } from './prepareChatContainer.js';
12
7
  import 'uuid';
13
8
  import '../chatbot/metadata/ChatBotMetadataStore.js';
14
9
  import { ChatBot } from '../chatbot/ChatBot.js';
15
10
  import { ChatBotAdapter } from '../chatbot/ChatBotAdapter.js';
11
+ import '../controller/channel/ChatResolver.js';
12
+ import '../controller/channel/UserResolver.js';
13
+ import '../controller/metadata/ControllerMetadataStore.js';
14
+ import 'express';
15
+ import 'socket.io';
16
+ import { prepareChatContainer } from './prepareChatContainer.js';
16
17
 
17
- dotenv.config();
18
18
  function runChannel(props) {
19
19
  container.registerSingleton(ChatRepository, props.chatRepository);
20
20
  container.register(ChatBotAdapter, { useClass: props.chatBotAdapter });
@@ -1,14 +1,49 @@
1
- import dotenv from 'dotenv';
2
1
  import '../controller/channel/ChatResolver.js';
3
2
  import '../controller/channel/UserResolver.js';
4
3
  import { container } from '../injection/index.js';
5
4
  import '../core/chat/repository/IChatRepository.js';
6
5
  import '../core/user/IUserRepository.js';
7
6
  import { ControllerMetadataStore } from '../controller/metadata/ControllerMetadataStore.js';
7
+ import { ExpressApp } from '../controller/express/Express.js';
8
+ import { SocketIoApp } from '../controller/socket.io/SocketIO.js';
8
9
  import { prepareChatContainer } from './prepareChatContainer.js';
10
+ import express from 'express';
11
+ import { Server } from 'socket.io';
12
+ import http from 'http';
13
+ import bodyParser from 'body-parser';
14
+ import { Logger } from '../logger/Logger.js';
9
15
 
10
- dotenv.config();
11
16
  function runServer(config) {
17
+ const httpLogger = new Logger('wabot:http');
18
+ const socketLogger = new Logger('wabot:socket');
19
+ const expressApp = express();
20
+ const httpServer = http.createServer(expressApp);
21
+ const io = new Server(httpServer, {
22
+ cors: {
23
+ origin: '*',
24
+ },
25
+ });
26
+ expressApp.use(bodyParser.json());
27
+ expressApp.use((req, res, next) => {
28
+ const start = process.hrtime();
29
+ res.on('finish', () => {
30
+ const [seconds, nanoseconds] = process.hrtime(start);
31
+ const ms = (seconds * 1000 + nanoseconds / 1e6).toFixed(2);
32
+ httpLogger.trace(`${req.method} ${req.originalUrl} ${res.statusCode} - ${ms}ms`);
33
+ });
34
+ next();
35
+ });
36
+ io.on('connection', (socket) => {
37
+ socketLogger.trace(`socket:${socket.id} connection`);
38
+ socket.onAny((event) => {
39
+ socketLogger.trace(`socket:${socket.id} emmits ${event}`);
40
+ });
41
+ socket.on('disconnect', (reason) => {
42
+ socketLogger.trace(`socket:${socket.id} disconnect with reason: ${reason}`);
43
+ });
44
+ });
45
+ container.register(ExpressApp, { useValue: expressApp });
46
+ container.register(SocketIoApp, { useValue: io });
12
47
  for (const provider of config.providers ?? []) {
13
48
  if (provider.singleton) {
14
49
  container.registerSingleton(provider.replace, provider.with);
@@ -39,6 +74,10 @@ function runServer(config) {
39
74
  channel.connect();
40
75
  }
41
76
  }
77
+ const PORT = process.env.PORT || 3000;
78
+ httpServer.listen(PORT, () => {
79
+ httpLogger.info(`server listenig on port ${PORT}`);
80
+ });
42
81
  }
43
82
 
44
83
  export { runServer };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wabot-dev/framework",
3
- "version": "0.0.13",
3
+ "version": "0.0.16",
4
4
  "description": "Framework for IA Chat Bots",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -16,8 +16,7 @@
16
16
  "fmt": "prettier --write .",
17
17
  "fmt:check": "prettier --check .",
18
18
  "types:check": "tsc --noEmit",
19
- "elia:cmd": "node --import @yucacodes/ts/src/custom-import.mjs ./test/elia/runEliaCmd.ts",
20
- "elia:telegram": "node --import @yucacodes/ts/src/custom-import.mjs ./test/elia/runEliaTelegram.ts"
19
+ "elia:dev": "yts --import ./dotenv.config.mjs ./test/elia/runElia.ts"
21
20
  },
22
21
  "devDependencies": {
23
22
  "@rollup/plugin-alias": "5.1.1",
@@ -35,10 +34,14 @@
35
34
  "typescript": "5.8.3"
36
35
  },
37
36
  "peerDependencies": {
37
+ "@types/debug": "^4.1.12",
38
+ "@types/express": "^5.0.1",
38
39
  "@types/pg": "^8.11.14",
39
40
  "@yucacodes/ts": "^0.0.4",
41
+ "body-parser": "^2.2.0",
40
42
  "class-transformer": "^0.5.1",
41
43
  "class-validator": "^0.14.1",
44
+ "debug": "^4.4.0",
42
45
  "dotenv": "^16.5.0",
43
46
  "express": "^5.1.0",
44
47
  "grammy": "^1.36.0",
@@ -46,6 +49,8 @@
46
49
  "pg": "^8.15.6",
47
50
  "reflect-metadata": "^0.2.2",
48
51
  "short-uuid": "^5.2.0",
52
+ "socket.io": "^4.8.1",
53
+ "socket.io-client": "^4.8.1",
49
54
  "sqlite": "^5.1.1",
50
55
  "sqlite3": "^5.1.7",
51
56
  "tslib": "^2.8.1",