better-zap 0.0.4 → 0.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/dist/index.cjs +400 -5
- package/dist/index.d.cts +519 -25
- package/dist/index.d.mts +519 -25
- package/dist/index.mjs +394 -6
- package/package.json +6 -1
- package/dist/client-CRwYOHIG.d.cts +0 -790
- package/dist/client-s6x3lYea.d.mts +0 -790
- package/dist/client.cjs +0 -73
- package/dist/client.d.cts +0 -2
- package/dist/client.d.mts +0 -2
- package/dist/client.mjs +0 -71
package/dist/index.cjs
CHANGED
|
@@ -132,8 +132,8 @@ function delay(ms) {
|
|
|
132
132
|
}
|
|
133
133
|
//#endregion
|
|
134
134
|
//#region src/services/whatsapp.service.ts
|
|
135
|
-
const META_API_VERSION = "v25.0";
|
|
136
|
-
const META_BASE_URL = "https://graph.facebook.com";
|
|
135
|
+
const META_API_VERSION$1 = "v25.0";
|
|
136
|
+
const META_BASE_URL$1 = "https://graph.facebook.com";
|
|
137
137
|
const CONTEXT_WINDOW_CLOSED_ERROR = "Free-form message window is closed.";
|
|
138
138
|
var WhatsAppService = class {
|
|
139
139
|
baseUrl;
|
|
@@ -142,7 +142,7 @@ var WhatsAppService = class {
|
|
|
142
142
|
logger;
|
|
143
143
|
log;
|
|
144
144
|
constructor(config, logger, log) {
|
|
145
|
-
this.baseUrl = `${META_BASE_URL}/${META_API_VERSION}/${config.phoneId}/messages`;
|
|
145
|
+
this.baseUrl = `${META_BASE_URL$1}/${META_API_VERSION$1}/${config.phoneId}/messages`;
|
|
146
146
|
this.token = config.token;
|
|
147
147
|
this.isDev = config.environment === "development";
|
|
148
148
|
this.logger = logger;
|
|
@@ -457,6 +457,366 @@ var WhatsAppService = class {
|
|
|
457
457
|
}
|
|
458
458
|
};
|
|
459
459
|
//#endregion
|
|
460
|
+
//#region src/services/coexistence.service.ts
|
|
461
|
+
const META_API_VERSION = "v25.0";
|
|
462
|
+
const META_BASE_URL = "https://graph.facebook.com";
|
|
463
|
+
var CoexistenceService = class {
|
|
464
|
+
accessToken;
|
|
465
|
+
appId;
|
|
466
|
+
appSecret;
|
|
467
|
+
graphApiVersion;
|
|
468
|
+
graphBaseUrl;
|
|
469
|
+
fetchImpl;
|
|
470
|
+
tokenProvider;
|
|
471
|
+
credentialProvider;
|
|
472
|
+
constructor(config) {
|
|
473
|
+
this.accessToken = config.accessToken;
|
|
474
|
+
this.appId = config.appId;
|
|
475
|
+
this.appSecret = config.appSecret;
|
|
476
|
+
this.graphApiVersion = config.graphApiVersion ?? META_API_VERSION;
|
|
477
|
+
this.graphBaseUrl = config.graphBaseUrl ?? META_BASE_URL;
|
|
478
|
+
this.fetchImpl = config.fetch ?? fetch;
|
|
479
|
+
this.tokenProvider = config.tokenProvider ?? config.credentialProvider;
|
|
480
|
+
this.credentialProvider = config.credentialProvider;
|
|
481
|
+
}
|
|
482
|
+
async exchangeEmbeddedSignupCode(input) {
|
|
483
|
+
if (this.credentialProvider) try {
|
|
484
|
+
return {
|
|
485
|
+
success: true,
|
|
486
|
+
data: await this.credentialProvider.exchangeEmbeddedSignupCode(input)
|
|
487
|
+
};
|
|
488
|
+
} catch (error) {
|
|
489
|
+
return {
|
|
490
|
+
success: false,
|
|
491
|
+
error: error instanceof Error ? error.message : "Token exchange failed"
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (!this.appId || !this.appSecret) return {
|
|
495
|
+
success: false,
|
|
496
|
+
error: "appId and appSecret are required when no credentialProvider is configured"
|
|
497
|
+
};
|
|
498
|
+
const params = new URLSearchParams({
|
|
499
|
+
client_id: this.appId,
|
|
500
|
+
client_secret: this.appSecret,
|
|
501
|
+
code: input.code
|
|
502
|
+
});
|
|
503
|
+
if (input.redirectUri) params.set("redirect_uri", input.redirectUri);
|
|
504
|
+
const result = await this.request({
|
|
505
|
+
path: "/oauth/access_token",
|
|
506
|
+
method: "GET",
|
|
507
|
+
query: params,
|
|
508
|
+
token: null
|
|
509
|
+
});
|
|
510
|
+
if (!result.success || !result.data) return {
|
|
511
|
+
success: false,
|
|
512
|
+
error: result.error,
|
|
513
|
+
errorCode: result.errorCode,
|
|
514
|
+
httpStatus: result.httpStatus,
|
|
515
|
+
details: result.details
|
|
516
|
+
};
|
|
517
|
+
return {
|
|
518
|
+
success: true,
|
|
519
|
+
data: {
|
|
520
|
+
accessToken: result.data.access_token,
|
|
521
|
+
tokenType: result.data.token_type,
|
|
522
|
+
expiresIn: result.data.expires_in,
|
|
523
|
+
raw: result.data
|
|
524
|
+
}
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
async subscribeWaba(input) {
|
|
528
|
+
return this.request({
|
|
529
|
+
path: `/${input.wabaId}/subscribed_apps`,
|
|
530
|
+
method: "POST",
|
|
531
|
+
token: input.accessToken ?? await this.resolveAccessToken({ wabaId: input.wabaId })
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
async getPhoneStatus(input) {
|
|
535
|
+
return this.request({
|
|
536
|
+
path: `/${input.phoneNumberId}`,
|
|
537
|
+
method: "GET",
|
|
538
|
+
query: new URLSearchParams({ fields: "is_on_biz_app,platform_type" }),
|
|
539
|
+
token: input.accessToken ?? await this.resolveAccessToken({ phoneNumberId: input.phoneNumberId })
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
async startContactsSync(input) {
|
|
543
|
+
return this.startSmbAppDataSync({
|
|
544
|
+
phoneNumberId: input.phoneNumberId,
|
|
545
|
+
accessToken: input.accessToken,
|
|
546
|
+
syncType: "smb_app_state_sync"
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
async startHistorySync(input) {
|
|
550
|
+
return this.startSmbAppDataSync({
|
|
551
|
+
phoneNumberId: input.phoneNumberId,
|
|
552
|
+
accessToken: input.accessToken,
|
|
553
|
+
syncType: "history"
|
|
554
|
+
});
|
|
555
|
+
}
|
|
556
|
+
async startSmbAppDataSync(input) {
|
|
557
|
+
return this.request({
|
|
558
|
+
path: `/${input.phoneNumberId}/smb_app_data`,
|
|
559
|
+
method: "POST",
|
|
560
|
+
body: { sync_type: input.syncType },
|
|
561
|
+
token: input.accessToken ?? await this.resolveAccessToken({ phoneNumberId: input.phoneNumberId })
|
|
562
|
+
});
|
|
563
|
+
}
|
|
564
|
+
async resolveAccessToken(input) {
|
|
565
|
+
if (this.tokenProvider) return this.tokenProvider.getAccessToken(input);
|
|
566
|
+
return this.accessToken;
|
|
567
|
+
}
|
|
568
|
+
async request(input) {
|
|
569
|
+
if (input.token === void 0) return {
|
|
570
|
+
success: false,
|
|
571
|
+
error: "Missing Meta access token"
|
|
572
|
+
};
|
|
573
|
+
const url = new URL(`${this.graphBaseUrl}/${this.graphApiVersion}${input.path}`);
|
|
574
|
+
if (input.query) input.query.forEach((value, key) => url.searchParams.set(key, value));
|
|
575
|
+
try {
|
|
576
|
+
const response = await this.fetchImpl(url.toString(), {
|
|
577
|
+
method: input.method,
|
|
578
|
+
headers: {
|
|
579
|
+
"Content-Type": "application/json",
|
|
580
|
+
...input.token ? { Authorization: `Bearer ${input.token}` } : {}
|
|
581
|
+
},
|
|
582
|
+
...input.body ? { body: JSON.stringify(input.body) } : {}
|
|
583
|
+
});
|
|
584
|
+
let data = null;
|
|
585
|
+
try {
|
|
586
|
+
data = await response.json();
|
|
587
|
+
} catch {
|
|
588
|
+
data = null;
|
|
589
|
+
}
|
|
590
|
+
if (!response.ok) {
|
|
591
|
+
const errorData = data;
|
|
592
|
+
return {
|
|
593
|
+
success: false,
|
|
594
|
+
error: errorData?.error?.message ?? `HTTP ${response.status}`,
|
|
595
|
+
errorCode: errorData?.error?.code,
|
|
596
|
+
httpStatus: response.status,
|
|
597
|
+
details: data
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
return {
|
|
601
|
+
success: true,
|
|
602
|
+
data
|
|
603
|
+
};
|
|
604
|
+
} catch (error) {
|
|
605
|
+
return {
|
|
606
|
+
success: false,
|
|
607
|
+
error: error instanceof Error ? error.message : "Network error"
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
};
|
|
612
|
+
//#endregion
|
|
613
|
+
//#region src/coexistence/config.ts
|
|
614
|
+
function createCoexistenceEmbeddedSignupConfig(input) {
|
|
615
|
+
return {
|
|
616
|
+
config_id: input.configId,
|
|
617
|
+
response_type: "code",
|
|
618
|
+
override_default_response_type: true,
|
|
619
|
+
extras: {
|
|
620
|
+
...input.setup ? { setup: input.setup } : {},
|
|
621
|
+
featureType: "whatsapp_business_app_onboarding",
|
|
622
|
+
sessionInfoVersion: "3"
|
|
623
|
+
}
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
//#endregion
|
|
627
|
+
//#region src/coexistence/events.ts
|
|
628
|
+
const LEGACY_EVENT_BY_GENERIC = {
|
|
629
|
+
FINISH: "FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING",
|
|
630
|
+
CANCEL: "CANCEL_WHATSAPP_BUSINESS_APP_ONBOARDING",
|
|
631
|
+
ERROR: "ERROR_WHATSAPP_BUSINESS_APP_ONBOARDING"
|
|
632
|
+
};
|
|
633
|
+
const GENERIC_EVENT_BY_LEGACY = {
|
|
634
|
+
FINISH_WHATSAPP_BUSINESS_APP_ONBOARDING: "FINISH",
|
|
635
|
+
CANCEL_WHATSAPP_BUSINESS_APP_ONBOARDING: "CANCEL",
|
|
636
|
+
ERROR_WHATSAPP_BUSINESS_APP_ONBOARDING: "ERROR"
|
|
637
|
+
};
|
|
638
|
+
function isKnownGenericEvent(event) {
|
|
639
|
+
return event === "FINISH" || event === "CANCEL" || event === "ERROR";
|
|
640
|
+
}
|
|
641
|
+
function normalizeCoexistenceSessionEvent(event) {
|
|
642
|
+
if (isKnownGenericEvent(event)) return event;
|
|
643
|
+
if (event in GENERIC_EVENT_BY_LEGACY) return GENERIC_EVENT_BY_LEGACY[event];
|
|
644
|
+
return "PROGRESS";
|
|
645
|
+
}
|
|
646
|
+
function toLegacyCoexistenceSessionEvent(event) {
|
|
647
|
+
return isKnownGenericEvent(event) ? LEGACY_EVENT_BY_GENERIC[event] : event;
|
|
648
|
+
}
|
|
649
|
+
function normalizeCoexistenceSessionPayload(payload) {
|
|
650
|
+
return {
|
|
651
|
+
...payload,
|
|
652
|
+
normalizedEvent: normalizeCoexistenceSessionEvent(payload.event)
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
//#endregion
|
|
656
|
+
//#region src/coexistence/embedded-signup.ts
|
|
657
|
+
const DEFAULT_ALLOWED_ORIGINS = ["https://www.facebook.com", "https://web.facebook.com"];
|
|
658
|
+
function parseEmbeddedSignupMessage(data) {
|
|
659
|
+
const payload = typeof data === "string" ? parseJson(data) : data;
|
|
660
|
+
if (typeof payload !== "object" || payload === null) return null;
|
|
661
|
+
const candidate = payload;
|
|
662
|
+
if (candidate.type !== "WA_EMBEDDED_SIGNUP" || candidate.version !== 3 || typeof candidate.event !== "string") return null;
|
|
663
|
+
return {
|
|
664
|
+
event: candidate.event,
|
|
665
|
+
data: typeof candidate.data === "object" && candidate.data !== null ? candidate.data : void 0
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
function parseJson(value) {
|
|
669
|
+
try {
|
|
670
|
+
return JSON.parse(value);
|
|
671
|
+
} catch {
|
|
672
|
+
return null;
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
function launchCoexistenceEmbeddedSignup(input) {
|
|
676
|
+
const allowedOrigins = new Set([
|
|
677
|
+
...DEFAULT_ALLOWED_ORIGINS,
|
|
678
|
+
...input.origin ? [input.origin] : [],
|
|
679
|
+
...input.allowedOrigins ?? []
|
|
680
|
+
]);
|
|
681
|
+
let latestSession = null;
|
|
682
|
+
let latestCode = null;
|
|
683
|
+
const listener = (event) => {
|
|
684
|
+
if (!allowedOrigins.has(event.origin)) return;
|
|
685
|
+
const session = parseEmbeddedSignupMessage(event.data);
|
|
686
|
+
if (!session) return;
|
|
687
|
+
latestSession = session;
|
|
688
|
+
const normalizedEvent = normalizeCoexistenceSessionEvent(session.event);
|
|
689
|
+
if (normalizedEvent === "FINISH") {
|
|
690
|
+
input.onFinish?.({
|
|
691
|
+
code: latestCode,
|
|
692
|
+
session
|
|
693
|
+
});
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
if (normalizedEvent === "CANCEL") {
|
|
697
|
+
input.onCancel?.({ session });
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (normalizedEvent === "ERROR") {
|
|
701
|
+
input.onError?.({ session });
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
input.onProgress?.({ session });
|
|
705
|
+
};
|
|
706
|
+
input.target.addEventListener("message", listener);
|
|
707
|
+
input.fb.init?.(input.fbInit ?? {});
|
|
708
|
+
return {
|
|
709
|
+
result: new Promise((resolve) => {
|
|
710
|
+
input.fb.login((response) => {
|
|
711
|
+
latestCode = typeof response.authResponse?.code === "string" ? response.authResponse.code : null;
|
|
712
|
+
if (latestSession && normalizeCoexistenceSessionEvent(latestSession.event) === "FINISH") input.onFinish?.({
|
|
713
|
+
code: latestCode,
|
|
714
|
+
session: latestSession
|
|
715
|
+
});
|
|
716
|
+
resolve({
|
|
717
|
+
code: latestCode,
|
|
718
|
+
session: latestSession,
|
|
719
|
+
loginResponse: response
|
|
720
|
+
});
|
|
721
|
+
}, createCoexistenceEmbeddedSignupConfig(input));
|
|
722
|
+
}),
|
|
723
|
+
teardown() {
|
|
724
|
+
input.target.removeEventListener("message", listener);
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
}
|
|
728
|
+
//#endregion
|
|
729
|
+
//#region src/coexistence/memory-store.ts
|
|
730
|
+
const IN_FLIGHT_SYNC_STATUSES = new Set(["requested", "processing"]);
|
|
731
|
+
function timeValue(value) {
|
|
732
|
+
if (!value) return;
|
|
733
|
+
return value instanceof Date ? value.getTime() : new Date(value).getTime();
|
|
734
|
+
}
|
|
735
|
+
function cloneRecord(record) {
|
|
736
|
+
return structuredClone(record);
|
|
737
|
+
}
|
|
738
|
+
function isInFlight(job, now) {
|
|
739
|
+
if (!IN_FLIGHT_SYNC_STATUSES.has(job.status)) return false;
|
|
740
|
+
const deadline = timeValue(job.deadlineAt);
|
|
741
|
+
if (deadline !== void 0 && deadline <= now.getTime()) return false;
|
|
742
|
+
return true;
|
|
743
|
+
}
|
|
744
|
+
var InMemoryCoexistenceStore = class {
|
|
745
|
+
connectedAccounts = /* @__PURE__ */ new Map();
|
|
746
|
+
onboardingSessions = /* @__PURE__ */ new Map();
|
|
747
|
+
syncJobs = /* @__PURE__ */ new Map();
|
|
748
|
+
contacts = /* @__PURE__ */ new Map();
|
|
749
|
+
lifecycleEvents = [];
|
|
750
|
+
rawEventStatuses = /* @__PURE__ */ new Map();
|
|
751
|
+
preflightStates = /* @__PURE__ */ new Map();
|
|
752
|
+
async upsertConnectedAccount(account) {
|
|
753
|
+
const record = cloneRecord(account);
|
|
754
|
+
this.connectedAccounts.set(account.wabaId, record);
|
|
755
|
+
this.connectedAccounts.set(account.phoneNumberId, record);
|
|
756
|
+
if (account.preflight) await this.upsertPreflightState(account.preflight);
|
|
757
|
+
}
|
|
758
|
+
async getConnectedAccountByWabaId(wabaId) {
|
|
759
|
+
return cloneRecord(this.connectedAccounts.get(wabaId) ?? null);
|
|
760
|
+
}
|
|
761
|
+
async getConnectedAccountByPhoneNumberId(phoneNumberId) {
|
|
762
|
+
return cloneRecord(this.connectedAccounts.get(phoneNumberId) ?? null);
|
|
763
|
+
}
|
|
764
|
+
async recordOnboardingSession(session) {
|
|
765
|
+
this.onboardingSessions.set(session.id, cloneRecord(session));
|
|
766
|
+
if (session.preflight) await this.upsertPreflightState(session.preflight);
|
|
767
|
+
}
|
|
768
|
+
async upsertPreflightState(state) {
|
|
769
|
+
const record = cloneRecord(state);
|
|
770
|
+
if (state.phoneNumberId) this.preflightStates.set(state.phoneNumberId, record);
|
|
771
|
+
if (state.wabaId) this.preflightStates.set(state.wabaId, record);
|
|
772
|
+
}
|
|
773
|
+
async getPreflightStateByPhoneNumberId(phoneNumberId) {
|
|
774
|
+
return cloneRecord(this.preflightStates.get(phoneNumberId) ?? null);
|
|
775
|
+
}
|
|
776
|
+
async createSyncJob(job) {
|
|
777
|
+
if (await this.getInFlightSyncJob({
|
|
778
|
+
phoneNumberId: job.phoneNumberId,
|
|
779
|
+
syncType: job.syncType,
|
|
780
|
+
now: job.requestedAt ?? job.createdAt
|
|
781
|
+
})) throw new Error(`Coexistence sync already in flight for ${job.phoneNumberId}:${job.syncType}`);
|
|
782
|
+
this.syncJobs.set(job.requestId, cloneRecord(job));
|
|
783
|
+
}
|
|
784
|
+
async getInFlightSyncJob(input) {
|
|
785
|
+
const now = input.now instanceof Date ? input.now : new Date(input.now ?? Date.now());
|
|
786
|
+
for (const job of this.syncJobs.values()) {
|
|
787
|
+
if (job.phoneNumberId !== input.phoneNumberId || job.syncType !== input.syncType) continue;
|
|
788
|
+
if (isInFlight(job, now)) return cloneRecord(job);
|
|
789
|
+
if (IN_FLIGHT_SYNC_STATUSES.has(job.status) && job.deadlineAt) await this.updateSyncJobByRequestId(job.requestId, {
|
|
790
|
+
status: "deadline_exceeded",
|
|
791
|
+
failedAt: now,
|
|
792
|
+
failureReason: "sync_deadline_exceeded"
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
async updateSyncJobByRequestId(requestId, patch) {
|
|
798
|
+
const current = this.syncJobs.get(requestId);
|
|
799
|
+
if (!current) return;
|
|
800
|
+
this.syncJobs.set(requestId, cloneRecord({
|
|
801
|
+
...current,
|
|
802
|
+
...patch
|
|
803
|
+
}));
|
|
804
|
+
}
|
|
805
|
+
async upsertContact(contact) {
|
|
806
|
+
const key = `${contact.phoneNumberId ?? ""}:${contact.waId}`;
|
|
807
|
+
this.contacts.set(key, cloneRecord(contact));
|
|
808
|
+
}
|
|
809
|
+
async removeContact(input) {
|
|
810
|
+
this.contacts.delete(`${input.phoneNumberId ?? ""}:${input.waId}`);
|
|
811
|
+
}
|
|
812
|
+
async recordLifecycleEvent(event) {
|
|
813
|
+
this.lifecycleEvents.push(cloneRecord(event));
|
|
814
|
+
}
|
|
815
|
+
async updateRawEventStatus(status) {
|
|
816
|
+
this.rawEventStatuses.set(status.id, cloneRecord(status));
|
|
817
|
+
}
|
|
818
|
+
};
|
|
819
|
+
//#endregion
|
|
460
820
|
//#region src/services/message-logger.service.ts
|
|
461
821
|
const WHATSAPP_MESSAGE_TYPES = [
|
|
462
822
|
"queue_position",
|
|
@@ -511,7 +871,7 @@ var MessageLoggerService = class {
|
|
|
511
871
|
* Log outgoing message for LGPD compliance
|
|
512
872
|
*/
|
|
513
873
|
async logOutgoing(params) {
|
|
514
|
-
const inserted = await this.store.createWhatsAppLog({
|
|
874
|
+
const { record: inserted } = await this.store.createWhatsAppLog({
|
|
515
875
|
phone: params.phone,
|
|
516
876
|
userId: params.userId,
|
|
517
877
|
direction: "outgoing",
|
|
@@ -567,7 +927,7 @@ var MessageLoggerService = class {
|
|
|
567
927
|
* Log incoming message (for audit trail)
|
|
568
928
|
*/
|
|
569
929
|
async logIncoming(params) {
|
|
570
|
-
const inserted = await this.store.createWhatsAppLog({
|
|
930
|
+
const { record: inserted, created } = await this.store.createWhatsAppLog({
|
|
571
931
|
phone: params.phone,
|
|
572
932
|
contactName: params.senderName,
|
|
573
933
|
waMessageId: params.waMessageId,
|
|
@@ -578,12 +938,40 @@ var MessageLoggerService = class {
|
|
|
578
938
|
metadata: params.metadata,
|
|
579
939
|
sentAt: params.sentAt
|
|
580
940
|
});
|
|
941
|
+
if (!created) return false;
|
|
942
|
+
const conversation = await this.getConversationById(inserted.conversationId);
|
|
943
|
+
if (conversation) await this.notify({
|
|
944
|
+
type: "NEW_MESSAGE",
|
|
945
|
+
message: inserted,
|
|
946
|
+
conversation
|
|
947
|
+
});
|
|
948
|
+
return true;
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* Log an imported WhatsApp message with an explicit direction and timestamp.
|
|
952
|
+
* Used by coexistence history imports and app echo webhooks where the message
|
|
953
|
+
* did not originate from the local send API call.
|
|
954
|
+
*/
|
|
955
|
+
async logImportedMessage(params) {
|
|
956
|
+
const { record: inserted, created } = await this.store.createWhatsAppLog({
|
|
957
|
+
phone: params.phone,
|
|
958
|
+
contactName: params.senderName,
|
|
959
|
+
waMessageId: params.waMessageId,
|
|
960
|
+
direction: params.direction,
|
|
961
|
+
messageType: params.messageType ?? (params.direction === "incoming" ? "incoming" : "bot_reply"),
|
|
962
|
+
content: params.content,
|
|
963
|
+
status: params.direction === "incoming" ? "delivered" : "sent",
|
|
964
|
+
metadata: params.metadata,
|
|
965
|
+
sentAt: params.sentAt
|
|
966
|
+
});
|
|
967
|
+
if (!created) return false;
|
|
581
968
|
const conversation = await this.getConversationById(inserted.conversationId);
|
|
582
969
|
if (conversation) await this.notify({
|
|
583
970
|
type: "NEW_MESSAGE",
|
|
584
971
|
message: inserted,
|
|
585
972
|
conversation
|
|
586
973
|
});
|
|
974
|
+
return true;
|
|
587
975
|
}
|
|
588
976
|
};
|
|
589
977
|
//#endregion
|
|
@@ -669,11 +1057,14 @@ function serializeTemplateParameter(parameter, value) {
|
|
|
669
1057
|
}
|
|
670
1058
|
//#endregion
|
|
671
1059
|
exports.BetterZapClientError = require_client.BetterZapClientError;
|
|
1060
|
+
exports.CoexistenceService = CoexistenceService;
|
|
672
1061
|
exports.EMPTY_TEMPLATE_REGISTRY = EMPTY_TEMPLATE_REGISTRY;
|
|
673
1062
|
exports.FREEFORM_MESSAGE_WINDOW_MS = FREEFORM_MESSAGE_WINDOW_MS;
|
|
1063
|
+
exports.InMemoryCoexistenceStore = InMemoryCoexistenceStore;
|
|
674
1064
|
exports.MessageLoggerService = MessageLoggerService;
|
|
675
1065
|
exports.WHATSAPP_MESSAGE_TYPES = WHATSAPP_MESSAGE_TYPES;
|
|
676
1066
|
exports.WhatsAppService = WhatsAppService;
|
|
1067
|
+
exports.createCoexistenceEmbeddedSignupConfig = createCoexistenceEmbeddedSignupConfig;
|
|
677
1068
|
exports.createFreeformMessageWindow = createFreeformMessageWindow;
|
|
678
1069
|
exports.createLogger = createLogger;
|
|
679
1070
|
exports.createZapClient = require_client.createZapClient;
|
|
@@ -683,9 +1074,13 @@ exports.formatPhone = formatPhone;
|
|
|
683
1074
|
exports.getLatestIncomingMessageAt = getLatestIncomingMessageAt;
|
|
684
1075
|
exports.getTemplateNames = getTemplateNames;
|
|
685
1076
|
exports.hasConfiguredTemplates = hasConfiguredTemplates;
|
|
1077
|
+
exports.launchCoexistenceEmbeddedSignup = launchCoexistenceEmbeddedSignup;
|
|
686
1078
|
exports.noopLogger = noopLogger;
|
|
1079
|
+
exports.normalizeCoexistenceSessionEvent = normalizeCoexistenceSessionEvent;
|
|
1080
|
+
exports.normalizeCoexistenceSessionPayload = normalizeCoexistenceSessionPayload;
|
|
687
1081
|
exports.normalizeConversationRecord = normalizeConversationRecord;
|
|
688
1082
|
exports.normalizeConversationRecords = normalizeConversationRecords;
|
|
689
1083
|
exports.resolveConversationFreeformMessageWindow = resolveConversationFreeformMessageWindow;
|
|
690
1084
|
exports.serializeError = serializeError;
|
|
691
1085
|
exports.serializeTemplateFromRegistry = serializeTemplateFromRegistry;
|
|
1086
|
+
exports.toLegacyCoexistenceSessionEvent = toLegacyCoexistenceSessionEvent;
|