@tangle-network/agent-integrations 0.65.1 → 0.67.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/data/bundled-adapter-manifests.json +1 -1
- package/dist/{adapters-DjRVmzxH.js → adapters-CHzc3qI0.js} +232 -11
- package/dist/{adapters-DjRVmzxH.js.map → adapters-CHzc3qI0.js.map} +1 -1
- package/dist/{bundled-manifest-data-xFP7UmF5.js → bundled-manifest-data-wo3D0Q4P.js} +194 -1
- package/dist/{bundled-manifest-data-xFP7UmF5.js.map → bundled-manifest-data-wo3D0Q4P.js.map} +1 -1
- package/dist/connectors/adapters/index.js +1 -1
- package/dist/connectors/index.js +2 -2
- package/dist/conversation-events/index.d.ts +1 -1
- package/dist/conversation-events/index.js +180 -45
- package/dist/conversation-events/index.js.map +1 -1
- package/dist/index-BXhHnxfA.d.ts.map +1 -1
- package/dist/{index-DP2Dd0fS.d.ts → index-XYlfJKj-.d.ts} +4 -4
- package/dist/{index-DP2Dd0fS.d.ts.map → index-XYlfJKj-.d.ts.map} +1 -1
- package/dist/index.js +4 -4
- package/dist/internal/bundled-manifest-runtime.js +1 -1
- package/dist/mcp.js +1 -1
- package/dist/registry.js +1 -1
- package/dist/{specs-BX6jHOpg.js → specs-DyeHZSyC.js} +2 -2
- package/dist/{specs-BX6jHOpg.js.map → specs-DyeHZSyC.js.map} +1 -1
- package/dist/specs.js +1 -1
- package/dist/{src-nyf-V-SW.js → src-CvnOy-XH.js} +3 -3
- package/dist/{src-nyf-V-SW.js.map → src-CvnOy-XH.js.map} +1 -1
- package/dist/webhooks/index.d.ts +1 -1
- package/package.json +1 -1
|
@@ -392,13 +392,13 @@ function isRecord(value) {
|
|
|
392
392
|
}
|
|
393
393
|
//#endregion
|
|
394
394
|
//#region src/conversation-events/linq-whatsapp.ts
|
|
395
|
-
function object$
|
|
395
|
+
function object$2(value) {
|
|
396
396
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
397
397
|
}
|
|
398
398
|
function id(value) {
|
|
399
399
|
return typeof value === "string" && value.length > 0 && value.length <= 256 && !/[\u0000-\u001f\u007f]/.test(value);
|
|
400
400
|
}
|
|
401
|
-
const invalid$
|
|
401
|
+
const invalid$4 = (message) => ({
|
|
402
402
|
ok: false,
|
|
403
403
|
code: "invalid_payload",
|
|
404
404
|
message
|
|
@@ -436,25 +436,25 @@ function mediaPart(part) {
|
|
|
436
436
|
* Keep that customer opaque; never mislabel message.from (our number) as the sender. */
|
|
437
437
|
function normalizeLinqWhatsappConversation(input) {
|
|
438
438
|
const value = input.payload;
|
|
439
|
-
if (!object$
|
|
439
|
+
if (!object$2(value) || input.type !== `linq-whatsapp.${value.type}`) return invalid$4("Event type does not match the provider envelope");
|
|
440
440
|
if (value.type !== "message.received") return {
|
|
441
441
|
ok: false,
|
|
442
442
|
code: "unsupported_event",
|
|
443
443
|
message: "Not an incoming message"
|
|
444
444
|
};
|
|
445
|
-
if (!object$
|
|
445
|
+
if (!object$2(value.data) || !object$2(value.data.message)) return invalid$4("Read the chat journal to hydrate this historical event");
|
|
446
446
|
const message = value.data.message;
|
|
447
|
-
if (!id(value.id) || !id(message.id) || !id(message.chat_id) || !id(message.from) || message.direction !== "inbound") return invalid$
|
|
448
|
-
if (value.data.chat_id !== void 0 && value.data.chat_id !== message.chat_id) return invalid$
|
|
449
|
-
if (!Array.isArray(message.parts) || !message.parts.length || message.parts.length > 50) return invalid$
|
|
447
|
+
if (!id(value.id) || !id(message.id) || !id(message.chat_id) || !id(message.from) || message.direction !== "inbound") return invalid$4("Incoming message requires a stable identity, conversation and owned destination");
|
|
448
|
+
if (value.data.chat_id !== void 0 && value.data.chat_id !== message.chat_id) return invalid$4("Chat identity mismatch");
|
|
449
|
+
if (!Array.isArray(message.parts) || !message.parts.length || message.parts.length > 50) return invalid$4("Invalid message parts");
|
|
450
450
|
const text = [];
|
|
451
451
|
const attachments = [];
|
|
452
452
|
let historyOnly = false;
|
|
453
453
|
for (const part of message.parts) {
|
|
454
|
-
if (!object$
|
|
454
|
+
if (!object$2(part)) return invalid$4("Invalid message part");
|
|
455
455
|
if (part.type === "media") {
|
|
456
456
|
const media = mediaPart(part);
|
|
457
|
-
if (!media) return invalid$
|
|
457
|
+
if (!media) return invalid$4("Invalid media attachment");
|
|
458
458
|
attachments.push(media.attachment);
|
|
459
459
|
if (media.caption) text.push(media.caption);
|
|
460
460
|
if (!media.attachment.url) historyOnly = true;
|
|
@@ -466,7 +466,7 @@ function normalizeLinqWhatsappConversation(input) {
|
|
|
466
466
|
};
|
|
467
467
|
}
|
|
468
468
|
const occurredAt = typeof message.created_at === "string" ? Date.parse(message.created_at) : NaN;
|
|
469
|
-
if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) return invalid$
|
|
469
|
+
if (!Number.isSafeInteger(occurredAt) || occurredAt < 0) return invalid$4("Invalid message timestamp");
|
|
470
470
|
return {
|
|
471
471
|
ok: true,
|
|
472
472
|
event: {
|
|
@@ -514,7 +514,7 @@ function timestamp(value) {
|
|
|
514
514
|
function phone$1(value) {
|
|
515
515
|
return typeof value === "string" && /^\+[1-9]\d{6,14}$/.test(value);
|
|
516
516
|
}
|
|
517
|
-
const invalid$
|
|
517
|
+
const invalid$3 = (message) => ({
|
|
518
518
|
ok: false,
|
|
519
519
|
code: "invalid_payload",
|
|
520
520
|
message
|
|
@@ -545,13 +545,13 @@ function attachment(value) {
|
|
|
545
545
|
}
|
|
546
546
|
function finish(input, data) {
|
|
547
547
|
const id = string(data.id), conversation = string(data.conversation), sender = string(data.sender), destination = string(data.destination);
|
|
548
|
-
if (!id || !conversation || !sender || !destination) return invalid$
|
|
549
|
-
if (data.text !== null && data.text !== void 0 && (typeof data.text !== "string" || data.text.length > 1e6)) return invalid$
|
|
550
|
-
if (data.media !== void 0 && data.media !== null && (!Array.isArray(data.media) || data.media.length > 50)) return invalid$
|
|
548
|
+
if (!id || !conversation || !sender || !destination) return invalid$3("Message identity, conversation, sender and destination are required");
|
|
549
|
+
if (data.text !== null && data.text !== void 0 && (typeof data.text !== "string" || data.text.length > 1e6)) return invalid$3("Invalid message text");
|
|
550
|
+
if (data.media !== void 0 && data.media !== null && (!Array.isArray(data.media) || data.media.length > 50)) return invalid$3("Invalid attachment list");
|
|
551
551
|
const attachments = (data.media ?? []).map(attachment);
|
|
552
|
-
if (attachments.some((a) => !a)) return invalid$
|
|
552
|
+
if (attachments.some((a) => !a)) return invalid$3("Attachments require HTTPS references; bytes must be resolved through the authorized file boundary");
|
|
553
553
|
const time = timestamp(data.time);
|
|
554
|
-
if (time === null) return invalid$
|
|
554
|
+
if (time === null) return invalid$3("A valid provider timestamp is required");
|
|
555
555
|
return {
|
|
556
556
|
ok: true,
|
|
557
557
|
event: {
|
|
@@ -588,17 +588,17 @@ function finish(input, data) {
|
|
|
588
588
|
/** Called after the host verifies signatures and resolves the owning connection. */
|
|
589
589
|
function normalizeMobileConversation(input) {
|
|
590
590
|
const p = input.payload;
|
|
591
|
-
if (!record$2(p)) return invalid$
|
|
591
|
+
if (!record$2(p)) return invalid$3("Provider payload requires an object");
|
|
592
592
|
if (input.provider === "sendblue") {
|
|
593
593
|
if (input.type !== "sendblue.message.received") return unsupported$1();
|
|
594
|
-
if (p.is_outbound !== false || String(p.status).toUpperCase() !== "RECEIVED" || !phone$1(p.from_number) || !phone$1(p.sendblue_number) || p.to_number !== void 0 && p.to_number !== p.sendblue_number || p.number !== void 0 && p.number !== p.from_number) return invalid$
|
|
594
|
+
if (p.is_outbound !== false || String(p.status).toUpperCase() !== "RECEIVED" || !phone$1(p.from_number) || !phone$1(p.sendblue_number) || p.to_number !== void 0 && p.to_number !== p.sendblue_number || p.number !== void 0 && p.number !== p.from_number) return invalid$3("Sendblue requires an inbound received message with exact line and contact routing");
|
|
595
595
|
const service = typeof p.service === "string" ? p.service.toLowerCase() : null;
|
|
596
596
|
const transport = service === "imessage" ? "imessage" : service === "sms" ? "sms" : service === "rcs" ? "rcs" : null;
|
|
597
597
|
const messageType = typeof p.message_type === "string" ? p.message_type.toLowerCase() : null;
|
|
598
598
|
if (!transport || messageType !== "message" && messageType !== "group") return unsupported$1();
|
|
599
599
|
const group = messageType === "group" || Boolean(p.group_id);
|
|
600
|
-
if (group && !string(p.group_id, 256)) return invalid$
|
|
601
|
-
if (p.media_url !== void 0 && p.media_url !== null && typeof p.media_url !== "string") return invalid$
|
|
600
|
+
if (group && !string(p.group_id, 256)) return invalid$3("Group messages require a group id");
|
|
601
|
+
if (p.media_url !== void 0 && p.media_url !== null && typeof p.media_url !== "string") return invalid$3("Invalid Sendblue media URL");
|
|
602
602
|
return finish(input, {
|
|
603
603
|
id: p.message_handle,
|
|
604
604
|
conversation: group ? p.group_id : JSON.stringify([
|
|
@@ -620,21 +620,21 @@ function normalizeMobileConversation(input) {
|
|
|
620
620
|
}
|
|
621
621
|
if (input.provider === "twilio-sms") {
|
|
622
622
|
if (input.type !== "twilio-sms.message.received") return unsupported$1();
|
|
623
|
-
if (!/^AC[a-f\d]{32}$/i.test(String(p.AccountSid ?? "")) || !phone$1(p.From) || !phone$1(p.To) || !/^(SM|MM)[a-f\d]{32}$/i.test(String(p.MessageSid ?? ""))) return invalid$
|
|
623
|
+
if (!/^AC[a-f\d]{32}$/i.test(String(p.AccountSid ?? "")) || !phone$1(p.From) || !phone$1(p.To) || !/^(SM|MM)[a-f\d]{32}$/i.test(String(p.MessageSid ?? ""))) return invalid$3("Twilio message requires its signed account, SID, and phone routing");
|
|
624
624
|
const count = Number(p.NumMedia ?? 0);
|
|
625
|
-
if (!Number.isSafeInteger(count) || count < 0 || count > 10) return invalid$
|
|
625
|
+
if (!Number.isSafeInteger(count) || count < 0 || count > 10) return invalid$3("Invalid Twilio media count");
|
|
626
626
|
const media = [];
|
|
627
627
|
for (let index = 0; index < count; index++) {
|
|
628
628
|
const rawUrl = string(p[`MediaUrl${index}`], 8192);
|
|
629
|
-
if (!rawUrl) return invalid$
|
|
629
|
+
if (!rawUrl) return invalid$3("Missing Twilio media URL");
|
|
630
630
|
let url;
|
|
631
631
|
try {
|
|
632
632
|
url = new URL(rawUrl);
|
|
633
633
|
} catch {
|
|
634
|
-
return invalid$
|
|
634
|
+
return invalid$3("Invalid Twilio media URL");
|
|
635
635
|
}
|
|
636
636
|
const parts = /^\/2010-04-01\/Accounts\/(AC[a-f\d]{32})\/Messages\/((?:SM|MM)[a-f\d]{32})\/Media\/(ME[a-f\d]{32})$/i.exec(url.pathname);
|
|
637
|
-
if (url.origin !== "https://api.twilio.com" || url.username || url.password || url.search || !parts || parts[1].toLowerCase() !== String(p.AccountSid).toLowerCase() || parts[2].toLowerCase() !== String(p.MessageSid).toLowerCase()) return invalid$
|
|
637
|
+
if (url.origin !== "https://api.twilio.com" || url.username || url.password || url.search || !parts || parts[1].toLowerCase() !== String(p.AccountSid).toLowerCase() || parts[2].toLowerCase() !== String(p.MessageSid).toLowerCase()) return invalid$3("Twilio media URL must belong to the signed message and account");
|
|
638
638
|
media.push({
|
|
639
639
|
id: parts[3],
|
|
640
640
|
url: rawUrl,
|
|
@@ -657,13 +657,13 @@ function normalizeMobileConversation(input) {
|
|
|
657
657
|
transport: "sms"
|
|
658
658
|
});
|
|
659
659
|
}
|
|
660
|
-
if (!record$2(p.data)) return invalid$
|
|
660
|
+
if (!record$2(p.data)) return invalid$3("Provider payload requires a data object");
|
|
661
661
|
const data = p.data;
|
|
662
662
|
if (input.provider === "inkbox") {
|
|
663
|
-
if (input.type !== `inkbox.${p.event_type}`) return invalid$
|
|
663
|
+
if (input.type !== `inkbox.${p.event_type}`) return invalid$3("Event type does not match the provider envelope");
|
|
664
664
|
if (p.event_type === "imessage.received") {
|
|
665
665
|
const m = data.message;
|
|
666
|
-
if (!record$2(m) || m.direction !== "inbound") return invalid$
|
|
666
|
+
if (!record$2(m) || m.direction !== "inbound") return invalid$3("Expected an inbound iMessage");
|
|
667
667
|
return finish(input, {
|
|
668
668
|
id: m.id,
|
|
669
669
|
conversation: m.conversation_id,
|
|
@@ -678,7 +678,7 @@ function normalizeMobileConversation(input) {
|
|
|
678
678
|
}
|
|
679
679
|
if (p.event_type === "text.received") {
|
|
680
680
|
const m = data.text_message;
|
|
681
|
-
if (!record$2(m) || m.direction !== "inbound") return invalid$
|
|
681
|
+
if (!record$2(m) || m.direction !== "inbound") return invalid$3("Expected an inbound phone text");
|
|
682
682
|
return finish(input, {
|
|
683
683
|
id: m.id,
|
|
684
684
|
conversation: m.conversation_id,
|
|
@@ -694,7 +694,7 @@ function normalizeMobileConversation(input) {
|
|
|
694
694
|
}
|
|
695
695
|
if (p.event_type === "message.received") {
|
|
696
696
|
const m = data.message;
|
|
697
|
-
if (!record$2(m) || m.direction !== "inbound") return invalid$
|
|
697
|
+
if (!record$2(m) || m.direction !== "inbound") return invalid$3("Expected inbound mail");
|
|
698
698
|
return finish(input, {
|
|
699
699
|
id: m.id,
|
|
700
700
|
conversation: m.thread_id ?? m.id,
|
|
@@ -713,17 +713,17 @@ function normalizeMobileConversation(input) {
|
|
|
713
713
|
return unsupported$1();
|
|
714
714
|
}
|
|
715
715
|
if (input.provider === "linq") {
|
|
716
|
-
if (input.type !== `linq.${p.event_type}`) return invalid$
|
|
716
|
+
if (input.type !== `linq.${p.event_type}`) return invalid$3("Event type does not match the provider envelope");
|
|
717
717
|
if (p.event_type !== "message.received") return unsupported$1();
|
|
718
|
-
if (p.webhook_version !== "2026-02-03" || data.direction !== "inbound" || !record$2(data.chat) || !record$2(data.sender_handle) || !record$2(data.chat.owner_handle) || data.chat.owner_handle.is_me !== true || data.sender_handle.is_me === true) return invalid$
|
|
718
|
+
if (p.webhook_version !== "2026-02-03" || data.direction !== "inbound" || !record$2(data.chat) || !record$2(data.sender_handle) || !record$2(data.chat.owner_handle) || data.chat.owner_handle.is_me !== true || data.sender_handle.is_me === true) return invalid$3("Linq requires v2026-02-03 incoming payloads with explicit sender and owner handles");
|
|
719
719
|
const transport = data.service === "iMessage" ? "imessage" : data.service === "SMS" ? "sms" : data.service === "RCS" ? "rcs" : null;
|
|
720
|
-
if (!transport) return invalid$
|
|
721
|
-
if (!Array.isArray(data.parts) || data.parts.length > 50) return invalid$
|
|
720
|
+
if (!transport) return invalid$3("Linq incoming message requires its actual service");
|
|
721
|
+
if (!Array.isArray(data.parts) || data.parts.length > 50) return invalid$3("Invalid Linq parts");
|
|
722
722
|
const texts = [], media = [];
|
|
723
723
|
for (const part of data.parts) {
|
|
724
|
-
if (!record$2(part)) return invalid$
|
|
724
|
+
if (!record$2(part)) return invalid$3("Invalid Linq part");
|
|
725
725
|
if (part.type === "text" || part.type === "link") {
|
|
726
|
-
if (typeof part.value !== "string") return invalid$
|
|
726
|
+
if (typeof part.value !== "string") return invalid$3("Invalid Linq text");
|
|
727
727
|
texts.push(part.value);
|
|
728
728
|
} else if (part.type === "media") media.push(part);
|
|
729
729
|
else return unsupported$1();
|
|
@@ -744,13 +744,13 @@ function normalizeMobileConversation(input) {
|
|
|
744
744
|
});
|
|
745
745
|
}
|
|
746
746
|
if (input.provider === "contiguity") {
|
|
747
|
-
if (input.type !== `contiguity.${p.type}`) return invalid$
|
|
747
|
+
if (input.type !== `contiguity.${p.type}`) return invalid$3("Event type does not match the provider envelope");
|
|
748
748
|
if (![
|
|
749
749
|
"imessage.incoming",
|
|
750
750
|
"text.incoming.sms",
|
|
751
751
|
"text.incoming.mms"
|
|
752
752
|
].includes(String(p.type))) return unsupported$1();
|
|
753
|
-
if (!string(data.to, 320) || !string(data.from, 320)) return invalid$
|
|
753
|
+
if (!string(data.to, 320) || !string(data.from, 320)) return invalid$3("Missing Contiguity phone routing");
|
|
754
754
|
return finish(input, {
|
|
755
755
|
id: p.id,
|
|
756
756
|
conversation: JSON.stringify([
|
|
@@ -782,7 +782,7 @@ function address(value) {
|
|
|
782
782
|
if (typeof value !== "string" || value.length > 320) return null;
|
|
783
783
|
return /^(?:[^<>]*<)?([^<>\s]+@[^<>\s]+)(?:>)?$/.exec(value.trim())?.[1]?.toLowerCase() ?? null;
|
|
784
784
|
}
|
|
785
|
-
const invalid$
|
|
785
|
+
const invalid$2 = (message) => ({
|
|
786
786
|
ok: false,
|
|
787
787
|
code: "invalid_payload",
|
|
788
788
|
message
|
|
@@ -790,13 +790,13 @@ const invalid$1 = (message) => ({
|
|
|
790
790
|
/** The host adds the provider-read email after verifying the notification. */
|
|
791
791
|
function normalizeResendConversation(input) {
|
|
792
792
|
const payload = input.payload;
|
|
793
|
-
if (input.type !== "resend.email.received" || !record$1(payload) || payload.type !== "email.received" || !record$1(payload.data) || !record$1(payload.received)) return invalid$
|
|
793
|
+
if (input.type !== "resend.email.received" || !record$1(payload) || payload.type !== "email.received" || !record$1(payload.data) || !record$1(payload.received)) return invalid$2("Resend requires a hydrated received-email notification");
|
|
794
794
|
const data = payload.data, received = payload.received;
|
|
795
|
-
if (typeof data.email_id !== "string" || received.id !== data.email_id || !Array.isArray(received.to) || received.to.length < 1 || received.to.length > 50 || received.cc !== void 0 && (!Array.isArray(received.cc) || received.cc.length > 50) || !address(received.from) || received.text != null && typeof received.text !== "string" || typeof received.created_at !== "string" || !Number.isFinite(Date.parse(received.created_at))) return invalid$
|
|
795
|
+
if (typeof data.email_id !== "string" || received.id !== data.email_id || !Array.isArray(received.to) || received.to.length < 1 || received.to.length > 50 || received.cc !== void 0 && (!Array.isArray(received.cc) || received.cc.length > 50) || !address(received.from) || received.text != null && typeof received.text !== "string" || typeof received.created_at !== "string" || !Number.isFinite(Date.parse(received.created_at))) return invalid$2("Resend email identity, sender, recipient, body or time is invalid");
|
|
796
796
|
const recipients = [...received.to, ...received.cc ?? []].map(address);
|
|
797
|
-
if (recipients.some((item) => !item)) return invalid$
|
|
797
|
+
if (recipients.some((item) => !item)) return invalid$2("Resend recipient address is invalid");
|
|
798
798
|
const attachments = Array.isArray(received.attachments) ? received.attachments : [];
|
|
799
|
-
if (attachments.length > 50 || attachments.some((item) => !record$1(item) || typeof item.id !== "string")) return invalid$
|
|
799
|
+
if (attachments.length > 50 || attachments.some((item) => !record$1(item) || typeof item.id !== "string")) return invalid$2("Resend attachments require provider ids");
|
|
800
800
|
const sender = address(received.from);
|
|
801
801
|
return {
|
|
802
802
|
ok: true,
|
|
@@ -841,6 +841,106 @@ function normalizeResendConversation(input) {
|
|
|
841
841
|
};
|
|
842
842
|
}
|
|
843
843
|
//#endregion
|
|
844
|
+
//#region src/conversation-events/telegram.ts
|
|
845
|
+
function object$1(value) {
|
|
846
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
847
|
+
}
|
|
848
|
+
function integer(value, positive = true) {
|
|
849
|
+
return typeof value === "number" && Number.isSafeInteger(value) && (positive ? value > 0 : value !== 0);
|
|
850
|
+
}
|
|
851
|
+
const invalid$1 = (message) => ({
|
|
852
|
+
ok: false,
|
|
853
|
+
code: "invalid_payload",
|
|
854
|
+
message
|
|
855
|
+
});
|
|
856
|
+
/** Parse only new human messages. The verified webhook proves origin; the host
|
|
857
|
+
* must still check live bot membership and the sender's authority before acting.
|
|
858
|
+
* Addresses include chat, forum topic and sender to prevent session reuse across
|
|
859
|
+
* groups, topics or people. Anonymous/channel senders cannot acquire user rights. */
|
|
860
|
+
function normalizeTelegramConversation(input) {
|
|
861
|
+
if (input.type !== "telegram.message") return {
|
|
862
|
+
ok: false,
|
|
863
|
+
code: "unsupported_event",
|
|
864
|
+
message: "Not a new Telegram message"
|
|
865
|
+
};
|
|
866
|
+
const envelope = input.payload;
|
|
867
|
+
if (!object$1(envelope) || !Number.isSafeInteger(envelope.update_id) || envelope.update_id < 0 || !object$1(envelope.message)) return invalid$1("Telegram requires an update id and message");
|
|
868
|
+
const message = envelope.message;
|
|
869
|
+
const chat = message.chat;
|
|
870
|
+
const from = message.from;
|
|
871
|
+
if (!object$1(chat) || !object$1(from) || !integer(chat.id, false) || !integer(from.id) || from.is_bot !== false || message.sender_chat !== void 0 || !integer(message.message_id) || !integer(message.date) || !Number.isSafeInteger(message.date * 1e3) || ![
|
|
872
|
+
"private",
|
|
873
|
+
"group",
|
|
874
|
+
"supergroup"
|
|
875
|
+
].includes(String(chat.type)) || (chat.type === "private" ? chat.id !== from.id : chat.id >= 0)) return invalid$1("Telegram requires a human sender and supported chat identity");
|
|
876
|
+
const topic = message.message_thread_id;
|
|
877
|
+
if (topic !== void 0 && (!integer(topic) || chat.type !== "supergroup")) return invalid$1("Invalid Telegram topic");
|
|
878
|
+
const text = message.text ?? message.caption ?? "";
|
|
879
|
+
if (typeof text !== "string" || text.length > 4096 || text.includes("\0")) return invalid$1("Invalid Telegram message text");
|
|
880
|
+
const media = [];
|
|
881
|
+
if (message.photo !== void 0) {
|
|
882
|
+
if (!Array.isArray(message.photo) || message.photo.length === 0 || message.photo.length > 20) return invalid$1("Invalid Telegram photo");
|
|
883
|
+
media.push(message.photo[message.photo.length - 1]);
|
|
884
|
+
}
|
|
885
|
+
for (const kind of [
|
|
886
|
+
"document",
|
|
887
|
+
"audio",
|
|
888
|
+
"voice",
|
|
889
|
+
"video",
|
|
890
|
+
"video_note",
|
|
891
|
+
"animation",
|
|
892
|
+
"sticker"
|
|
893
|
+
]) if (message[kind] !== void 0) media.push(message[kind]);
|
|
894
|
+
const attachments = [];
|
|
895
|
+
for (const file of media) {
|
|
896
|
+
if (!object$1(file) || typeof file.file_id !== "string" || !/^[A-Za-z0-9_-]{1,512}$/.test(file.file_id) || file.file_size !== void 0 && (!Number.isSafeInteger(file.file_size) || file.file_size < 0)) return invalid$1("Invalid Telegram attachment");
|
|
897
|
+
attachments.push({
|
|
898
|
+
id: file.file_id,
|
|
899
|
+
name: typeof file.file_name === "string" ? file.file_name.slice(0, 255) : null,
|
|
900
|
+
contentType: typeof file.mime_type === "string" ? file.mime_type.slice(0, 200) : null,
|
|
901
|
+
size: typeof file.file_size === "number" ? file.file_size : null,
|
|
902
|
+
contentBase64: null,
|
|
903
|
+
url: null
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
if (!text.trim() && attachments.length === 0) return {
|
|
907
|
+
ok: false,
|
|
908
|
+
code: "unsupported_event",
|
|
909
|
+
message: "No message content"
|
|
910
|
+
};
|
|
911
|
+
return {
|
|
912
|
+
ok: true,
|
|
913
|
+
event: {
|
|
914
|
+
version: 1,
|
|
915
|
+
provider: "telegram",
|
|
916
|
+
eventType: input.type,
|
|
917
|
+
operation: "created",
|
|
918
|
+
eventId: `${chat.id}:${message.message_id}`,
|
|
919
|
+
conversationId: String(chat.id),
|
|
920
|
+
parentEventIds: object$1(message.reply_to_message) && integer(message.reply_to_message.message_id) ? [`${chat.id}:${message.reply_to_message.message_id}`] : [],
|
|
921
|
+
sender: {
|
|
922
|
+
id: String(from.id),
|
|
923
|
+
address: `telegram:${chat.id}:${topic ?? 0}:${from.id}`,
|
|
924
|
+
displayName: typeof from.first_name === "string" ? from.first_name.slice(0, 100) : null
|
|
925
|
+
},
|
|
926
|
+
destinations: [{
|
|
927
|
+
kind: "chat",
|
|
928
|
+
id: String(chat.id),
|
|
929
|
+
address: `telegram:${chat.id}`,
|
|
930
|
+
displayName: null
|
|
931
|
+
}],
|
|
932
|
+
subject: null,
|
|
933
|
+
text,
|
|
934
|
+
html: null,
|
|
935
|
+
attachments,
|
|
936
|
+
occurredAt: message.date * 1e3,
|
|
937
|
+
transport: "telegram",
|
|
938
|
+
isGroup: chat.type !== "private",
|
|
939
|
+
historyOnly: false
|
|
940
|
+
}
|
|
941
|
+
};
|
|
942
|
+
}
|
|
943
|
+
//#endregion
|
|
844
944
|
//#region src/conversation-events/reply.ts
|
|
845
945
|
function object(value) {
|
|
846
946
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
@@ -885,7 +985,27 @@ function buildMessagingReply(input, text, operationId) {
|
|
|
885
985
|
const event = normalized.event;
|
|
886
986
|
if (typeof text !== "string" || !text.trim() || text.length > 1e4 || text.includes("\0")) return fail("Reply text is empty or exceeds its limit");
|
|
887
987
|
if (!validOperationId(operationId)) return fail("A stable operation id is required");
|
|
888
|
-
if (event.historyOnly || event.isGroup) return fail("This event requires review or complete input before a reply");
|
|
988
|
+
if (event.historyOnly || event.isGroup && event.provider !== "telegram") return fail("This event requires review or complete input before a reply");
|
|
989
|
+
if (event.provider === "telegram") {
|
|
990
|
+
if (text.length > 4096) return fail("Telegram text is limited to 4096 characters");
|
|
991
|
+
const message = object(object(input.payload).message);
|
|
992
|
+
return {
|
|
993
|
+
ok: true,
|
|
994
|
+
reply: {
|
|
995
|
+
idempotencyKey: operationId,
|
|
996
|
+
action: "telegram.sendMessage",
|
|
997
|
+
input: {
|
|
998
|
+
chat_id: event.conversationId,
|
|
999
|
+
text,
|
|
1000
|
+
reply_parameters: {
|
|
1001
|
+
message_id: message.message_id,
|
|
1002
|
+
allow_sending_without_reply: true
|
|
1003
|
+
},
|
|
1004
|
+
...message.message_thread_id === void 0 ? {} : { message_thread_id: message.message_thread_id }
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
889
1009
|
const data = object(object(input.payload).data);
|
|
890
1010
|
if (event.provider === "inkbox") {
|
|
891
1011
|
if (event.eventType === "inkbox.imessage.received") return {
|
|
@@ -1068,6 +1188,15 @@ function buildMessagingMediaReply(input, media, operationId) {
|
|
|
1068
1188
|
//#endregion
|
|
1069
1189
|
//#region src/conversation-events/channels.ts
|
|
1070
1190
|
const channels = [
|
|
1191
|
+
{
|
|
1192
|
+
providerId: "telegram",
|
|
1193
|
+
eventType: "telegram.message",
|
|
1194
|
+
label: "Telegram",
|
|
1195
|
+
transport: "telegram",
|
|
1196
|
+
sourceKind: "connection",
|
|
1197
|
+
replies: true,
|
|
1198
|
+
replyAction: "telegram.sendMessage"
|
|
1199
|
+
},
|
|
1071
1200
|
{
|
|
1072
1201
|
providerId: "email",
|
|
1073
1202
|
eventType: "email.received",
|
|
@@ -1465,13 +1594,19 @@ function normalizeConversationEvent(value) {
|
|
|
1465
1594
|
"linq-whatsapp",
|
|
1466
1595
|
"resend",
|
|
1467
1596
|
"sendblue",
|
|
1468
|
-
"twilio-sms"
|
|
1597
|
+
"twilio-sms",
|
|
1598
|
+
"telegram"
|
|
1469
1599
|
].includes(String(value.provider))) {
|
|
1470
1600
|
if (!("type" in value) || typeof value.type !== "string" || !("payload" in value)) return {
|
|
1471
1601
|
ok: false,
|
|
1472
1602
|
code: "invalid_payload",
|
|
1473
1603
|
message: "Provider event requires type and payload"
|
|
1474
1604
|
};
|
|
1605
|
+
if (value.provider === "telegram") return normalizeTelegramConversation({
|
|
1606
|
+
provider: value.provider,
|
|
1607
|
+
type: value.type,
|
|
1608
|
+
payload: value.payload
|
|
1609
|
+
});
|
|
1475
1610
|
if (value.provider === "linq-whatsapp") return normalizeLinqWhatsappConversation({
|
|
1476
1611
|
provider: value.provider,
|
|
1477
1612
|
type: value.type,
|