@cogitator-ai/channels 0.16.0 → 0.18.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 +78 -14
- package/dist/approvals.d.ts +3 -0
- package/dist/approvals.d.ts.map +1 -1
- package/dist/approvals.js +1 -0
- package/dist/approvals.js.map +1 -1
- package/dist/assistant-config.d.ts +60 -0
- package/dist/assistant-config.d.ts.map +1 -1
- package/dist/assistant-config.js +102 -0
- package/dist/assistant-config.js.map +1 -1
- package/dist/channels/email/address.d.ts +44 -0
- package/dist/channels/email/address.d.ts.map +1 -0
- package/dist/channels/email/address.js +211 -0
- package/dist/channels/email/address.js.map +1 -0
- package/dist/channels/email/auth.d.ts +59 -0
- package/dist/channels/email/auth.d.ts.map +1 -0
- package/dist/channels/email/auth.js +212 -0
- package/dist/channels/email/auth.js.map +1 -0
- package/dist/channels/email/channel.d.ts +256 -0
- package/dist/channels/email/channel.d.ts.map +1 -0
- package/dist/channels/email/channel.js +701 -0
- package/dist/channels/email/channel.js.map +1 -0
- package/dist/channels/email/errors.d.ts +11 -0
- package/dist/channels/email/errors.d.ts.map +1 -0
- package/dist/channels/email/errors.js +13 -0
- package/dist/channels/email/errors.js.map +1 -0
- package/dist/channels/email/imap.d.ts +125 -0
- package/dist/channels/email/imap.d.ts.map +1 -0
- package/dist/channels/email/imap.js +309 -0
- package/dist/channels/email/imap.js.map +1 -0
- package/dist/channels/email/index.d.ts +7 -0
- package/dist/channels/email/index.d.ts.map +1 -0
- package/dist/channels/email/index.js +3 -0
- package/dist/channels/email/index.js.map +1 -0
- package/dist/channels/email/mime.d.ts +71 -0
- package/dist/channels/email/mime.d.ts.map +1 -0
- package/dist/channels/email/mime.js +83 -0
- package/dist/channels/email/mime.js.map +1 -0
- package/dist/channels/email/multipart.d.ts +28 -0
- package/dist/channels/email/multipart.d.ts.map +1 -0
- package/dist/channels/email/multipart.js +102 -0
- package/dist/channels/email/multipart.js.map +1 -0
- package/dist/channels/email/providers.d.ts +49 -0
- package/dist/channels/email/providers.d.ts.map +1 -0
- package/dist/channels/email/providers.js +292 -0
- package/dist/channels/email/providers.js.map +1 -0
- package/dist/channels/email/reply.d.ts +9 -0
- package/dist/channels/email/reply.d.ts.map +1 -0
- package/dist/channels/email/reply.js +122 -0
- package/dist/channels/email/reply.js.map +1 -0
- package/dist/channels/teams/activity.d.ts +108 -0
- package/dist/channels/teams/activity.d.ts.map +1 -0
- package/dist/channels/teams/activity.js +206 -0
- package/dist/channels/teams/activity.js.map +1 -0
- package/dist/channels/teams/auth.d.ts +65 -0
- package/dist/channels/teams/auth.d.ts.map +1 -0
- package/dist/channels/teams/auth.js +213 -0
- package/dist/channels/teams/auth.js.map +1 -0
- package/dist/channels/teams/cards.d.ts +23 -0
- package/dist/channels/teams/cards.d.ts.map +1 -0
- package/dist/channels/teams/cards.js +97 -0
- package/dist/channels/teams/cards.js.map +1 -0
- package/dist/channels/teams/channel.d.ts +303 -0
- package/dist/channels/teams/channel.d.ts.map +1 -0
- package/dist/channels/teams/channel.js +1071 -0
- package/dist/channels/teams/channel.js.map +1 -0
- package/dist/channels/teams/client.d.ts +72 -0
- package/dist/channels/teams/client.d.ts.map +1 -0
- package/dist/channels/teams/client.js +161 -0
- package/dist/channels/teams/client.js.map +1 -0
- package/dist/channels/teams/index.d.ts +7 -0
- package/dist/channels/teams/index.d.ts.map +1 -0
- package/dist/channels/teams/index.js +6 -0
- package/dist/channels/teams/index.js.map +1 -0
- package/dist/channels/teams/pacer.d.ts +47 -0
- package/dist/channels/teams/pacer.d.ts.map +1 -0
- package/dist/channels/teams/pacer.js +174 -0
- package/dist/channels/teams/pacer.js.map +1 -0
- package/dist/channels/teams/token.d.ts +47 -0
- package/dist/channels/teams/token.d.ts.map +1 -0
- package/dist/channels/teams/token.js +107 -0
- package/dist/channels/teams/token.js.map +1 -0
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +3 -0
- package/dist/channels/telegram.js.map +1 -1
- package/dist/formatters/html.d.ts +16 -0
- package/dist/formatters/html.d.ts.map +1 -0
- package/dist/formatters/html.js +535 -0
- package/dist/formatters/html.js.map +1 -0
- package/dist/formatters/markdown-images.d.ts +8 -0
- package/dist/formatters/markdown-images.d.ts.map +1 -0
- package/dist/formatters/markdown-images.js +181 -0
- package/dist/formatters/markdown-images.js.map +1 -0
- package/dist/formatters/markdown.d.ts.map +1 -1
- package/dist/formatters/markdown.js +22 -3
- package/dist/formatters/markdown.js.map +1 -1
- package/dist/gateway.d.ts +23 -1
- package/dist/gateway.d.ts.map +1 -1
- package/dist/gateway.js +113 -16
- package/dist/gateway.js.map +1 -1
- package/dist/inbound-debounce.d.ts +4 -1
- package/dist/inbound-debounce.d.ts.map +1 -1
- package/dist/inbound-debounce.js +4 -2
- package/dist/inbound-debounce.js.map +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/runtime-builder.d.ts +9 -0
- package/dist/runtime-builder.d.ts.map +1 -1
- package/dist/runtime-builder.js +145 -1
- package/dist/runtime-builder.js.map +1 -1
- package/package.json +25 -8
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/** The longest line read as an attribution: longer ones are text, whatever they say. */
|
|
2
|
+
const MAX_ATTRIBUTION = 500;
|
|
3
|
+
/**
|
|
4
|
+
* Lines that introduce a quoted message, as mail clients write them in several languages: how
|
|
5
|
+
* they start and the word that names the writing. Checked as two linear tests, not one pattern.
|
|
6
|
+
*/
|
|
7
|
+
const ATTRIBUTIONS = [
|
|
8
|
+
[/^On\b/i, /\bwrote:$/i],
|
|
9
|
+
[/^Le\b/i, /\ba écrit\s?:$/i],
|
|
10
|
+
[/^Am\b/i, /\bschrieb\b/i],
|
|
11
|
+
[/^El\b/i, /\bescribió:$/i],
|
|
12
|
+
[/^Em\b/i, /\bescreveu:$/i],
|
|
13
|
+
[/^Op\b/i, /\bschreef\b/i],
|
|
14
|
+
[/^Il\b/i, /\bha scritto:$/i],
|
|
15
|
+
];
|
|
16
|
+
function isAttribution(line) {
|
|
17
|
+
if (line.length > MAX_ATTRIBUTION || !line.endsWith(':'))
|
|
18
|
+
return false;
|
|
19
|
+
return ATTRIBUTIONS.some(([start, word]) => start.test(line) && word.test(line));
|
|
20
|
+
}
|
|
21
|
+
const ADDRESS_TOKEN = /^<?[^\s@<>]+@[^\s@<>.]+(?:\.[^\s@<>.]+)+>?,?$/;
|
|
22
|
+
const WROTE = /^(пишет|написал\(а\)|написала?|wrote)$/i;
|
|
23
|
+
/**
|
|
24
|
+
* A line that ends with an address and a colon, as Gmail and Yandex write in Russian
|
|
25
|
+
* (`пн, 19 окт. 2026 г. в 10:00, Иван <ivan@example.ru>:`), read token by token.
|
|
26
|
+
*/
|
|
27
|
+
function isAddressAttribution(line) {
|
|
28
|
+
if (line.length > MAX_ATTRIBUTION || !line.endsWith(':'))
|
|
29
|
+
return false;
|
|
30
|
+
const words = line.slice(0, -1).trim().split(/\s+/);
|
|
31
|
+
let last = words.pop() ?? '';
|
|
32
|
+
if (WROTE.test(last))
|
|
33
|
+
last = words.pop() ?? '';
|
|
34
|
+
return ADDRESS_TOKEN.test(last);
|
|
35
|
+
}
|
|
36
|
+
const FORWARD_HEADER = /^(-{2,}\s*(Original Message|Ursprüngliche Nachricht|Исходное сообщение|Message d'origine)\s*-{2,}|_{10,})$/i;
|
|
37
|
+
const OUTLOOK_FROM = /^\*?(From|De|Von|От|Van|Da):\*?\s/i;
|
|
38
|
+
const OUTLOOK_FIELD = /^\*?(Sent|Date|To|Subject|Cc|Envoyé|Gesendet|Отправлено|Дата|Кому|Тема|Verzonden|Inviato|Enviado|Objet|Betreff|À|An|Aan|A|Para):\*?\s/i;
|
|
39
|
+
const MOBILE_SIGNATURE = /^(Sent from my \S+|Sent from (Mail|Outlook|Yahoo Mail) for \S+|Get Outlook for \S+|Отправлено с \S+)/i;
|
|
40
|
+
function isQuoted(line) {
|
|
41
|
+
return /^\s*>/.test(line);
|
|
42
|
+
}
|
|
43
|
+
function linesBelow(lines) {
|
|
44
|
+
const nextContent = new Array(lines.length + 1);
|
|
45
|
+
const onlyQuotes = new Array(lines.length + 1);
|
|
46
|
+
nextContent[lines.length] = lines.length;
|
|
47
|
+
onlyQuotes[lines.length] = false;
|
|
48
|
+
let clean = true;
|
|
49
|
+
let quoted = false;
|
|
50
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
51
|
+
const blank = !lines[i].trim();
|
|
52
|
+
nextContent[i] = blank ? nextContent[i + 1] : i;
|
|
53
|
+
if (!blank) {
|
|
54
|
+
if (isQuoted(lines[i]))
|
|
55
|
+
quoted = true;
|
|
56
|
+
else
|
|
57
|
+
clean = false;
|
|
58
|
+
}
|
|
59
|
+
onlyQuotes[i] = clean && quoted;
|
|
60
|
+
}
|
|
61
|
+
return { nextContent, onlyQuotes };
|
|
62
|
+
}
|
|
63
|
+
/** Where a quoted message starts, if it starts at line `i`: its attribution or separator. */
|
|
64
|
+
function quoteStartsAt(lines, i, below) {
|
|
65
|
+
const line = lines[i].trim();
|
|
66
|
+
if (!line)
|
|
67
|
+
return false;
|
|
68
|
+
if (FORWARD_HEADER.test(line))
|
|
69
|
+
return true;
|
|
70
|
+
const wrapped = i + 1 < lines.length && line.length <= MAX_ATTRIBUTION;
|
|
71
|
+
const joined = wrapped ? `${line} ${lines[i + 1].trim()}` : line;
|
|
72
|
+
const single = isAttribution(line);
|
|
73
|
+
if (single || (wrapped && isAttribution(joined))) {
|
|
74
|
+
const next = below.nextContent[single ? i + 1 : i + 2] ?? lines.length;
|
|
75
|
+
return next >= lines.length || isQuoted(lines[next]) || OUTLOOK_FROM.test(lines[next]);
|
|
76
|
+
}
|
|
77
|
+
if (isAddressAttribution(line)) {
|
|
78
|
+
const next = below.nextContent[i + 1];
|
|
79
|
+
return next < lines.length && below.onlyQuotes[next];
|
|
80
|
+
}
|
|
81
|
+
if (OUTLOOK_FROM.test(line)) {
|
|
82
|
+
let fields = 0;
|
|
83
|
+
for (let j = i + 1; j < Math.min(lines.length, i + 6); j++) {
|
|
84
|
+
if (OUTLOOK_FIELD.test(lines[j].trim()))
|
|
85
|
+
fields++;
|
|
86
|
+
}
|
|
87
|
+
return fields >= 2;
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The new text of a reply, without what it quotes: the history after an attribution line
|
|
93
|
+
* (`On ... wrote:` and its translations, `-----Original Message-----`, an Outlook `From:` and
|
|
94
|
+
* `Sent:` block), a trailing block of `>` quotes, the signature after a `-- ` line and a
|
|
95
|
+
* `Sent from my ...` line. Quotes the writer answers between are kept, as they say what each
|
|
96
|
+
* answer is about. Returns the text unchanged when stripping would leave nothing.
|
|
97
|
+
*/
|
|
98
|
+
export function stripQuotedReply(text) {
|
|
99
|
+
const lines = text.replace(/\r\n?/g, '\n').split('\n');
|
|
100
|
+
const below = linesBelow(lines);
|
|
101
|
+
let end = lines.length;
|
|
102
|
+
for (let i = 0; i < lines.length; i++) {
|
|
103
|
+
if (lines[i] === '-- ' || lines[i] === '--') {
|
|
104
|
+
end = i;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
if (quoteStartsAt(lines, i, below)) {
|
|
108
|
+
end = i;
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
let kept = lines.slice(0, end);
|
|
113
|
+
while (kept.length > 0 && (!kept[kept.length - 1].trim() || isQuoted(kept[kept.length - 1]))) {
|
|
114
|
+
kept.pop();
|
|
115
|
+
}
|
|
116
|
+
const last = kept.length - 1;
|
|
117
|
+
if (last >= 0 && MOBILE_SIGNATURE.test(kept[last].trim()))
|
|
118
|
+
kept = kept.slice(0, last);
|
|
119
|
+
const stripped = kept.join('\n').trim();
|
|
120
|
+
return stripped || text.trim();
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=reply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reply.js","sourceRoot":"","sources":["../../../src/channels/email/reply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
declare const AttachmentSchema: z.ZodObject<{
|
|
3
|
+
contentType: z.ZodString;
|
|
4
|
+
contentUrl: z.ZodOptional<z.ZodString>;
|
|
5
|
+
name: z.ZodOptional<z.ZodString>;
|
|
6
|
+
content: z.ZodOptional<z.ZodUnknown>;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
declare const ActivitySchema: z.ZodObject<{
|
|
9
|
+
type: z.ZodString;
|
|
10
|
+
id: z.ZodOptional<z.ZodString>;
|
|
11
|
+
name: z.ZodOptional<z.ZodString>;
|
|
12
|
+
channelId: z.ZodString;
|
|
13
|
+
serviceUrl: z.ZodString;
|
|
14
|
+
from: z.ZodObject<{
|
|
15
|
+
id: z.ZodString;
|
|
16
|
+
name: z.ZodOptional<z.ZodString>;
|
|
17
|
+
aadObjectId: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
recipient: z.ZodOptional<z.ZodObject<{
|
|
20
|
+
id: z.ZodString;
|
|
21
|
+
name: z.ZodOptional<z.ZodString>;
|
|
22
|
+
aadObjectId: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strip>>;
|
|
24
|
+
conversation: z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
conversationType: z.ZodOptional<z.ZodString>;
|
|
27
|
+
tenantId: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
text: z.ZodOptional<z.ZodString>;
|
|
30
|
+
replyToId: z.ZodOptional<z.ZodString>;
|
|
31
|
+
value: z.ZodOptional<z.ZodUnknown>;
|
|
32
|
+
entities: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
33
|
+
attachments: z.ZodOptional<z.ZodArray<z.ZodUnknown>>;
|
|
34
|
+
channelData: z.ZodOptional<z.ZodUnknown>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
/** An activity Bot Framework posts to the bot, reduced to what the channel reads. */
|
|
37
|
+
export type TeamsActivity = z.infer<typeof ActivitySchema>;
|
|
38
|
+
/** An attachment of an activity. */
|
|
39
|
+
export type TeamsAttachment = z.infer<typeof AttachmentSchema>;
|
|
40
|
+
/** The kind of a Teams conversation: a personal chat, a group chat or a thread of a team channel. */
|
|
41
|
+
export type TeamsConversationType = 'personal' | 'groupChat' | 'channel';
|
|
42
|
+
/** Reads an activity, or throws when the JSON is not one. */
|
|
43
|
+
export declare function parseActivity(json: unknown): TeamsActivity;
|
|
44
|
+
/**
|
|
45
|
+
* A conversation id split into the conversation and the thread inside it: a channel thread is
|
|
46
|
+
* `<channel id>;messageid=<root message id>`, other conversations have no thread.
|
|
47
|
+
*/
|
|
48
|
+
export declare function splitConversation(id: string): {
|
|
49
|
+
channelId: string;
|
|
50
|
+
topicId?: string;
|
|
51
|
+
};
|
|
52
|
+
/** The conversation id of a chat and the thread inside it, as {@link splitConversation} reads it. */
|
|
53
|
+
export declare function joinConversation(channelId: string, topicId?: string): string;
|
|
54
|
+
/** The kind of a conversation: as the activity says, or guessed from the shape of its id. */
|
|
55
|
+
export declare function conversationTypeOf(id: string, declared?: string): TeamsConversationType;
|
|
56
|
+
/**
|
|
57
|
+
* The tenant an activity comes from, or `undefined` when it names none, or two that differ in
|
|
58
|
+
* `channelData.tenant.id` and `conversation.tenantId`, which no activity of Teams does.
|
|
59
|
+
*/
|
|
60
|
+
export declare function tenantOf(activity: TeamsActivity): string | undefined;
|
|
61
|
+
/** Whether an activity names two tenants that differ. */
|
|
62
|
+
export declare function tenantsDisagree(activity: TeamsActivity): boolean;
|
|
63
|
+
/** The team a channel activity comes from. */
|
|
64
|
+
export declare function teamOf(activity: TeamsActivity): string | undefined;
|
|
65
|
+
/** Whether the activity mentions the bot. */
|
|
66
|
+
export declare function mentionsBot(activity: TeamsActivity): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* The text of a message without the bot's mentions (`<at>Bot</at>`), trimmed. Mentions of other
|
|
69
|
+
* people stay. Linear in the length of the text.
|
|
70
|
+
*/
|
|
71
|
+
export declare function textWithoutMention(activity: TeamsActivity): string;
|
|
72
|
+
/** The attachments of an activity that can be read. */
|
|
73
|
+
export declare function attachmentsOf(activity: TeamsActivity): TeamsAttachment[];
|
|
74
|
+
/** A file a user sent in a personal chat, with a download URL that needs no token. */
|
|
75
|
+
export declare const FILE_DOWNLOAD_INFO = "application/vnd.microsoft.teams.file.download.info";
|
|
76
|
+
declare const DownloadInfoSchema: z.ZodObject<{
|
|
77
|
+
downloadUrl: z.ZodString;
|
|
78
|
+
fileType: z.ZodOptional<z.ZodString>;
|
|
79
|
+
}, z.core.$strip>;
|
|
80
|
+
/** The download URL and file type of a {@link FILE_DOWNLOAD_INFO} attachment. */
|
|
81
|
+
export declare function downloadInfoOf(attachment: TeamsAttachment): z.infer<typeof DownloadInfoSchema> | undefined;
|
|
82
|
+
/** What kind of attachment a MIME type is, so images reach vision and audio speech to text. */
|
|
83
|
+
export declare function attachmentTypeOf(mimeType: string): 'image' | 'audio' | 'video' | 'file';
|
|
84
|
+
/** The MIME type of a file type (an extension, as Teams names it). */
|
|
85
|
+
export declare function mimeTypeOf(fileType: string | undefined): string;
|
|
86
|
+
declare const FileConsentSchema: z.ZodObject<{
|
|
87
|
+
type: z.ZodOptional<z.ZodLiteral<"fileUpload">>;
|
|
88
|
+
action: z.ZodEnum<{
|
|
89
|
+
accept: "accept";
|
|
90
|
+
decline: "decline";
|
|
91
|
+
}>;
|
|
92
|
+
context: z.ZodOptional<z.ZodObject<{
|
|
93
|
+
uploadId: z.ZodString;
|
|
94
|
+
}, z.core.$strip>>;
|
|
95
|
+
uploadInfo: z.ZodOptional<z.ZodObject<{
|
|
96
|
+
name: z.ZodString;
|
|
97
|
+
uploadUrl: z.ZodString;
|
|
98
|
+
contentUrl: z.ZodString;
|
|
99
|
+
uniqueId: z.ZodString;
|
|
100
|
+
fileType: z.ZodOptional<z.ZodString>;
|
|
101
|
+
}, z.core.$strip>>;
|
|
102
|
+
}, z.core.$strip>;
|
|
103
|
+
/** The answer to a file consent card: accepted with where to upload, or declined. */
|
|
104
|
+
export type FileConsentAnswer = z.infer<typeof FileConsentSchema>;
|
|
105
|
+
/** Reads the value of a `fileConsent/invoke` activity. */
|
|
106
|
+
export declare function fileConsentOf(value: unknown): FileConsentAnswer | undefined;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=activity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../../../src/channels/teams/activity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB,QAAA,MAAM,gBAAgB;;;;;iBAKpB,CAAC;AAEH,QAAA,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAelB,CAAC;AAEH,qFAAqF;AACrF,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAE3D,oCAAoC;AACpC,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE/D,qGAAqG;AACrG,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,CAAC;AAEzE,6DAA6D;AAC7D,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,aAAa,CAE1D;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAKrF;AAED,qGAAqG;AACrG,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAG5E;AAED,6FAA6F;AAC7F,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAMvF;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAIpE;AAED,yDAAyD;AACzD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAOhE;AAED,8CAA8C;AAC9C,wBAAgB,MAAM,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,GAAG,SAAS,CAGlE;AAgBD,6CAA6C;AAC7C,wBAAgB,WAAW,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAE5D;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAMlE;AAED,uDAAuD;AACvD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,aAAa,GAAG,eAAe,EAAE,CAOxE;AAED,sFAAsF;AACtF,eAAO,MAAM,kBAAkB,uDAAuD,CAAC;AAEvF,QAAA,MAAM,kBAAkB;;;iBAGtB,CAAC;AAEH,iFAAiF;AACjF,wBAAgB,cAAc,CAC5B,UAAU,EAAE,eAAe,GAC1B,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,GAAG,SAAS,CAIhD;AA2BD,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAKvF;AAED,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE/D;AAED,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;iBAarB,CAAC;AAEH,qFAAqF;AACrF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAElE,0DAA0D;AAC1D,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,iBAAiB,GAAG,SAAS,CAG3E"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const AccountSchema = z.object({
|
|
3
|
+
id: z.string(),
|
|
4
|
+
name: z.string().optional(),
|
|
5
|
+
aadObjectId: z.string().optional(),
|
|
6
|
+
});
|
|
7
|
+
const ConversationSchema = z.object({
|
|
8
|
+
id: z.string().min(1),
|
|
9
|
+
conversationType: z.string().optional(),
|
|
10
|
+
tenantId: z.string().optional(),
|
|
11
|
+
});
|
|
12
|
+
const ChannelDataSchema = z.object({
|
|
13
|
+
tenant: z.object({ id: z.string() }).optional(),
|
|
14
|
+
team: z.object({ id: z.string() }).optional(),
|
|
15
|
+
});
|
|
16
|
+
const MentionSchema = z.object({
|
|
17
|
+
type: z.literal('mention'),
|
|
18
|
+
text: z.string().optional(),
|
|
19
|
+
mentioned: z.object({ id: z.string() }),
|
|
20
|
+
});
|
|
21
|
+
const AttachmentSchema = z.object({
|
|
22
|
+
contentType: z.string(),
|
|
23
|
+
contentUrl: z.string().optional(),
|
|
24
|
+
name: z.string().optional(),
|
|
25
|
+
content: z.unknown().optional(),
|
|
26
|
+
});
|
|
27
|
+
const ActivitySchema = z.object({
|
|
28
|
+
type: z.string(),
|
|
29
|
+
id: z.string().optional(),
|
|
30
|
+
name: z.string().optional(),
|
|
31
|
+
channelId: z.string(),
|
|
32
|
+
serviceUrl: z.string().min(1),
|
|
33
|
+
from: AccountSchema,
|
|
34
|
+
recipient: AccountSchema.optional(),
|
|
35
|
+
conversation: ConversationSchema,
|
|
36
|
+
text: z.string().optional(),
|
|
37
|
+
replyToId: z.string().optional(),
|
|
38
|
+
value: z.unknown().optional(),
|
|
39
|
+
entities: z.array(z.unknown()).optional(),
|
|
40
|
+
attachments: z.array(z.unknown()).optional(),
|
|
41
|
+
channelData: z.unknown().optional(),
|
|
42
|
+
});
|
|
43
|
+
/** Reads an activity, or throws when the JSON is not one. */
|
|
44
|
+
export function parseActivity(json) {
|
|
45
|
+
return ActivitySchema.parse(json);
|
|
46
|
+
}
|
|
47
|
+
const THREAD_MARKER = ';messageid=';
|
|
48
|
+
/**
|
|
49
|
+
* A conversation id split into the conversation and the thread inside it: a channel thread is
|
|
50
|
+
* `<channel id>;messageid=<root message id>`, other conversations have no thread.
|
|
51
|
+
*/
|
|
52
|
+
export function splitConversation(id) {
|
|
53
|
+
const at = id.indexOf(THREAD_MARKER);
|
|
54
|
+
if (at < 0)
|
|
55
|
+
return { channelId: id };
|
|
56
|
+
const topicId = id.slice(at + THREAD_MARKER.length);
|
|
57
|
+
return { channelId: id.slice(0, at), ...(topicId && { topicId }) };
|
|
58
|
+
}
|
|
59
|
+
/** The conversation id of a chat and the thread inside it, as {@link splitConversation} reads it. */
|
|
60
|
+
export function joinConversation(channelId, topicId) {
|
|
61
|
+
if (!topicId || channelId.includes(THREAD_MARKER))
|
|
62
|
+
return channelId;
|
|
63
|
+
return `${channelId}${THREAD_MARKER}${topicId}`;
|
|
64
|
+
}
|
|
65
|
+
/** The kind of a conversation: as the activity says, or guessed from the shape of its id. */
|
|
66
|
+
export function conversationTypeOf(id, declared) {
|
|
67
|
+
if (declared === 'personal' || declared === 'groupChat' || declared === 'channel') {
|
|
68
|
+
return declared;
|
|
69
|
+
}
|
|
70
|
+
if (id.startsWith('a:'))
|
|
71
|
+
return 'personal';
|
|
72
|
+
return id.includes('@thread.tacv2') || id.includes('@thread.skype') ? 'channel' : 'groupChat';
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The tenant an activity comes from, or `undefined` when it names none, or two that differ in
|
|
76
|
+
* `channelData.tenant.id` and `conversation.tenantId`, which no activity of Teams does.
|
|
77
|
+
*/
|
|
78
|
+
export function tenantOf(activity) {
|
|
79
|
+
if (tenantsDisagree(activity))
|
|
80
|
+
return undefined;
|
|
81
|
+
const data = ChannelDataSchema.safeParse(activity.channelData);
|
|
82
|
+
return (data.success ? data.data.tenant?.id : undefined) ?? activity.conversation.tenantId;
|
|
83
|
+
}
|
|
84
|
+
/** Whether an activity names two tenants that differ. */
|
|
85
|
+
export function tenantsDisagree(activity) {
|
|
86
|
+
const data = ChannelDataSchema.safeParse(activity.channelData);
|
|
87
|
+
const fromData = data.success ? data.data.tenant?.id : undefined;
|
|
88
|
+
const fromConversation = activity.conversation.tenantId;
|
|
89
|
+
return (!!fromData && !!fromConversation && fromData.toLowerCase() !== fromConversation.toLowerCase());
|
|
90
|
+
}
|
|
91
|
+
/** The team a channel activity comes from. */
|
|
92
|
+
export function teamOf(activity) {
|
|
93
|
+
const data = ChannelDataSchema.safeParse(activity.channelData);
|
|
94
|
+
return data.success ? data.data.team?.id : undefined;
|
|
95
|
+
}
|
|
96
|
+
/** The mentions of the bot in an activity: its `mention` entities that name the recipient. */
|
|
97
|
+
function botMentions(activity) {
|
|
98
|
+
const botId = activity.recipient?.id;
|
|
99
|
+
if (!botId)
|
|
100
|
+
return [];
|
|
101
|
+
const texts = [];
|
|
102
|
+
for (const entity of activity.entities ?? []) {
|
|
103
|
+
const mention = MentionSchema.safeParse(entity);
|
|
104
|
+
if (mention.success && mention.data.mentioned.id === botId) {
|
|
105
|
+
texts.push(mention.data.text ?? '');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return texts;
|
|
109
|
+
}
|
|
110
|
+
/** Whether the activity mentions the bot. */
|
|
111
|
+
export function mentionsBot(activity) {
|
|
112
|
+
return botMentions(activity).length > 0;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The text of a message without the bot's mentions (`<at>Bot</at>`), trimmed. Mentions of other
|
|
116
|
+
* people stay. Linear in the length of the text.
|
|
117
|
+
*/
|
|
118
|
+
export function textWithoutMention(activity) {
|
|
119
|
+
let text = activity.text ?? '';
|
|
120
|
+
for (const mention of botMentions(activity)) {
|
|
121
|
+
if (mention)
|
|
122
|
+
text = text.split(mention).join('');
|
|
123
|
+
}
|
|
124
|
+
return text.trim();
|
|
125
|
+
}
|
|
126
|
+
/** The attachments of an activity that can be read. */
|
|
127
|
+
export function attachmentsOf(activity) {
|
|
128
|
+
const attachments = [];
|
|
129
|
+
for (const entry of activity.attachments ?? []) {
|
|
130
|
+
const parsed = AttachmentSchema.safeParse(entry);
|
|
131
|
+
if (parsed.success)
|
|
132
|
+
attachments.push(parsed.data);
|
|
133
|
+
}
|
|
134
|
+
return attachments;
|
|
135
|
+
}
|
|
136
|
+
/** A file a user sent in a personal chat, with a download URL that needs no token. */
|
|
137
|
+
export const FILE_DOWNLOAD_INFO = 'application/vnd.microsoft.teams.file.download.info';
|
|
138
|
+
const DownloadInfoSchema = z.object({
|
|
139
|
+
downloadUrl: z.string(),
|
|
140
|
+
fileType: z.string().optional(),
|
|
141
|
+
});
|
|
142
|
+
/** The download URL and file type of a {@link FILE_DOWNLOAD_INFO} attachment. */
|
|
143
|
+
export function downloadInfoOf(attachment) {
|
|
144
|
+
if (attachment.contentType !== FILE_DOWNLOAD_INFO)
|
|
145
|
+
return undefined;
|
|
146
|
+
const parsed = DownloadInfoSchema.safeParse(attachment.content);
|
|
147
|
+
return parsed.success ? parsed.data : undefined;
|
|
148
|
+
}
|
|
149
|
+
const MIME_TYPES = {
|
|
150
|
+
png: 'image/png',
|
|
151
|
+
jpg: 'image/jpeg',
|
|
152
|
+
jpeg: 'image/jpeg',
|
|
153
|
+
gif: 'image/gif',
|
|
154
|
+
webp: 'image/webp',
|
|
155
|
+
pdf: 'application/pdf',
|
|
156
|
+
txt: 'text/plain',
|
|
157
|
+
md: 'text/markdown',
|
|
158
|
+
csv: 'text/csv',
|
|
159
|
+
json: 'application/json',
|
|
160
|
+
mp3: 'audio/mpeg',
|
|
161
|
+
m4a: 'audio/mp4',
|
|
162
|
+
wav: 'audio/wav',
|
|
163
|
+
ogg: 'audio/ogg',
|
|
164
|
+
mp4: 'video/mp4',
|
|
165
|
+
mov: 'video/quicktime',
|
|
166
|
+
webm: 'video/webm',
|
|
167
|
+
aac: 'audio/aac',
|
|
168
|
+
flac: 'audio/flac',
|
|
169
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
170
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
171
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
172
|
+
};
|
|
173
|
+
/** What kind of attachment a MIME type is, so images reach vision and audio speech to text. */
|
|
174
|
+
export function attachmentTypeOf(mimeType) {
|
|
175
|
+
if (mimeType.startsWith('image/'))
|
|
176
|
+
return 'image';
|
|
177
|
+
if (mimeType.startsWith('audio/'))
|
|
178
|
+
return 'audio';
|
|
179
|
+
if (mimeType.startsWith('video/'))
|
|
180
|
+
return 'video';
|
|
181
|
+
return 'file';
|
|
182
|
+
}
|
|
183
|
+
/** The MIME type of a file type (an extension, as Teams names it). */
|
|
184
|
+
export function mimeTypeOf(fileType) {
|
|
185
|
+
return MIME_TYPES[fileType?.toLowerCase() ?? ''] ?? 'application/octet-stream';
|
|
186
|
+
}
|
|
187
|
+
const FileConsentSchema = z.object({
|
|
188
|
+
type: z.literal('fileUpload').optional(),
|
|
189
|
+
action: z.enum(['accept', 'decline']),
|
|
190
|
+
context: z.object({ uploadId: z.string() }).optional(),
|
|
191
|
+
uploadInfo: z
|
|
192
|
+
.object({
|
|
193
|
+
name: z.string(),
|
|
194
|
+
uploadUrl: z.string(),
|
|
195
|
+
contentUrl: z.string(),
|
|
196
|
+
uniqueId: z.string(),
|
|
197
|
+
fileType: z.string().optional(),
|
|
198
|
+
})
|
|
199
|
+
.optional(),
|
|
200
|
+
});
|
|
201
|
+
/** Reads the value of a `fileConsent/invoke` activity. */
|
|
202
|
+
export function fileConsentOf(value) {
|
|
203
|
+
const parsed = FileConsentSchema.safeParse(value);
|
|
204
|
+
return parsed.success ? parsed.data : undefined;
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=activity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity.js","sourceRoot":"","sources":["../../../src/channels/teams/activity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/** Where Bot Framework publishes the OpenID metadata of the tokens it signs requests with. */
|
|
2
|
+
export declare const BOT_FRAMEWORK_OPENID_METADATA = "https://login.botframework.com/v1/.well-known/openidconfiguration";
|
|
3
|
+
/** The issuer of the tokens Bot Framework sends with every activity. */
|
|
4
|
+
export declare const BOT_FRAMEWORK_ISSUER = "https://api.botframework.com";
|
|
5
|
+
/** Why a request was refused: `401` for a token that does not prove Bot Framework sent it, `403` for one it may not use. */
|
|
6
|
+
export declare class TeamsAuthError extends Error {
|
|
7
|
+
readonly status: 401 | 403 | 503;
|
|
8
|
+
constructor(status: 401 | 403 | 503, message: string, options?: {
|
|
9
|
+
cause?: unknown;
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
/** A token Bot Framework signed: the service URL it was issued for and the channels its key may sign for. */
|
|
13
|
+
export interface VerifiedTeamsToken {
|
|
14
|
+
/** The `serviceurl` claim: the only Bot Connector the activity may be answered through */
|
|
15
|
+
serviceUrl?: string;
|
|
16
|
+
/** The channels the signing key is endorsed for, such as `msteams` */
|
|
17
|
+
endorsements: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
export interface TeamsTokenVerifierOptions {
|
|
20
|
+
/** The bot's Microsoft App ID, the audience every token must name */
|
|
21
|
+
appId: string;
|
|
22
|
+
/** The OpenID metadata URL (default {@link BOT_FRAMEWORK_OPENID_METADATA}) */
|
|
23
|
+
metadataUrl?: string;
|
|
24
|
+
fetch?: typeof fetch;
|
|
25
|
+
/** The current time in ms, for tests */
|
|
26
|
+
now?: () => number;
|
|
27
|
+
/** How long loading the metadata or the keys may take, in ms (default 10 000) */
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Checks the JWT Bot Framework sends with every activity, with no dependency but `node:crypto`:
|
|
32
|
+
* RS256 only, signed by a key of the published JWKS, issued by {@link BOT_FRAMEWORK_ISSUER} for
|
|
33
|
+
* the bot's App ID, and valid now within five minutes of clock skew. The keys are cached and
|
|
34
|
+
* loaded again once a day, and a token signed by a key not seen yet loads them again at most
|
|
35
|
+
* every five minutes, so a rotated key is picked up and a flood of forged ones costs nothing.
|
|
36
|
+
*/
|
|
37
|
+
export declare class TeamsTokenVerifier {
|
|
38
|
+
private readonly options;
|
|
39
|
+
private readonly metadataUrl;
|
|
40
|
+
private readonly fetchImpl;
|
|
41
|
+
private readonly now;
|
|
42
|
+
private readonly timeout;
|
|
43
|
+
private keys;
|
|
44
|
+
private loadedAt;
|
|
45
|
+
private lastUnknownRefresh;
|
|
46
|
+
private lastFailure;
|
|
47
|
+
private loading?;
|
|
48
|
+
constructor(options: TeamsTokenVerifierOptions);
|
|
49
|
+
/** Checks a token, resolving with what it proves, or throws a {@link TeamsAuthError}. */
|
|
50
|
+
verify(token: string): Promise<VerifiedTeamsToken>;
|
|
51
|
+
/**
|
|
52
|
+
* The signing key of `kid`. Cached keys are used at once, and once they are a day old they are
|
|
53
|
+
* loaded again in the background. Only a cache that is still empty waits for the keys. A key
|
|
54
|
+
* the cache lacks loads them again, at most every five minutes.
|
|
55
|
+
*/
|
|
56
|
+
private keyFor;
|
|
57
|
+
/**
|
|
58
|
+
* Loads the keys once for every caller waiting. After a failure no load is tried for ten
|
|
59
|
+
* seconds, however many requests come, and the keys loaded before stay in use.
|
|
60
|
+
*/
|
|
61
|
+
private refresh;
|
|
62
|
+
private load;
|
|
63
|
+
private json;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../../src/channels/teams/auth.ts"],"names":[],"mappings":"AAGA,8FAA8F;AAC9F,eAAO,MAAM,6BAA6B,sEAC2B,CAAC;AACtE,wEAAwE;AACxE,eAAO,MAAM,oBAAoB,iCAAiC,CAAC;AAgBnE,4HAA4H;AAC5H,qBAAa,cAAe,SAAQ,KAAK;IAErC,QAAQ,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG;gBAAvB,MAAM,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAChC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE;CAKhC;AA6BD,6GAA6G;AAC7G,MAAM,WAAW,kBAAkB;IACjC,0FAA0F;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sEAAsE;IACtE,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,yBAAyB;IACxC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,wCAAwC;IACxC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAWD;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAWjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAVpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAgB;gBAEH,OAAO,EAAE,yBAAyB;IAO/D,yFAAyF;IACnF,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgDxD;;;;OAIG;YACW,MAAM;IAYpB;;;OAGG;IACH,OAAO,CAAC,OAAO;YAuBD,IAAI;YA4BJ,IAAI;CAQnB"}
|