@things-factory/integration-msgraph 10.1.255 → 10.1.257
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-server/engine/task/index.d.ts +1 -0
- package/dist-server/engine/task/index.js +1 -0
- package/dist-server/engine/task/index.js.map +1 -1
- package/dist-server/engine/task/msgraph-mailbox-messages.d.ts +17 -0
- package/dist-server/engine/task/msgraph-mailbox-messages.js +77 -0
- package/dist-server/engine/task/msgraph-mailbox-messages.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -1
- package/helps/integration/task/msgraph-mailbox-messages.md +20 -0
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/task/index.ts"],"names":[],"mappings":";;AAAA,yBAAsB;AACtB,0BAAuB;AACvB,yCAAsC","sourcesContent":["import './msgraph-get'\nimport './msgraph-post'\nimport './msgraph-license-assignments'\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/engine/task/index.ts"],"names":[],"mappings":";;AAAA,yBAAsB;AACtB,0BAAuB;AACvB,yCAAsC;AACtC,sCAAmC","sourcesContent":["import './msgraph-get'\nimport './msgraph-post'\nimport './msgraph-license-assignments'\nimport './msgraph-mailbox-messages'\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface MailboxMessage {
|
|
2
|
+
id: string;
|
|
3
|
+
conversationId: string | null;
|
|
4
|
+
subject: string;
|
|
5
|
+
from: string | null;
|
|
6
|
+
fromName: string | null;
|
|
7
|
+
to: string[];
|
|
8
|
+
cc: string[];
|
|
9
|
+
sentAt: string | null;
|
|
10
|
+
receivedAt: string | null;
|
|
11
|
+
body: string;
|
|
12
|
+
internal: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** What a Graph message says, as the keeper of work mail reads it. */
|
|
15
|
+
export declare function messageOf(raw: any): MailboxMessage;
|
|
16
|
+
/** Every message of the mailbox received after `since`, oldest first, each page Graph gives. */
|
|
17
|
+
export declare function readMailboxMessages(client: any, mailbox: string, since: string | null, limit?: number): Promise<MailboxMessage[]>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.messageOf = messageOf;
|
|
4
|
+
exports.readMailboxMessages = readMailboxMessages;
|
|
5
|
+
const integration_base_1 = require("@things-factory/integration-base");
|
|
6
|
+
const address = (one) => String(one?.emailAddress?.address ?? '').toLowerCase() || null;
|
|
7
|
+
/** What a Graph message says, as the keeper of work mail reads it. */
|
|
8
|
+
function messageOf(raw) {
|
|
9
|
+
const headers = raw.internetMessageHeaders ?? [];
|
|
10
|
+
const authAs = headers.find(one => one.name?.toLowerCase() === 'x-ms-exchange-organization-authas')?.value;
|
|
11
|
+
return {
|
|
12
|
+
id: raw.id,
|
|
13
|
+
conversationId: raw.conversationId ?? null,
|
|
14
|
+
subject: String(raw.subject ?? ''),
|
|
15
|
+
from: address(raw.from),
|
|
16
|
+
fromName: raw.from?.emailAddress?.name ?? null,
|
|
17
|
+
to: (raw.toRecipients ?? []).map(address).filter(Boolean),
|
|
18
|
+
cc: (raw.ccRecipients ?? []).map(address).filter(Boolean),
|
|
19
|
+
sentAt: raw.sentDateTime ?? null,
|
|
20
|
+
receivedAt: raw.receivedDateTime ?? null,
|
|
21
|
+
body: String(raw.body?.content ?? ''),
|
|
22
|
+
internal: String(authAs ?? '').toLowerCase() === 'internal'
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
const FIELDS = ['id', 'conversationId', 'subject', 'from', 'toRecipients', 'ccRecipients', 'sentDateTime', 'receivedDateTime', 'body', 'internetMessageHeaders'];
|
|
26
|
+
/** Every message of the mailbox received after `since`, oldest first, each page Graph gives. */
|
|
27
|
+
async function readMailboxMessages(client, mailbox, since, limit = 200) {
|
|
28
|
+
if (!mailbox || !/^[^@\s]+@[^@\s]+$/.test(mailbox))
|
|
29
|
+
throw new Error(`'${mailbox}' is not a mailbox address`);
|
|
30
|
+
let request = client
|
|
31
|
+
.api(`/users/${encodeURIComponent(mailbox)}/messages`)
|
|
32
|
+
.header('Prefer', 'outlook.body-content-type="text"')
|
|
33
|
+
.select(FIELDS)
|
|
34
|
+
.orderby('receivedDateTime asc')
|
|
35
|
+
.top(50);
|
|
36
|
+
if (since)
|
|
37
|
+
request = request.filter(`receivedDateTime gt ${new Date(since).toISOString()}`);
|
|
38
|
+
const out = [];
|
|
39
|
+
try {
|
|
40
|
+
let page = await request.get();
|
|
41
|
+
for (;;) {
|
|
42
|
+
for (const raw of page?.value ?? []) {
|
|
43
|
+
out.push(messageOf(raw));
|
|
44
|
+
if (out.length >= limit)
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
const next = page?.['@odata.nextLink'];
|
|
48
|
+
if (!next)
|
|
49
|
+
return out;
|
|
50
|
+
page = await client.api(next).header('Prefer', 'outlook.body-content-type="text"').get();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
const code = error?.code ? ` (${error.code})` : '';
|
|
55
|
+
throw new Error(`/users/${mailbox}/messages${code}: ${error?.message ?? error} - needs the application permission Mail.Read with admin consent, allowed for this mailbox`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function MsGraphMailboxMessages(step, context) {
|
|
59
|
+
const { connection: connectionName, params } = step;
|
|
60
|
+
const { domain, data } = context;
|
|
61
|
+
const client = await integration_base_1.ConnectionManager.getConnectionInstanceByName(domain, connectionName);
|
|
62
|
+
if (!client)
|
|
63
|
+
throw new Error(`no connection '${connectionName}'`);
|
|
64
|
+
const { mailbox, since, sinceAccessor, limit } = params || {};
|
|
65
|
+
/* The moment to read from: given, or read off an earlier step (the last mail the keeper took in). */
|
|
66
|
+
const from = since || (sinceAccessor ? String(sinceAccessor).split('.').reduce((value, key) => value?.[key], data) : null) || null;
|
|
67
|
+
return { data: await readMailboxMessages(client, mailbox, from, Number(limit) || 200) };
|
|
68
|
+
}
|
|
69
|
+
MsGraphMailboxMessages.parameterSpec = [
|
|
70
|
+
{ type: 'string', name: 'mailbox', label: 'mailbox' },
|
|
71
|
+
{ type: 'string', name: 'since', label: 'since' },
|
|
72
|
+
{ type: 'string', name: 'sinceAccessor', label: 'since-accessor' },
|
|
73
|
+
{ type: 'number', name: 'limit', label: 'limit' }
|
|
74
|
+
];
|
|
75
|
+
MsGraphMailboxMessages.help = 'integration/task/msgraph-mailbox-messages';
|
|
76
|
+
integration_base_1.TaskRegistry.registerTaskHandler('msgraph-mailbox-messages', MsGraphMailboxMessages);
|
|
77
|
+
//# sourceMappingURL=msgraph-mailbox-messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msgraph-mailbox-messages.js","sourceRoot":"","sources":["../../../server/engine/task/msgraph-mailbox-messages.ts"],"names":[],"mappings":"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","sourcesContent":["import { ConnectionManager, TaskRegistry } from '@things-factory/integration-base'\n\n/*\n * The mail that reached one mailbox since a moment - for a scenario that hands work mail to whoever keeps it (Office\n * `takeInWorkMail`, ADR-0185 decision 7). Read with the application permission Mail.Read, which the tenant narrows to\n * that one mailbox (an Exchange application access policy). Bodies come as text, attachments are not read.\n *\n * `internal` is Exchange's own word that the message was sent by someone signed in to the organisation\n * (X-MS-Exchange-Organization-AuthAs: Internal) - the From line can be written by anyone, this cannot.\n */\n\nexport interface MailboxMessage {\n id: string\n conversationId: string | null\n subject: string\n from: string | null\n fromName: string | null\n to: string[]\n cc: string[]\n sentAt: string | null\n receivedAt: string | null\n body: string\n internal: boolean\n}\n\nconst address = (one: any) => String(one?.emailAddress?.address ?? '').toLowerCase() || null\n\n/** What a Graph message says, as the keeper of work mail reads it. */\nexport function messageOf(raw: any): MailboxMessage {\n const headers: { name: string; value: string }[] = raw.internetMessageHeaders ?? []\n const authAs = headers.find(one => one.name?.toLowerCase() === 'x-ms-exchange-organization-authas')?.value\n return {\n id: raw.id,\n conversationId: raw.conversationId ?? null,\n subject: String(raw.subject ?? ''),\n from: address(raw.from),\n fromName: raw.from?.emailAddress?.name ?? null,\n to: (raw.toRecipients ?? []).map(address).filter(Boolean),\n cc: (raw.ccRecipients ?? []).map(address).filter(Boolean),\n sentAt: raw.sentDateTime ?? null,\n receivedAt: raw.receivedDateTime ?? null,\n body: String(raw.body?.content ?? ''),\n internal: String(authAs ?? '').toLowerCase() === 'internal'\n }\n}\n\nconst FIELDS = ['id', 'conversationId', 'subject', 'from', 'toRecipients', 'ccRecipients', 'sentDateTime', 'receivedDateTime', 'body', 'internetMessageHeaders']\n\n/** Every message of the mailbox received after `since`, oldest first, each page Graph gives. */\nexport async function readMailboxMessages(client: any, mailbox: string, since: string | null, limit = 200): Promise<MailboxMessage[]> {\n if (!mailbox || !/^[^@\\s]+@[^@\\s]+$/.test(mailbox)) throw new Error(`'${mailbox}' is not a mailbox address`)\n let request = client\n .api(`/users/${encodeURIComponent(mailbox)}/messages`)\n .header('Prefer', 'outlook.body-content-type=\"text\"')\n .select(FIELDS)\n .orderby('receivedDateTime asc')\n .top(50)\n if (since) request = request.filter(`receivedDateTime gt ${new Date(since).toISOString()}`)\n const out: MailboxMessage[] = []\n try {\n let page = await request.get()\n for (;;) {\n for (const raw of page?.value ?? []) {\n out.push(messageOf(raw))\n if (out.length >= limit) return out\n }\n const next = page?.['@odata.nextLink']\n if (!next) return out\n page = await client.api(next).header('Prefer', 'outlook.body-content-type=\"text\"').get()\n }\n } catch (error: any) {\n const code = error?.code ? ` (${error.code})` : ''\n throw new Error(`/users/${mailbox}/messages${code}: ${error?.message ?? error} - needs the application permission Mail.Read with admin consent, allowed for this mailbox`)\n }\n}\n\nasync function MsGraphMailboxMessages(step, context) {\n const { connection: connectionName, params } = step\n const { domain, data } = context\n const client = await ConnectionManager.getConnectionInstanceByName(domain, connectionName)\n if (!client) throw new Error(`no connection '${connectionName}'`)\n const { mailbox, since, sinceAccessor, limit } = params || {}\n /* The moment to read from: given, or read off an earlier step (the last mail the keeper took in). */\n const from = since || (sinceAccessor ? String(sinceAccessor).split('.').reduce((value: any, key: string) => value?.[key], data) : null) || null\n return { data: await readMailboxMessages(client, mailbox, from, Number(limit) || 200) }\n}\n\nMsGraphMailboxMessages.parameterSpec = [\n { type: 'string', name: 'mailbox', label: 'mailbox' },\n { type: 'string', name: 'since', label: 'since' },\n { type: 'string', name: 'sinceAccessor', label: 'since-accessor' },\n { type: 'number', name: 'limit', label: 'limit' }\n]\nMsGraphMailboxMessages.help = 'integration/task/msgraph-mailbox-messages'\n\nTaskRegistry.registerTaskHandler('msgraph-mailbox-messages', MsGraphMailboxMessages)\n"]}
|