Skip to content

Commit 8e1b983

Browse files
committed
new components
1 parent c37db1c commit 8e1b983

File tree

8 files changed

+255
-56
lines changed

8 files changed

+255
-56
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import microsoftOutlook from "../../microsoft_outlook.app.mjs";
2+
import fs from "fs";
3+
import mime from "mime-types";
4+
5+
export default {
6+
key: "microsoft_outlook-download-attachment",
7+
name: "Download Attachment",
8+
description: "Downloads an attachment to the /tmp directory. [See the documentation](https://learn.microsoft.com/en-us/graph/api/attachment-get?view=graph-rest-1.0&tabs=http)",
9+
version: "0.0.1",
10+
type: "action",
11+
props: {
12+
microsoftOutlook,
13+
messageId: {
14+
propDefinition: [
15+
microsoftOutlook,
16+
"messageId",
17+
],
18+
description: "The identifier of the message containing the attachment to download",
19+
},
20+
attachmentId: {
21+
propDefinition: [
22+
microsoftOutlook,
23+
"attachmentId",
24+
(c) => ({
25+
messageId: c.messageId,
26+
}),
27+
],
28+
},
29+
filename: {
30+
type: "string",
31+
label: "Filename",
32+
description: "The filename to save the attachment as in the /tmp directory",
33+
},
34+
},
35+
async run({ $ }) {
36+
const response = await this.microsoftOutlook.getAttachment({
37+
$,
38+
messageId: this.messageId,
39+
attachmentId: this.attachmentId,
40+
responseType: "arraybuffer",
41+
});
42+
43+
const rawcontent = response.toString("base64");
44+
const buffer = Buffer.from(rawcontent, "base64");
45+
const downloadedFilepath = `/tmp/${this.filename}`;
46+
fs.writeFileSync(downloadedFilepath, buffer);
47+
const contentType = mime.lookup(downloadedFilepath);
48+
49+
return {
50+
fileName: this.filename,
51+
contentType,
52+
filePath: downloadedFilepath,
53+
};
54+
},
55+
};

components/microsoft_outlook/microsoft_outlook.app.mjs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,29 @@ export default {
170170
})) || [];
171171
},
172172
},
173+
attachmentId: {
174+
type: "string",
175+
label: "Attachment ID",
176+
description: "The identifier of the attachment to download",
177+
async options({
178+
messageId, page,
179+
}) {
180+
const limit = DEFAULT_LIMIT;
181+
const { value: attachments } = await this.listAttachments({
182+
messageId,
183+
params: {
184+
$top: limit,
185+
$skip: limit * page,
186+
},
187+
});
188+
return attachments?.map(({
189+
id: value, name: label,
190+
}) => ({
191+
value,
192+
label,
193+
})) || [];
194+
},
195+
},
173196
maxResults: {
174197
type: "integer",
175198
label: "Max Results",
@@ -403,6 +426,22 @@ export default {
403426
...args,
404427
});
405428
},
429+
getAttachment({
430+
messageId, attachmentId, ...args
431+
}) {
432+
return this._makeRequest({
433+
path: `/me/messages/${messageId}/attachments/${attachmentId}/$value`,
434+
...args,
435+
});
436+
},
437+
listAttachments({
438+
messageId, ...args
439+
}) {
440+
return this._makeRequest({
441+
path: `/me/messages/${messageId}/attachments`,
442+
...args,
443+
});
444+
},
406445
async *paginate({
407446
fn, args = {}, max,
408447
}) {

components/microsoft_outlook/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@pipedream/microsoft_outlook",
3-
"version": "1.4.1",
3+
"version": "1.5.0",
44
"description": "Pipedream Microsoft Outlook Components",
55
"main": "microsoft_outlook.app.mjs",
66
"keywords": [
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import common from "./common.mjs";
2+
3+
export default {
4+
...common,
5+
props: {
6+
...common.props,
7+
folderIds: {
8+
propDefinition: [
9+
common.props.microsoftOutlook,
10+
"folderIds",
11+
],
12+
optional: true,
13+
},
14+
},
15+
hooks: {
16+
...common.hooks,
17+
async deploy() {
18+
this.db.set("sentItemFolderId", await this.getFolderIdByName("Sent Items"));
19+
this.db.set("draftsFolderId", await this.getFolderIdByName("Drafts"));
20+
21+
const events = await this.getSampleEvents({
22+
pageSize: 25,
23+
});
24+
if (!events || events.length == 0) {
25+
return;
26+
}
27+
for (const item of events) {
28+
this.emitEvent(item);
29+
}
30+
},
31+
async activate() {
32+
await this.activate({
33+
changeType: "created",
34+
resource: "/me/messages",
35+
});
36+
},
37+
async deactivate() {
38+
await this.deactivate();
39+
},
40+
},
41+
methods: {
42+
...common.methods,
43+
async getFolderIdByName(name) {
44+
const { value: folders } = await this.microsoftOutlook.listFolders();
45+
const folder = folders.find(({ displayName }) => displayName === name);
46+
return folder?.id;
47+
},
48+
isRelevant(item) {
49+
if (this.folderIds?.length) {
50+
return this.folderIds.includes(item.parentFolderId);
51+
}
52+
// if no folderIds are specified, filter out items in Sent Items & Drafts
53+
const sentItemFolderId = this.db.get("sentItemFolderId");
54+
const draftsFolderId = this.db.get("draftsFolderId");
55+
return item.parentFolderId !== sentItemFolderId && item.parentFolderId !== draftsFolderId;
56+
},
57+
},
58+
};

components/microsoft_outlook/sources/common.mjs renamed to components/microsoft_outlook/sources/common/common.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import microsoftOutlook from "../microsoft_outlook.app.mjs";
1+
import microsoftOutlook from "../../microsoft_outlook.app.mjs";
22

33
const getRenewalInterval = (period) => {
44
let day = 24 * 60 * 60;
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import common from "../common/common-new-email.mjs";
2+
import md5 from "md5";
3+
4+
export default {
5+
...common,
6+
key: "microsoft_outlook-new-attachment-received",
7+
name: "New Attachment Received (Instant)",
8+
description: "Emit new event when a new email containing one or more attachments arrives in a specified Microsoft Outlook folder.",
9+
version: "0.0.1",
10+
type: "source",
11+
dedupe: "unique",
12+
methods: {
13+
...common.methods,
14+
async getSampleEvents({ pageSize }) {
15+
const folders = this.folderIds?.length
16+
? this.folderIds.map((id) => `/me/mailFolders/${id}/messages`)
17+
: [
18+
"/me/messages",
19+
];
20+
21+
const messagesWithAttachments = [];
22+
for (const folder of folders) {
23+
const { value: messages } = await this.microsoftOutlook.listMessages({
24+
resource: folder,
25+
params: {
26+
$top: pageSize,
27+
$filter: "hasAttachments eq true",
28+
},
29+
});
30+
messagesWithAttachments.push(...messages);
31+
}
32+
33+
const attachments = [];
34+
for (const message of messagesWithAttachments) {
35+
const messageAttachments = await this.getMessageAttachments(message);
36+
attachments.push(...messageAttachments);
37+
}
38+
return attachments;
39+
},
40+
async getMessageAttachments(message) {
41+
const { value: attachments } = await this.microsoftOutlook.listAttachments({
42+
messageId: message.id,
43+
});
44+
if (!attachments?.length) {
45+
return [];
46+
}
47+
return attachments.map((attachment) => ({
48+
...attachment,
49+
messageId: message.id,
50+
messageSubject: message.subject,
51+
messageSender: message.sender,
52+
messageReceivedDateTime: message.receivedDateTime,
53+
parentFolderId: message.parentFolderId,
54+
contentBytes: undefined,
55+
}));
56+
},
57+
emitEvent(item) {
58+
if (this.isRelevant(item)) {
59+
this.$emit(item, this.generateMeta(item));
60+
}
61+
},
62+
generateMeta(item) {
63+
return {
64+
id: md5(item.id), // id > 64 characters, so dedupe on hash of id
65+
summary: `New attachment ${item.name}`,
66+
ts: Date.parse(item.messageReceivedDateTime),
67+
};
68+
},
69+
},
70+
async run(event) {
71+
const folders = this.folderIds?.length
72+
? this.folderIds.map((id) => `/me/mailFolders/${id}/messages`)
73+
: [
74+
"/me/messages",
75+
];
76+
77+
for (const folder of folders) {
78+
await this.run({
79+
event,
80+
emitFn: async ({ resourceId } = {}) => {
81+
try {
82+
const message = await this.microsoftOutlook.getMessage({
83+
resource: folder,
84+
messageId: resourceId,
85+
});
86+
if (message.hasAttachments) {
87+
const attachments = await this.getMessageAttachments(message);
88+
attachments.forEach((item) => this.emitEvent(item));
89+
}
90+
} catch {
91+
console.log(`Could not fetch message with ID: ${resourceId}`);
92+
}
93+
},
94+
});
95+
}
96+
},
97+
};

components/microsoft_outlook/sources/new-contact/new-contact.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import common from "../common.mjs";
1+
import common from "../common/common.mjs";
22

33
export default {
44
...common,
55
key: "microsoft_outlook-new-contact",
66
name: "New Contact Event (Instant)",
77
description: "Emit new event when a new Contact is created",
8-
version: "0.0.13",
8+
version: "0.0.14",
99
type: "source",
1010
hooks: {
1111
...common.hooks,

components/microsoft_outlook/sources/new-email/new-email.mjs

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import common from "../common.mjs";
1+
import common from "../common/common-new-email.mjs";
22
import md5 from "md5";
33
import sampleEmit from "./test-event.mjs";
44

@@ -7,52 +7,11 @@ export default {
77
key: "microsoft_outlook-new-email",
88
name: "New Email Event (Instant)",
99
description: "Emit new event when an email is received in specified folders.",
10-
version: "0.0.16",
10+
version: "0.0.17",
1111
type: "source",
1212
dedupe: "unique",
13-
props: {
14-
...common.props,
15-
folderIds: {
16-
propDefinition: [
17-
common.props.microsoftOutlook,
18-
"folderIds",
19-
],
20-
optional: true,
21-
},
22-
},
23-
hooks: {
24-
...common.hooks,
25-
async deploy() {
26-
this.db.set("sentItemFolderId", await this.getFolderIdByName("Sent Items"));
27-
this.db.set("draftsFolderId", await this.getFolderIdByName("Drafts"));
28-
29-
const events = await this.getSampleEvents({
30-
pageSize: 25,
31-
});
32-
if (!events || events.length == 0) {
33-
return;
34-
}
35-
for (const item of events) {
36-
this.emitEvent(item);
37-
}
38-
},
39-
async activate() {
40-
await this.activate({
41-
changeType: "created",
42-
resource: "/me/messages",
43-
});
44-
},
45-
async deactivate() {
46-
await this.deactivate();
47-
},
48-
},
4913
methods: {
5014
...common.methods,
51-
async getFolderIdByName(name) {
52-
const { value: folders } = await this.microsoftOutlook.listFolders();
53-
const folder = folders.find(({ displayName }) => displayName === name);
54-
return folder?.id;
55-
},
5615
async getSampleEvents({ pageSize }) {
5716
const folders = this.folderIds?.length
5817
? this.folderIds.map((id) => `/me/mailFolders/${id}/messages`)
@@ -73,15 +32,6 @@ export default {
7332
}
7433
return results;
7534
},
76-
isRelevant(item) {
77-
if (this.folderIds?.length) {
78-
return this.folderIds.includes(item.parentFolderId);
79-
}
80-
// if no folderIds are specified, filter out items in Sent Items & Drafts
81-
const sentItemFolderId = this.db.get("sentItemFolderId");
82-
const draftsFolderId = this.db.get("draftsFolderId");
83-
return item.parentFolderId !== sentItemFolderId && item.parentFolderId !== draftsFolderId;
84-
},
8535
emitEvent(item) {
8636
if (this.isRelevant(item)) {
8737
this.$emit(

0 commit comments

Comments
 (0)