crewly 1.1.2 → 1.2.0
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/README.md +6 -6
- package/config/roles/ops/prompt.md +140 -0
- package/config/roles/ops/role.json +13 -0
- package/config/skills/agent/browse-stealth/execute.sh +84 -0
- package/config/skills/agent/browse-stealth/instructions.md +108 -0
- package/config/skills/agent/browse-stealth/launch-chrome-cdp.sh +141 -0
- package/config/skills/agent/browse-stealth/skill.json +20 -0
- package/config/skills/agent/browse-stealth/stealth-browse.py +330 -0
- package/config/skills/agent/competitor-content-tracker/execute.sh +232 -0
- package/config/skills/agent/competitor-content-tracker/instructions.md +210 -0
- package/config/skills/agent/competitor-content-tracker/skill.json +22 -0
- package/config/skills/agent/content-calendar/execute.sh +294 -0
- package/config/skills/agent/content-calendar/instructions.md +122 -0
- package/config/skills/agent/content-calendar/skill.json +22 -0
- package/config/skills/agent/content-repurposer/execute.sh +194 -0
- package/config/skills/agent/content-repurposer/instructions.md +69 -0
- package/config/skills/agent/content-repurposer/skill.json +22 -0
- package/config/skills/agent/content-writer/execute.sh +311 -0
- package/config/skills/agent/content-writer/instructions.md +124 -0
- package/config/skills/agent/content-writer/skill.json +22 -0
- package/config/skills/agent/core/generate-pdf/execute.sh +88 -0
- package/config/skills/agent/core/generate-pdf/instructions.md +46 -0
- package/config/skills/agent/core/generate-pdf/skill.json +20 -0
- package/config/skills/agent/core/report-status/execute.sh +6 -0
- package/config/skills/agent/trend-monitor/execute.sh +211 -0
- package/config/skills/agent/trend-monitor/instructions.md +207 -0
- package/config/skills/agent/trend-monitor/skill.json +22 -0
- package/config/skills/agent/vnc-browser/execute.sh +261 -0
- package/config/skills/agent/vnc-browser/instructions.md +102 -0
- package/config/skills/agent/vnc-browser/skill.json +20 -0
- package/config/skills/orchestrator/delegate-task/execute.sh +63 -4
- package/config/skills/orchestrator/delegate-task/instructions.md +60 -0
- package/config/skills/orchestrator/delegate-task/skill.json +4 -4
- package/config/skills/orchestrator/reply-slack/execute.sh +2 -0
- package/config/skills/orchestrator/send-key/execute.sh +19 -6
- package/config/skills/orchestrator/send-key/instructions.md +44 -0
- package/config/skills/orchestrator/send-key/skill.json +20 -0
- package/config/skills/orchestrator/send-message/execute.sh +9 -1
- package/config/skills/registry.json +256 -0
- package/config/templates/code-review-team/README.md +176 -0
- package/config/templates/code-review-team/team-config.json +16 -0
- package/config/templates/code-review-team.json +62 -0
- package/config/templates/content-generation-team/README.md +128 -0
- package/config/templates/content-generation-team/team-config.json +21 -0
- package/config/templates/content-generation-team.json +67 -0
- package/config/templates/demo-team.json +22 -0
- package/config/templates/social-media-ops-team/README.md +145 -0
- package/config/templates/social-media-ops-team/team-config.json +21 -0
- package/config/templates/social-media-ops-team.json +67 -0
- package/dist/backend/backend/src/constants.d.ts +69 -6
- package/dist/backend/backend/src/constants.d.ts.map +1 -1
- package/dist/backend/backend/src/constants.js +75 -6
- package/dist/backend/backend/src/constants.js.map +1 -1
- package/dist/backend/backend/src/controllers/index.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/index.js +2 -0
- package/dist/backend/backend/src/controllers/index.js.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts +8 -0
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js +110 -63
- package/dist/backend/backend/src/controllers/messaging/messenger.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js +31 -4
- package/dist/backend/backend/src/controllers/monitoring/terminal.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts +8 -0
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.js +127 -111
- package/dist/backend/backend/src/controllers/oauth/oauth.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts +34 -0
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js +219 -2
- package/dist/backend/backend/src/controllers/task-management/task-management.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/user/user.routes.d.ts +7 -0
- package/dist/backend/backend/src/controllers/user/user.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/user/user.routes.js +45 -38
- package/dist/backend/backend/src/controllers/user/user.routes.js.map +1 -1
- package/dist/backend/backend/src/controllers/whatsapp/index.d.ts +17 -0
- package/dist/backend/backend/src/controllers/whatsapp/index.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/whatsapp/index.js +18 -0
- package/dist/backend/backend/src/controllers/whatsapp/index.js.map +1 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts +12 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js +185 -0
- package/dist/backend/backend/src/controllers/whatsapp/whatsapp.controller.js.map +1 -0
- package/dist/backend/backend/src/index.d.ts +5 -0
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +35 -0
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/modules/task-management.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/modules/task-management.routes.js +4 -0
- package/dist/backend/backend/src/routes/modules/task-management.routes.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-heartbeat.service.js +1 -1
- package/dist/backend/backend/src/services/agent/agent-heartbeat.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts +14 -3
- package/dist/backend/backend/src/services/agent/agent-registration.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/agent-registration.service.js +160 -29
- package/dist/backend/backend/src/services/agent/agent-registration.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts +4 -3
- package/dist/backend/backend/src/services/agent/claude-runtime.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js +29 -4
- package/dist/backend/backend/src/services/agent/claude-runtime.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.js +11 -0
- package/dist/backend/backend/src/services/agent/context-window-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts +32 -2
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.d.ts.map +1 -1
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js +69 -8
- package/dist/backend/backend/src/services/agent/runtime-agent.service.abstract.js.map +1 -1
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js +14 -2
- package/dist/backend/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js +11 -2
- package/dist/backend/backend/src/services/marketplace/marketplace-installer.service.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.d.ts +18 -0
- package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.js +28 -4
- package/dist/backend/backend/src/services/messaging/adapters/discord-messenger.adapter.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/slack-messenger.adapter.js +2 -2
- package/dist/backend/backend/src/services/messaging/adapters/slack-messenger.adapter.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.d.ts +18 -0
- package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.js +26 -4
- package/dist/backend/backend/src/services/messaging/adapters/telegram-messenger.adapter.js.map +1 -1
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts +28 -2
- package/dist/backend/backend/src/services/messaging/messenger-adapter.interface.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/messenger-registry.service.d.ts +33 -2
- package/dist/backend/backend/src/services/messaging/messenger-registry.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/messaging/messenger-registry.service.js +33 -0
- package/dist/backend/backend/src/services/messaging/messenger-registry.service.js.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js +4 -2
- package/dist/backend/backend/src/services/monitoring/activity-monitor.service.js.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js +4 -3
- package/dist/backend/backend/src/services/orchestrator/orchestrator-restart.service.js.map +1 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts +27 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project/task-tracking.service.js +54 -0
- package/dist/backend/backend/src/services/project/task-tracking.service.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts +36 -6
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js +238 -36
- package/dist/backend/backend/src/services/slack/slack-orchestrator-bridge.js.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/slack/slack.service.js +6 -4
- package/dist/backend/backend/src/services/slack/slack.service.js.map +1 -1
- package/dist/backend/backend/src/services/user/user-identity.service.d.ts +44 -0
- package/dist/backend/backend/src/services/user/user-identity.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/user/user-identity.service.js +75 -8
- package/dist/backend/backend/src/services/user/user-identity.service.js.map +1 -1
- package/dist/backend/backend/src/services/whatsapp/index.d.ts +11 -0
- package/dist/backend/backend/src/services/whatsapp/index.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/index.js +11 -0
- package/dist/backend/backend/src/services/whatsapp/index.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts +66 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js +96 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-initializer.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts +109 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js +234 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp-orchestrator-bridge.js.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts +127 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js +347 -0
- package/dist/backend/backend/src/services/whatsapp/whatsapp.service.js.map +1 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/workflow/scheduler.service.js +4 -0
- package/dist/backend/backend/src/services/workflow/scheduler.service.js.map +1 -1
- package/dist/backend/backend/src/types/index.d.ts +1 -0
- package/dist/backend/backend/src/types/index.d.ts.map +1 -1
- package/dist/backend/backend/src/types/index.js.map +1 -1
- package/dist/backend/backend/src/types/slack.types.d.ts +24 -0
- package/dist/backend/backend/src/types/slack.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/slack.types.js.map +1 -1
- package/dist/backend/backend/src/types/task-tracking.types.d.ts +4 -0
- package/dist/backend/backend/src/types/task-tracking.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/task-tracking.types.js.map +1 -1
- package/dist/backend/backend/src/types/whatsapp.types.d.ts +84 -0
- package/dist/backend/backend/src/types/whatsapp.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/whatsapp.types.js +33 -0
- package/dist/backend/backend/src/types/whatsapp.types.js.map +1 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts +11 -0
- package/dist/backend/backend/src/websocket/terminal.gateway.d.ts.map +1 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.js +35 -1
- package/dist/backend/backend/src/websocket/terminal.gateway.js.map +1 -1
- package/dist/cli/backend/src/constants.d.ts +69 -6
- package/dist/cli/backend/src/constants.d.ts.map +1 -1
- package/dist/cli/backend/src/constants.js +75 -6
- package/dist/cli/backend/src/constants.js.map +1 -1
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.d.ts.map +1 -1
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js +14 -2
- package/dist/cli/backend/src/services/knowledge/knowledge-search.service.js.map +1 -1
- package/dist/cli/backend/src/types/index.d.ts +1 -0
- package/dist/cli/backend/src/types/index.d.ts.map +1 -1
- package/dist/cli/backend/src/types/index.js.map +1 -1
- package/dist/cli/cli/src/commands/publish.d.ts.map +1 -1
- package/dist/cli/cli/src/commands/publish.js +17 -15
- package/dist/cli/cli/src/commands/publish.js.map +1 -1
- package/dist/cli/cli/src/index.js +2 -2
- package/dist/cli/cli/src/index.js.map +1 -1
- package/dist/cli/cli/src/utils/gh-submit.d.ts +46 -0
- package/dist/cli/cli/src/utils/gh-submit.d.ts.map +1 -0
- package/dist/cli/cli/src/utils/gh-submit.js +167 -0
- package/dist/cli/cli/src/utils/gh-submit.js.map +1 -0
- package/dist/cli/cli/src/utils/marketplace.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/marketplace.js +13 -5
- package/dist/cli/cli/src/utils/marketplace.js.map +1 -1
- package/dist/cli/cli/src/utils/templates.d.ts +3 -2
- package/dist/cli/cli/src/utils/templates.d.ts.map +1 -1
- package/dist/cli/cli/src/utils/templates.js +5 -4
- package/dist/cli/cli/src/utils/templates.js.map +1 -1
- package/frontend/dist/assets/{index-45eeea99.js → index-a23214ae.js} +241 -241
- package/frontend/dist/assets/{index-6972eeee.css → index-c407fe13.css} +1 -1
- package/frontend/dist/index.html +2 -2
- package/package.json +3 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp Initializer
|
|
3
|
+
*
|
|
4
|
+
* Handles automatic WhatsApp connection on application startup.
|
|
5
|
+
* Checks for environment variables and initializes if configured.
|
|
6
|
+
*
|
|
7
|
+
* @module services/whatsapp/initializer
|
|
8
|
+
*/
|
|
9
|
+
import { getWhatsAppService } from './whatsapp.service.js';
|
|
10
|
+
import { getWhatsAppOrchestratorBridge } from './whatsapp-orchestrator-bridge.js';
|
|
11
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
12
|
+
const logger = LoggerService.getInstance().createComponentLogger('WhatsAppInitializer');
|
|
13
|
+
/**
|
|
14
|
+
* Check if WhatsApp is configured via environment variables.
|
|
15
|
+
*
|
|
16
|
+
* @returns True if WHATSAPP_ENABLED is set to 'true'
|
|
17
|
+
*/
|
|
18
|
+
export function isWhatsAppConfigured() {
|
|
19
|
+
return process.env.WHATSAPP_ENABLED === 'true';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get WhatsApp configuration from environment variables.
|
|
23
|
+
*
|
|
24
|
+
* @returns WhatsAppConfig object or null if not configured
|
|
25
|
+
*/
|
|
26
|
+
export function getWhatsAppConfigFromEnv() {
|
|
27
|
+
if (!isWhatsAppConfigured()) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
phoneNumber: process.env.WHATSAPP_PHONE_NUMBER,
|
|
32
|
+
authStatePath: process.env.WHATSAPP_AUTH_PATH,
|
|
33
|
+
allowedContacts: process.env.WHATSAPP_ALLOWED_CONTACTS?.split(',').filter(Boolean),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Initialize WhatsApp integration if configured via environment variables.
|
|
38
|
+
*
|
|
39
|
+
* This function is designed to be called during application startup.
|
|
40
|
+
* It safely handles cases where WhatsApp is not configured.
|
|
41
|
+
*
|
|
42
|
+
* @param options - Optional initialization options
|
|
43
|
+
* @returns Result object indicating success or failure
|
|
44
|
+
*
|
|
45
|
+
* @example
|
|
46
|
+
* ```typescript
|
|
47
|
+
* const result = await initializeWhatsAppIfConfigured({
|
|
48
|
+
* messageQueueService: myService,
|
|
49
|
+
* });
|
|
50
|
+
* if (result.success) {
|
|
51
|
+
* console.log('WhatsApp connected!');
|
|
52
|
+
* }
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export async function initializeWhatsAppIfConfigured(options) {
|
|
56
|
+
const config = getWhatsAppConfigFromEnv();
|
|
57
|
+
if (!config) {
|
|
58
|
+
logger.info('Not configured — skipping initialization');
|
|
59
|
+
return { attempted: false, success: false };
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
const whatsappService = getWhatsAppService();
|
|
63
|
+
await whatsappService.initialize(config);
|
|
64
|
+
const bridge = getWhatsAppOrchestratorBridge();
|
|
65
|
+
if (options?.messageQueueService) {
|
|
66
|
+
bridge.setMessageQueueService(options.messageQueueService);
|
|
67
|
+
}
|
|
68
|
+
await bridge.initialize();
|
|
69
|
+
logger.info('Successfully initialized');
|
|
70
|
+
return { attempted: true, success: true };
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
74
|
+
logger.error('Failed to initialize', { error: errorMessage });
|
|
75
|
+
return { attempted: true, success: false, error: errorMessage };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Gracefully shutdown WhatsApp integration.
|
|
80
|
+
* Call this during application shutdown to disconnect cleanly.
|
|
81
|
+
*/
|
|
82
|
+
export async function shutdownWhatsApp() {
|
|
83
|
+
try {
|
|
84
|
+
const whatsappService = getWhatsAppService();
|
|
85
|
+
if (whatsappService.isConnected()) {
|
|
86
|
+
await whatsappService.disconnect();
|
|
87
|
+
logger.info('Disconnected');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger.error('Error during shutdown', {
|
|
92
|
+
error: error instanceof Error ? error.message : String(error),
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=whatsapp-initializer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp-initializer.js","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-initializer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp-Orchestrator Bridge
|
|
3
|
+
*
|
|
4
|
+
* Routes messages between WhatsApp and the Crewly orchestrator,
|
|
5
|
+
* enabling mobile control of AI teams via WhatsApp.
|
|
6
|
+
*
|
|
7
|
+
* @module services/whatsapp/bridge
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
import type { MessageQueueService } from '../messaging/message-queue.service.js';
|
|
11
|
+
/**
|
|
12
|
+
* Bridge configuration
|
|
13
|
+
*/
|
|
14
|
+
export interface WhatsAppBridgeConfig {
|
|
15
|
+
/** Orchestrator session name */
|
|
16
|
+
orchestratorSession: string;
|
|
17
|
+
/** Maximum response length before truncation */
|
|
18
|
+
maxResponseLength: number;
|
|
19
|
+
/** Response timeout in ms */
|
|
20
|
+
responseTimeoutMs: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* WhatsAppOrchestratorBridge class
|
|
24
|
+
*
|
|
25
|
+
* Routes messages between WhatsApp and the Crewly orchestrator.
|
|
26
|
+
* Mirrors the SlackOrchestratorBridge pattern with WhatsApp-specific handling.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const bridge = getWhatsAppOrchestratorBridge();
|
|
31
|
+
* await bridge.initialize();
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class WhatsAppOrchestratorBridge extends EventEmitter {
|
|
35
|
+
private logger;
|
|
36
|
+
private whatsappService;
|
|
37
|
+
private chatService;
|
|
38
|
+
private messageQueueService;
|
|
39
|
+
private config;
|
|
40
|
+
private initialized;
|
|
41
|
+
private boundMessageHandler;
|
|
42
|
+
/**
|
|
43
|
+
* Create a new WhatsAppOrchestratorBridge
|
|
44
|
+
*
|
|
45
|
+
* @param config - Partial configuration to override defaults
|
|
46
|
+
*/
|
|
47
|
+
constructor(config?: Partial<WhatsAppBridgeConfig>);
|
|
48
|
+
/**
|
|
49
|
+
* Initialize the bridge.
|
|
50
|
+
* Sets up message listeners for WhatsApp incoming messages.
|
|
51
|
+
*/
|
|
52
|
+
initialize(): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Check if bridge is initialized
|
|
55
|
+
*
|
|
56
|
+
* @returns True if initialized
|
|
57
|
+
*/
|
|
58
|
+
isInitialized(): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Set the message queue service for enqueuing messages to the orchestrator.
|
|
61
|
+
*
|
|
62
|
+
* @param service - The MessageQueueService instance
|
|
63
|
+
*/
|
|
64
|
+
setMessageQueueService(service: MessageQueueService): void;
|
|
65
|
+
/**
|
|
66
|
+
* Get current configuration
|
|
67
|
+
*
|
|
68
|
+
* @returns A copy of the current configuration
|
|
69
|
+
*/
|
|
70
|
+
getConfig(): WhatsAppBridgeConfig;
|
|
71
|
+
/**
|
|
72
|
+
* Handle incoming WhatsApp message.
|
|
73
|
+
* Routes the message to the orchestrator and sends the response back.
|
|
74
|
+
*
|
|
75
|
+
* @param message - Incoming WhatsApp message
|
|
76
|
+
*/
|
|
77
|
+
private handleWhatsAppMessage;
|
|
78
|
+
/**
|
|
79
|
+
* Send message to orchestrator via the message queue and wait for response.
|
|
80
|
+
*
|
|
81
|
+
* @param message - Message text to send
|
|
82
|
+
* @param context - Conversation context
|
|
83
|
+
* @returns Orchestrator response or offline/error message
|
|
84
|
+
*/
|
|
85
|
+
private sendToOrchestrator;
|
|
86
|
+
/**
|
|
87
|
+
* Cleanup bridge resources.
|
|
88
|
+
* Removes only this bridge's event listener and resets initialization state.
|
|
89
|
+
*/
|
|
90
|
+
cleanup(): void;
|
|
91
|
+
/**
|
|
92
|
+
* Send a text response back to a WhatsApp chat.
|
|
93
|
+
*
|
|
94
|
+
* @param chatId - Destination chat JID
|
|
95
|
+
* @param text - Response text
|
|
96
|
+
*/
|
|
97
|
+
sendWhatsAppResponse(chatId: string, text: string): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Get WhatsApp bridge singleton
|
|
101
|
+
*
|
|
102
|
+
* @returns WhatsAppOrchestratorBridge instance
|
|
103
|
+
*/
|
|
104
|
+
export declare function getWhatsAppOrchestratorBridge(): WhatsAppOrchestratorBridge;
|
|
105
|
+
/**
|
|
106
|
+
* Reset WhatsApp bridge singleton (for testing)
|
|
107
|
+
*/
|
|
108
|
+
export declare function resetWhatsAppOrchestratorBridge(): void;
|
|
109
|
+
//# sourceMappingURL=whatsapp-orchestrator-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp-orchestrator-bridge.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-orchestrator-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAWtC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAIjF;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gDAAgD;IAChD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,6BAA6B;IAC7B,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAcD;;;;;;;;;;;GAWG;AACH,qBAAa,0BAA2B,SAAQ,YAAY;IAC1D,OAAO,CAAC,MAAM,CAAuE;IACrF,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,mBAAmB,CAAoC;IAC/D,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,mBAAmB,CAAsE;IAEjG;;;;OAIG;gBACS,MAAM,GAAE,OAAO,CAAC,oBAAoB,CAAM;IAOtD;;;OAGG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;OAIG;IACH,sBAAsB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI;IAI1D;;;;OAIG;IACH,SAAS,IAAI,oBAAoB;IAIjC;;;;;OAKG;YACW,qBAAqB;IAiCnC;;;;;;OAMG;YACW,kBAAkB;IAgEhC;;;OAGG;IACH,OAAO,IAAI,IAAI;IAQf;;;;;OAKG;IACG,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAYxE;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,IAAI,0BAA0B,CAK1E;AAED;;GAEG;AACH,wBAAgB,+BAA+B,IAAI,IAAI,CAEtD"}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp-Orchestrator Bridge
|
|
3
|
+
*
|
|
4
|
+
* Routes messages between WhatsApp and the Crewly orchestrator,
|
|
5
|
+
* enabling mobile control of AI teams via WhatsApp.
|
|
6
|
+
*
|
|
7
|
+
* @module services/whatsapp/bridge
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
import { getWhatsAppService } from './whatsapp.service.js';
|
|
11
|
+
import { getChatService } from '../chat/chat.service.js';
|
|
12
|
+
import { isOrchestratorActive, getOrchestratorOfflineMessage, } from '../orchestrator/index.js';
|
|
13
|
+
import { ORCHESTRATOR_SESSION_NAME, MESSAGE_QUEUE_CONSTANTS, WHATSAPP_CONSTANTS } from '../../constants.js';
|
|
14
|
+
import { LoggerService } from '../core/logger.service.js';
|
|
15
|
+
/**
|
|
16
|
+
* Default bridge configuration
|
|
17
|
+
*/
|
|
18
|
+
const DEFAULT_CONFIG = {
|
|
19
|
+
orchestratorSession: ORCHESTRATOR_SESSION_NAME,
|
|
20
|
+
maxResponseLength: WHATSAPP_CONSTANTS.MAX_RESPONSE_LENGTH,
|
|
21
|
+
responseTimeoutMs: (MESSAGE_QUEUE_CONSTANTS?.DEFAULT_MESSAGE_TIMEOUT ?? WHATSAPP_CONSTANTS.DEFAULT_FALLBACK_TIMEOUT_MS) + WHATSAPP_CONSTANTS.RESPONSE_TIMEOUT_BUFFER_MS,
|
|
22
|
+
};
|
|
23
|
+
/** WhatsApp bridge singleton */
|
|
24
|
+
let bridgeInstance = null;
|
|
25
|
+
/**
|
|
26
|
+
* WhatsAppOrchestratorBridge class
|
|
27
|
+
*
|
|
28
|
+
* Routes messages between WhatsApp and the Crewly orchestrator.
|
|
29
|
+
* Mirrors the SlackOrchestratorBridge pattern with WhatsApp-specific handling.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* const bridge = getWhatsAppOrchestratorBridge();
|
|
34
|
+
* await bridge.initialize();
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export class WhatsAppOrchestratorBridge extends EventEmitter {
|
|
38
|
+
logger = LoggerService.getInstance().createComponentLogger('WhatsAppBridge');
|
|
39
|
+
whatsappService;
|
|
40
|
+
chatService;
|
|
41
|
+
messageQueueService = null;
|
|
42
|
+
config;
|
|
43
|
+
initialized = false;
|
|
44
|
+
boundMessageHandler = null;
|
|
45
|
+
/**
|
|
46
|
+
* Create a new WhatsAppOrchestratorBridge
|
|
47
|
+
*
|
|
48
|
+
* @param config - Partial configuration to override defaults
|
|
49
|
+
*/
|
|
50
|
+
constructor(config = {}) {
|
|
51
|
+
super();
|
|
52
|
+
this.whatsappService = getWhatsAppService();
|
|
53
|
+
this.chatService = getChatService();
|
|
54
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Initialize the bridge.
|
|
58
|
+
* Sets up message listeners for WhatsApp incoming messages.
|
|
59
|
+
*/
|
|
60
|
+
async initialize() {
|
|
61
|
+
if (this.initialized)
|
|
62
|
+
return;
|
|
63
|
+
this.boundMessageHandler = this.handleWhatsAppMessage.bind(this);
|
|
64
|
+
this.whatsappService.on('message', this.boundMessageHandler);
|
|
65
|
+
this.initialized = true;
|
|
66
|
+
this.logger.info('Initialized');
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if bridge is initialized
|
|
70
|
+
*
|
|
71
|
+
* @returns True if initialized
|
|
72
|
+
*/
|
|
73
|
+
isInitialized() {
|
|
74
|
+
return this.initialized;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Set the message queue service for enqueuing messages to the orchestrator.
|
|
78
|
+
*
|
|
79
|
+
* @param service - The MessageQueueService instance
|
|
80
|
+
*/
|
|
81
|
+
setMessageQueueService(service) {
|
|
82
|
+
this.messageQueueService = service;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get current configuration
|
|
86
|
+
*
|
|
87
|
+
* @returns A copy of the current configuration
|
|
88
|
+
*/
|
|
89
|
+
getConfig() {
|
|
90
|
+
return { ...this.config };
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Handle incoming WhatsApp message.
|
|
94
|
+
* Routes the message to the orchestrator and sends the response back.
|
|
95
|
+
*
|
|
96
|
+
* @param message - Incoming WhatsApp message
|
|
97
|
+
*/
|
|
98
|
+
async handleWhatsAppMessage(message) {
|
|
99
|
+
this.logger.info('Received message', {
|
|
100
|
+
from: message.contactName || message.from,
|
|
101
|
+
preview: message.text.substring(0, 50),
|
|
102
|
+
});
|
|
103
|
+
try {
|
|
104
|
+
const context = this.whatsappService.getConversationContext(message.chatId, message.contactName || message.from);
|
|
105
|
+
const response = await this.sendToOrchestrator(message.text, context);
|
|
106
|
+
await this.sendWhatsAppResponse(message.chatId, response);
|
|
107
|
+
this.emit('message_handled', { message, response });
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
this.logger.error('Error handling message', {
|
|
111
|
+
error: error instanceof Error ? error.message : String(error),
|
|
112
|
+
});
|
|
113
|
+
try {
|
|
114
|
+
await this.sendWhatsAppResponse(message.chatId, `Sorry, I encountered an error: ${error instanceof Error ? error.message : String(error)}`);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Silent fail on error response
|
|
118
|
+
}
|
|
119
|
+
this.emit('error', error);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Send message to orchestrator via the message queue and wait for response.
|
|
124
|
+
*
|
|
125
|
+
* @param message - Message text to send
|
|
126
|
+
* @param context - Conversation context
|
|
127
|
+
* @returns Orchestrator response or offline/error message
|
|
128
|
+
*/
|
|
129
|
+
async sendToOrchestrator(message, context) {
|
|
130
|
+
try {
|
|
131
|
+
const isActive = await isOrchestratorActive();
|
|
132
|
+
if (!isActive) {
|
|
133
|
+
this.logger.info('Orchestrator is not active, returning offline message');
|
|
134
|
+
return getOrchestratorOfflineMessage(true);
|
|
135
|
+
}
|
|
136
|
+
// Capture reference to avoid race condition with non-null assertion
|
|
137
|
+
const mqService = this.messageQueueService;
|
|
138
|
+
if (!mqService) {
|
|
139
|
+
this.logger.error('Message queue service not configured');
|
|
140
|
+
return 'The WhatsApp bridge is not properly configured. Please restart the server.';
|
|
141
|
+
}
|
|
142
|
+
// Store message in chat service
|
|
143
|
+
const result = await this.chatService.sendMessage({
|
|
144
|
+
content: message,
|
|
145
|
+
conversationId: context?.conversationId,
|
|
146
|
+
metadata: {
|
|
147
|
+
source: 'whatsapp',
|
|
148
|
+
chatId: context?.chatId,
|
|
149
|
+
contactName: context?.contactName,
|
|
150
|
+
},
|
|
151
|
+
});
|
|
152
|
+
// Enqueue with a resolve callback for response routing
|
|
153
|
+
const response = await new Promise((resolve) => {
|
|
154
|
+
const timeoutId = setTimeout(() => {
|
|
155
|
+
resolve('The orchestrator is taking longer than expected. Please try again.');
|
|
156
|
+
}, this.config.responseTimeoutMs);
|
|
157
|
+
try {
|
|
158
|
+
mqService.enqueue({
|
|
159
|
+
content: message,
|
|
160
|
+
conversationId: result.conversation.id,
|
|
161
|
+
source: 'whatsapp',
|
|
162
|
+
sourceMetadata: {
|
|
163
|
+
whatsappResolve: (resp) => {
|
|
164
|
+
clearTimeout(timeoutId);
|
|
165
|
+
resolve(resp);
|
|
166
|
+
},
|
|
167
|
+
chatId: context?.chatId,
|
|
168
|
+
contactName: context?.contactName,
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
catch (enqueueErr) {
|
|
173
|
+
clearTimeout(timeoutId);
|
|
174
|
+
resolve(`Failed to enqueue message: ${enqueueErr instanceof Error ? enqueueErr.message : String(enqueueErr)}`);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return response;
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
this.logger.error('Error sending to orchestrator', {
|
|
181
|
+
error: error instanceof Error ? error.message : String(error),
|
|
182
|
+
});
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Cleanup bridge resources.
|
|
188
|
+
* Removes only this bridge's event listener and resets initialization state.
|
|
189
|
+
*/
|
|
190
|
+
cleanup() {
|
|
191
|
+
if (this.boundMessageHandler) {
|
|
192
|
+
this.whatsappService.removeListener('message', this.boundMessageHandler);
|
|
193
|
+
this.boundMessageHandler = null;
|
|
194
|
+
}
|
|
195
|
+
this.initialized = false;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Send a text response back to a WhatsApp chat.
|
|
199
|
+
*
|
|
200
|
+
* @param chatId - Destination chat JID
|
|
201
|
+
* @param text - Response text
|
|
202
|
+
*/
|
|
203
|
+
async sendWhatsAppResponse(chatId, text) {
|
|
204
|
+
const trimmed = text?.trim();
|
|
205
|
+
if (!trimmed)
|
|
206
|
+
return;
|
|
207
|
+
try {
|
|
208
|
+
await this.whatsappService.sendMessage({ to: chatId, text: trimmed });
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
this.logger.error('Failed to send WhatsApp response', {
|
|
212
|
+
error: err instanceof Error ? err.message : String(err),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Get WhatsApp bridge singleton
|
|
219
|
+
*
|
|
220
|
+
* @returns WhatsAppOrchestratorBridge instance
|
|
221
|
+
*/
|
|
222
|
+
export function getWhatsAppOrchestratorBridge() {
|
|
223
|
+
if (!bridgeInstance) {
|
|
224
|
+
bridgeInstance = new WhatsAppOrchestratorBridge();
|
|
225
|
+
}
|
|
226
|
+
return bridgeInstance;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Reset WhatsApp bridge singleton (for testing)
|
|
230
|
+
*/
|
|
231
|
+
export function resetWhatsAppOrchestratorBridge() {
|
|
232
|
+
bridgeInstance = null;
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=whatsapp-orchestrator-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp-orchestrator-bridge.js","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp-orchestrator-bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp Service
|
|
3
|
+
*
|
|
4
|
+
* Manages WhatsApp connection via Baileys (WhatsApp Web multi-device protocol).
|
|
5
|
+
* Handles QR code pairing, auth state persistence, and bidirectional messaging.
|
|
6
|
+
*
|
|
7
|
+
* @module services/whatsapp
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
import type { WhatsAppConfig, WhatsAppIncomingMessage, WhatsAppOutgoingMessage, WhatsAppServiceStatus, WhatsAppConversationContext } from '../../types/whatsapp.types.js';
|
|
11
|
+
/**
|
|
12
|
+
* Events emitted by WhatsAppService
|
|
13
|
+
*/
|
|
14
|
+
export interface WhatsAppServiceEvents {
|
|
15
|
+
message: (message: WhatsAppIncomingMessage) => void;
|
|
16
|
+
qr: (qrCode: string) => void;
|
|
17
|
+
connected: () => void;
|
|
18
|
+
disconnected: (reason?: string) => void;
|
|
19
|
+
error: (error: Error) => void;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* WhatsApp Service singleton
|
|
23
|
+
*
|
|
24
|
+
* Manages the Baileys WebSocket connection, QR pairing flow,
|
|
25
|
+
* and message send/receive lifecycle.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const service = getWhatsAppService();
|
|
30
|
+
* await service.initialize({ allowedContacts: ['+1234567890'] });
|
|
31
|
+
* service.on('message', (msg) => console.log(msg.text));
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class WhatsAppService extends EventEmitter {
|
|
35
|
+
private logger;
|
|
36
|
+
private sock;
|
|
37
|
+
private config;
|
|
38
|
+
private connected;
|
|
39
|
+
private currentQrCode;
|
|
40
|
+
private messagesSent;
|
|
41
|
+
private messagesReceived;
|
|
42
|
+
private phoneNumber;
|
|
43
|
+
private conversationContexts;
|
|
44
|
+
private reconnectAttempts;
|
|
45
|
+
private reconnectTimer;
|
|
46
|
+
private static readonly MAX_RECONNECT_DELAY_MS;
|
|
47
|
+
private static readonly MAX_RECONNECT_ATTEMPTS;
|
|
48
|
+
/**
|
|
49
|
+
* Initialize the WhatsApp connection.
|
|
50
|
+
* Sets up Baileys socket, auth state persistence, and event handlers.
|
|
51
|
+
*
|
|
52
|
+
* @param config - WhatsApp configuration
|
|
53
|
+
*/
|
|
54
|
+
initialize(config: WhatsAppConfig): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Process an incoming Baileys message and emit as WhatsAppIncomingMessage.
|
|
57
|
+
*
|
|
58
|
+
* Extracts text from various WhatsApp message types (conversation, extendedTextMessage),
|
|
59
|
+
* validates the sender against the allowed contacts list, and emits a normalized
|
|
60
|
+
* message event for the bridge to handle.
|
|
61
|
+
*
|
|
62
|
+
* Messages are silently ignored if:
|
|
63
|
+
* - Sent by this account (fromMe = true)
|
|
64
|
+
* - No text content present (images, stickers, etc.)
|
|
65
|
+
* - Sender not in allowedContacts list (when configured)
|
|
66
|
+
*
|
|
67
|
+
* @param rawMsg - Raw Baileys message object containing key, message content, and metadata
|
|
68
|
+
*/
|
|
69
|
+
private handleIncomingMessage;
|
|
70
|
+
/**
|
|
71
|
+
* Send a text message via WhatsApp.
|
|
72
|
+
*
|
|
73
|
+
* @param msg - Outgoing message with destination and text
|
|
74
|
+
* @throws Error if not connected or message too long
|
|
75
|
+
*/
|
|
76
|
+
sendMessage(msg: WhatsAppOutgoingMessage): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Send a file (document) via WhatsApp.
|
|
79
|
+
*
|
|
80
|
+
* @param chatId - Destination chat JID
|
|
81
|
+
* @param filePath - Absolute path to the file on disk
|
|
82
|
+
* @param caption - Optional caption for the file
|
|
83
|
+
* @throws Error if not connected or file too large
|
|
84
|
+
*/
|
|
85
|
+
sendFile(chatId: string, filePath: string, caption?: string): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Disconnect from WhatsApp gracefully.
|
|
88
|
+
*/
|
|
89
|
+
disconnect(): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Get current connection status.
|
|
92
|
+
*
|
|
93
|
+
* @returns WhatsApp service status object
|
|
94
|
+
*/
|
|
95
|
+
getStatus(): WhatsAppServiceStatus;
|
|
96
|
+
/**
|
|
97
|
+
* Check if WhatsApp is currently connected.
|
|
98
|
+
*
|
|
99
|
+
* @returns True if connected
|
|
100
|
+
*/
|
|
101
|
+
isConnected(): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Get the current QR code for pairing.
|
|
104
|
+
*
|
|
105
|
+
* @returns QR code string or null if not pending
|
|
106
|
+
*/
|
|
107
|
+
getQRCode(): string | null;
|
|
108
|
+
/**
|
|
109
|
+
* Get or create a conversation context for a chat.
|
|
110
|
+
*
|
|
111
|
+
* @param chatId - Chat JID
|
|
112
|
+
* @param contactName - Contact display name
|
|
113
|
+
* @returns Conversation context for message routing
|
|
114
|
+
*/
|
|
115
|
+
getConversationContext(chatId: string, contactName: string): WhatsAppConversationContext;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get WhatsApp service singleton
|
|
119
|
+
*
|
|
120
|
+
* @returns WhatsAppService instance
|
|
121
|
+
*/
|
|
122
|
+
export declare function getWhatsAppService(): WhatsAppService;
|
|
123
|
+
/**
|
|
124
|
+
* Reset WhatsApp service singleton (for testing)
|
|
125
|
+
*/
|
|
126
|
+
export declare function resetWhatsAppService(): void;
|
|
127
|
+
//# sourceMappingURL=whatsapp.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp.service.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/services/whatsapp/whatsapp.service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,OAAO,KAAK,EACV,cAAc,EACd,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,2BAA2B,EAC5B,MAAM,+BAA+B,CAAC;AAKvC;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;IACpD,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,YAAY,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAaD;;;;;;;;;;;;GAYG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,MAAM,CAAwE;IACtF,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,oBAAoB,CAAuD;IACnF,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAS;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAM;IAEpD;;;;;OAKG;IACG,UAAU,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA4HvD;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,qBAAqB;IAkD7B;;;;;OAKG;IACG,WAAW,CAAC,GAAG,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D;;;;;;;OAOG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBjF;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBjC;;;;OAIG;IACH,SAAS,IAAI,qBAAqB;IAUlC;;;;OAIG;IACH,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI;IAI1B;;;;;;OAMG;IACH,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,2BAA2B;CAczF;AAKD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
|