diff --git a/components/zoom/package.json b/components/zoom/package.json index ae565990557c7..5fcbe0841e52a 100644 --- a/components/zoom/package.json +++ b/components/zoom/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/zoom", - "version": "0.3.3", + "version": "0.3.4", "description": "Pipedream Zoom Components", "main": "zoom.app.js", "keywords": [ @@ -13,5 +13,8 @@ "gitHead": "e12480b94cc03bed4808ebc6b13e7fdb3a1ba535", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^1.1.0" } } diff --git a/components/zoom/sources/common/common.mjs b/components/zoom/sources/common/common.mjs new file mode 100644 index 0000000000000..6fc9c62b567d6 --- /dev/null +++ b/components/zoom/sources/common/common.mjs @@ -0,0 +1,25 @@ +import zoom from "../../zoom.app.mjs"; + +export default { + props: { + zoom, + }, + methods: { + sortByDate(objects, field) { + return objects.sort((a, b) => (Date.parse(a[field]) > Date.parse(b[field])) + ? 1 + : -1); + }, + monthAgo() { + const now = new Date(); + const monthAgo = new Date(now.getTime()); + monthAgo.setMonth(monthAgo.getMonth() - 1); + return monthAgo.toISOString().slice(0, 10); + }, + }, + async run(event) { + const { payload } = event; + const { object } = payload; + this.emitEvent(payload, object); + }, +}; diff --git a/components/zoom/sources/custom-event/custom-event.mjs b/components/zoom/sources/custom-event/custom-event.mjs index 8c84f94ffe097..e798edcbd1593 100644 --- a/components/zoom/sources/custom-event/custom-event.mjs +++ b/components/zoom/sources/custom-event/custom-event.mjs @@ -3,9 +3,9 @@ import constants from "../common/constants.mjs"; export default { key: "zoom-custom-event", - name: "Custom Events", + name: "Custom Events (Instant)", description: "Listen for any events tied to your Zoom user or resources you own", - version: "0.0.5", + version: "0.0.6", type: "source", props: { zoom, diff --git a/components/zoom/sources/meeting-created/meeting-created.mjs b/components/zoom/sources/meeting-created/meeting-created.mjs index 95f9a6c734ef9..99ebe94c68314 100644 --- a/components/zoom/sources/meeting-created/meeting-created.mjs +++ b/components/zoom/sources/meeting-created/meeting-created.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-meeting-created", - name: "Meeting Created", - description: - "Emits an event each time a meeting is created where you're the host", - version: "0.0.3", + name: "Meeting Created (Instant)", + description: "Emit new event each time a meeting is created where you're the host", + version: "0.0.4", + type: "source", dedupe: "unique", // Dedupe based on meeting ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -18,19 +19,37 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + hooks: { + async deploy() { + const { meetings } = await this.zoom.listMeetings({ + page_size: 25, + }); + if (!meetings || meetings.length === 0) { + return; + } + const objects = this.sortByDate(meetings, "created_at"); + for (const object of objects) { + this.emitEvent({ + object, + }, object); + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ event: "meeting.created", payload, - }, - { - summary: `Meeting ${object.topic} created`, + }, meta); + }, + generateMeta(object) { + return { id: object.uuid, + summary: `Meeting ${object.topic} created`, ts: +new Date(object.start_time), - }, - ); + }; + }, }, }; diff --git a/components/zoom/sources/meeting-deleted/meeting-deleted.mjs b/components/zoom/sources/meeting-deleted/meeting-deleted.mjs index cbd4b6d97282c..4eee0af6fe9b2 100644 --- a/components/zoom/sources/meeting-deleted/meeting-deleted.mjs +++ b/components/zoom/sources/meeting-deleted/meeting-deleted.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-meeting-deleted", - name: "Meeting Deleted", - description: - "Emits an event each time a meeting is deleted where you're the host", - version: "0.0.3", + name: "Meeting Deleted (Instant)", + description: "Emit new event each time a meeting is deleted where you're the host", + version: "0.0.4", + type: "source", dedupe: "unique", // Dedupe based on meeting ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -18,19 +19,20 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + methods: { + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ event: "meeting.deleted", payload, - }, - { - summary: `Meeting ${object.topic} deleted`, + }, meta); + }, + generateMeta(object) { + return { id: object.uuid, + summary: `Meeting ${object.topic} deleted`, ts: +new Date(object.start_time), - }, - ); + }; + }, }, }; diff --git a/components/zoom/sources/meeting-ended/meeting-ended.mjs b/components/zoom/sources/meeting-ended/meeting-ended.mjs index 1b26b7710f0fd..038c958da8946 100644 --- a/components/zoom/sources/meeting-ended/meeting-ended.mjs +++ b/components/zoom/sources/meeting-ended/meeting-ended.mjs @@ -1,13 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-meeting-ended", - name: "Meeting Ended", - description: "Emits an event each time a meeting ends where you're the host", - version: "0.0.3", + name: "Meeting Ended (Instant)", + description: "Emit new event each time a meeting ends where you're the host", + version: "0.0.4", + type: "source", dedupe: "unique", // Dedupe based on meeting ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -16,13 +18,48 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit(event, { - summary: `Meeting ${object.topic} ended`, - id: object.uuid, - ts: +new Date(object.end_time), - }); + hooks: { + async deploy() { + const { meetings } = await this.zoom.listMeetings({ + page_size: 25, + type: "previous_meetings", + }); + if (!meetings || meetings.length === 0) { + return; + } + const detailedMeetings = []; + for (const meeting of meetings) { + try { + const details = await this.zoom.getPastMeetingDetails(meeting.id); + detailedMeetings.push(details); + } catch { + // catch error thrown by getPastMeetingDetails if meeting has not ended + continue; + } + } + const objects = this.sortByDate(detailedMeetings, "end_time"); + for (const object of objects) { + this.emitEvent({ + object, + }, object); + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ + event: "meeting.ended", + payload, + }, meta); + }, + generateMeta(object) { + return { + id: object.uuid, + summary: `Meeting ${object.topic} ended`, + ts: +new Date(object.end_time), + }; + }, }, }; diff --git a/components/zoom/sources/meeting-started/meeting-started.mjs b/components/zoom/sources/meeting-started/meeting-started.mjs index b8adbe38eb2be..1004bd52fdc20 100644 --- a/components/zoom/sources/meeting-started/meeting-started.mjs +++ b/components/zoom/sources/meeting-started/meeting-started.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-meeting-started", - name: "Meeting Started", - description: - "Emits an event each time a meeting starts where you're the host", - version: "0.0.3", + name: "Meeting Started (Instant)", + description: "Emit new event each time a meeting starts where you're the host", + version: "0.0.4", + type: "source", dedupe: "unique", // Dedupe based on meeting ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -17,13 +18,42 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit(event, { - summary: `Meeting ${object.topic} started`, - id: object.uuid, - ts: +new Date(object.start_time), - }); + hooks: { + async deploy() { + const { meetings } = await this.zoom.listMeetings({ + page_size: 25, + type: "previous_meetings", + }); + if (!meetings || meetings.length === 0) { + return; + } + const objects = this.sortByDate(meetings, "start_time"); + for (const object of objects) { + const startTime = Date.parse(object.start_time); + if (startTime < Date.now()) { + this.emitEvent({ + object, + time_stamp: Date.now(), + }, object); + } + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ + event: "meeting.started", + payload, + }, meta); + }, + generateMeta(object) { + return { + id: object.uuid, + summary: `Meeting ${object.topic} started`, + ts: +new Date(object.start_time), + }; + }, }, }; diff --git a/components/zoom/sources/meeting-updated/meeting-updated.mjs b/components/zoom/sources/meeting-updated/meeting-updated.mjs index e4e9e5de6dd21..70da64112835d 100644 --- a/components/zoom/sources/meeting-updated/meeting-updated.mjs +++ b/components/zoom/sources/meeting-updated/meeting-updated.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-meeting-updated", - name: "Meeting Updated", - description: - "Emits an event each time a meeting is updated where you're the host", - version: "0.0.3", + name: "Meeting Updated (Instant)", + description: "Emit new event each time a meeting is updated where you're the host", + version: "0.0.4", + type: "source", dedupe: "unique", // dedupe on the meeting ID + timestamp props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -17,12 +18,38 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit(event, { - summary: `Meeting ${object.id} updated`, - id: `${object.id}-${payload.time_stamp}`, - }); + hooks: { + async deploy() { + const { meetings } = await this.zoom.listMeetings({ + page_size: 25, + }); + if (!meetings || meetings.length === 0) { + return; + } + const objects = this.sortByDate(meetings, "created_at"); + for (const object of objects) { + this.emitEvent({ + object, + time_stamp: +new Date(object.start_time), + }, object); + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(payload, object); + this.$emit({ + event: "meeting.updated", + payload, + }, meta); + }, + generateMeta(payload, object) { + return { + id: `${object.id}-${payload.time_stamp}`, + summary: `Meeting ${object.id} updated`, + ts: +new Date(object.start_time), + }; + }, }, }; diff --git a/components/zoom/sources/phone-event/phone-event.mjs b/components/zoom/sources/phone-event/phone-event.mjs index f8e483efffc4e..6f628cf55063f 100644 --- a/components/zoom/sources/phone-event/phone-event.mjs +++ b/components/zoom/sources/phone-event/phone-event.mjs @@ -3,9 +3,9 @@ import constants from "../common/constants.mjs"; export default { key: "zoom-phone-event", - name: "Zoom Phone Events", + name: "Zoom Phone Events (Instant)", description: "Listen for any Zoom Phone events tied to your Zoom user or resources you own", - version: "0.0.1", + version: "0.0.2", type: "source", props: { zoom, diff --git a/components/zoom/sources/recording-completed/recording-completed.mjs b/components/zoom/sources/recording-completed/recording-completed.mjs index c98ff3c4eadac..b3e33b529fb94 100644 --- a/components/zoom/sources/recording-completed/recording-completed.mjs +++ b/components/zoom/sources/recording-completed/recording-completed.mjs @@ -1,15 +1,15 @@ -/* eslint-disable camelcase */ -import axios from "axios"; import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { key: "zoom-recording-completed", - name: "Recording Completed", - description: - "Emits an event each time a new recording completes for a meeting or webinar where you're the host", - version: "0.0.5", + name: "Recording Completed (Instant)", + description: "Emit new event each time a new recording completes for a meeting or webinar where you're the host", + version: "0.0.6", + type: "source", + dedupe: "unique", props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -18,50 +18,88 @@ export default { ], }, meetingIds: { - type: "integer[]", - label: "Meeting Filter", - description: "Optionally filter for events for one or more meetings.", - async options({ page }) { - const data = await this.listMeetings(page); - return data.meetings.map((meeting) => { - return { - label: `${meeting.topic} (${meeting.id})`, - value: meeting.id, - }; - }); - }, - optional: true, + propDefinition: [ + zoom, + "meetingIds", + ], }, includeAudioRecordings: { - type: "boolean", - label: "Include Audio Recordings", - description: - "This source emits video (MP4) recordings only by default. Set this prop to true to include audio recordings", - optional: true, - default: false, + propDefinition: [ + zoom, + "includeAudioRecordings", + ], }, includeChatTranscripts: { - type: "boolean", - label: "Include Chat Transcripts", - description: - "This source emits video (MP4) recordings only by default. Set this prop to `true` to include chat transcripts", - optional: true, - default: false, + propDefinition: [ + zoom, + "includeChatTranscripts", + ], + }, + }, + hooks: { + async deploy() { + const { meetings } = await this.zoom.listRecordings({ + from: this.monthAgo(), + to: new Date().toISOString() + .slice(0, 10), + page_size: 25, + }); + if (!meetings || meetings.length === 0) { + return; + } + for (const meeting of meetings) { + if (!this.isMeetingRelevant(meeting)) { + continue; + } + for (const file of meeting.recording_files) { + if (!this.isFileRelevant(file)) { + continue; + } + this.emitEvent(file, meeting); + } + } }, }, methods: { - async listMeetings({ page }) { - const config = { - method: "get", - url: "https://api.zoom.us/v2//users/me/meetings", - headers: { - Authorization: `Bearer ${this.zoom.$auth.oauth_access_token}`, + ...common.methods, + isMeetingRelevant(meeting) { + const { + id, recording_files, + } = meeting; + + if (!recording_files || recording_files.length === 0) { + console.log("No files in recording. Exiting"); + return false; + } + + if (this.meetingIds && this.meetingIds.length > 0 && !this.meetingIds.includes(id)) { + console.log("Meeting ID does not match the filter rules."); + return false; + } + return true; + }, + isFileRelevant(file) { + return !((file.status !== "completed") + || (file.file_type === "M4A" && !this.includeAudioRecordings) + || (file.file_type === "CHAT" && !this.includeChatTranscripts)); + }, + emitEvent(file, meeting, downloadToken = null) { + this.$emit( + { + download_url_with_token: `${file.download_url}?access_token=${downloadToken}`, + download_token: downloadToken, + ...file, + meeting_id_long: meeting.id, // Long ID is necessary for certain API operations + meeting_topic: meeting.topic, + host_id: meeting.host_id, + host_email: meeting.host_email, }, - params: { - page_number: page + 1, + { + id: file.id, + summary: `${meeting.topic} — ${file.file_type}`, + ts: +new Date(file.recording_end), }, - }; - return (await axios(config)).data; + ); }, }, async run(event) { @@ -72,49 +110,20 @@ export default { const { payload } = event; const { object, - download_token, + download_token: downloadToken, } = payload; - const { - recording_files, - host_id, - host_email, - } = object; - if (!recording_files || recording_files.length === 0) { - console.log("No files in recording. Exiting"); - return; - } + const { recording_files: recordingFiles } = object; - if (this.meetingIds && this.meetingIds.length > 0 && !this.meetingIds.includes(object.id)) { - console.log("Meeting ID does not match the filter rules."); + if (!this.isMeetingRelevant(object)) { return; } - for (const file of recording_files) { - if (file.status !== "completed") continue; - - if (file.file_type === "M4A" && !this.includeAudioRecordings) { - continue; - } - if (file.file_type === "CHAT" && !this.includeChatTranscripts) { + for (const file of recordingFiles) { + if (!this.isFileRelevant(file)) { continue; } - this.$emit( - { - download_url_with_token: `${file.download_url}?access_token=${download_token}`, - download_token, - ...file, - meeting_id_long: object.id, // Long ID is necessary for certain API operations - meeting_topic: object.topic, - host_id, - host_email, - }, - { - summary: `${object.topic} — ${file.file_type}`, - id: file.id, - ts: +new Date(file.recording_end), - }, - ); + this.emitEvent(file, object, downloadToken); } }, }; diff --git a/components/zoom/sources/webinar-created/webinar-created.mjs b/components/zoom/sources/webinar-created/webinar-created.mjs index 208aae89b86d6..9e201d8236d6f 100644 --- a/components/zoom/sources/webinar-created/webinar-created.mjs +++ b/components/zoom/sources/webinar-created/webinar-created.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-webinar-created", - name: "Webinar Created", - description: - "Emits an event each time a webinar is created where you're the host", - version: "0.0.3", - dedupe: "unique", // Dedupe based on meeting ID + name: "Webinar Created (Instant)", + description: "Emit new event each time a webinar is created where you're the host", + version: "0.0.4", + type: "source", + dedupe: "unique", // Dedupe based on webinar ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -18,19 +19,37 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + hooks: { + async deploy() { + const { webinars } = await this.zoom.listWebinars({ + page_size: 25, + }); + if (!webinars || webinars.length === 0) { + return; + } + const objects = this.sortByDate(webinars, "created_at"); + for (const object of objects) { + this.emitEvent({ + object, + }, object); + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ event: "webinar.created", payload, - }, - { - summary: object.topic, + }, meta); + }, + generateMeta(object) { + return { id: object.uuid, + summary: object.topic, ts: +new Date(object.start_time), - }, - ); + }; + }, }, }; diff --git a/components/zoom/sources/webinar-deleted/webinar-deleted.mjs b/components/zoom/sources/webinar-deleted/webinar-deleted.mjs index 81629eb00c3ff..4e4bb04fb41cb 100644 --- a/components/zoom/sources/webinar-deleted/webinar-deleted.mjs +++ b/components/zoom/sources/webinar-deleted/webinar-deleted.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-webinar-deleted", name: "Webinar Deleted", - description: - "Emits an event each time a webinar is deleted where you're the host", - version: "0.0.3", - dedupe: "unique", // Dedupe based on meeting ID + description: "Emit new event each time a webinar is deleted where you're the host", + version: "0.0.4", + type: "source", + dedupe: "unique", // Dedupe based on webinar ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -18,19 +19,20 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + methods: { + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ event: "webinar.deleted", payload, - }, - { - summary: object.topic, + }, meta); + }, + generateMeta(object) { + return { id: object.uuid, + summary: object.topic, ts: +new Date(object.start_time), - }, - ); + }; + }, }, }; diff --git a/components/zoom/sources/webinar-ended/webinar-ended.mjs b/components/zoom/sources/webinar-ended/webinar-ended.mjs index 3b0d42b0d5a45..0306aeb6023f0 100644 --- a/components/zoom/sources/webinar-ended/webinar-ended.mjs +++ b/components/zoom/sources/webinar-ended/webinar-ended.mjs @@ -1,13 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-webinar-ended", - name: "Webinar Ended", - description: "Emits an event each time a webinar ends where you're the host", - version: "0.0.3", - dedupe: "unique", // Dedupe based on meeting ID + name: "Webinar Ended (Instant)", + description: "Emit new event each time a webinar ends where you're the host", + version: "0.0.4", + type: "source", + dedupe: "unique", // Dedupe based on webinar ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -16,19 +18,43 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + hooks: { + async deploy() { + const { webinars } = await this.zoom.listWebinarMetrics({ + from: this.monthAgo(), + to: new Date().toISOString() + .slice(0, 10), + page_size: 25, + }); + if (!webinars || webinars.length === 0) { + return; + } + const objects = this.sortByDate(webinars, "end_time"); + for (const object of objects) { + const endTime = Date.parse(object.end_time); + if (endTime < Date.now()) { + this.emitEvent({ + object, + }, object); + } + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ event: "webinar.ended", payload, - }, - { - summary: object.topic, + }, meta); + }, + generateMeta(object) { + return { id: object.uuid, - ts: +new Date(object.start_time), - }, - ); + summary: object.topic, + ts: +new Date(object.end_time), + }; + }, }, }; diff --git a/components/zoom/sources/webinar-started/webinar-started.mjs b/components/zoom/sources/webinar-started/webinar-started.mjs index 35a6f4bae319b..fa226a0fbfd7e 100644 --- a/components/zoom/sources/webinar-started/webinar-started.mjs +++ b/components/zoom/sources/webinar-started/webinar-started.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-webinar-started", - name: "Webinar Started", - description: - "Emits an event each time a webinar starts where you're the host", - version: "0.0.3", - dedupe: "unique", // Dedupe based on meeting ID + name: "Webinar Started (Instant)", + description: "Emit new event each time a webinar starts where you're the host", + version: "0.0.4", + type: "source", + dedupe: "unique", // Dedupe based on webinar ID props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -17,19 +18,41 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + hooks: { + async deploy() { + const { webinars } = await this.zoom.listWebinars({ + page_size: 25, + }); + if (!webinars || webinars.length === 0) { + return; + } + const objects = this.sortByDate(webinars, "start_time"); + for (const object of objects) { + const startTime = Date.parse(object.start_time); + if (startTime < Date.now()) { + this.emitEvent({ + object, + time_stamp: startTime, + }, object); + } + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(object); + this.$emit({ event: "webinar.started", payload, - }, - { - summary: object.topic, + }, meta); + }, + generateMeta(object) { + return { id: object.uuid, + summary: object.topic, ts: +new Date(object.start_time), - }, - ); + }; + }, }, }; diff --git a/components/zoom/sources/webinar-updated/webinar-updated.mjs b/components/zoom/sources/webinar-updated/webinar-updated.mjs index f5fcb8e7d3043..4353f04156d22 100644 --- a/components/zoom/sources/webinar-updated/webinar-updated.mjs +++ b/components/zoom/sources/webinar-updated/webinar-updated.mjs @@ -1,14 +1,15 @@ -import zoom from "../../zoom.app.mjs"; +import common from "../common/common.mjs"; export default { + ...common, key: "zoom-webinar-updated", - name: "Webinar Updated", - description: - "Emits an event each time a webinar is updated where you're the host", - version: "0.0.3", - dedupe: "unique", // Dedupe based on meeting ID + name: "Webinar Updated (Instant)", + description: "Emit new event each time a webinar is updated where you're the host", + version: "0.0.4", + type: "source", + dedupe: "unique", // Dedupe based on webinar ID & timestamp props: { - zoom, + ...common.props, zoomApphook: { type: "$.interface.apphook", appProp: "zoom", @@ -17,18 +18,38 @@ export default { ], }, }, - async run(event) { - const { payload } = event; - const { object } = payload; - this.$emit( - { + hooks: { + async deploy() { + const { webinars } = await this.zoom.listWebinars({ + page_size: 25, + }); + if (!webinars || webinars.length === 0) { + return; + } + const objects = this.sortByDate(webinars, "created_at"); + for (const object of objects) { + this.emitEvent({ + object, + time_stamp: +new Date(object.start_time), + }, object); + } + }, + }, + methods: { + ...common.methods, + emitEvent(payload, object) { + const meta = this.generateMeta(payload, object); + this.$emit({ event: "webinar.updated", payload, - }, - { - summary: `Webinar ${object.id} updated`, + }, meta); + }, + generateMeta(payload, object) { + return { id: `${object.id}-${payload.time_stamp}`, - }, - ); + summary: `Webinar ${object.id} updated`, + ts: +new Date(object.start_time), + }; + }, }, }; diff --git a/components/zoom/zoom.app.mjs b/components/zoom/zoom.app.mjs index a074a00173849..cf071c40caa8b 100644 --- a/components/zoom/zoom.app.mjs +++ b/components/zoom/zoom.app.mjs @@ -1,4 +1,99 @@ +import { axios } from "@pipedream/platform"; + export default { type: "app", app: "zoom", + propDefinitions: { + meetingIds: { + type: "integer[]", + label: "Meeting Filter", + description: "Optionally filter for events for one or more meetings", + async options({ page }) { + const { meetings } = await this.listMeetings({ + page_number: page + 1, + }); + return meetings.map((meeting) => ({ + label: `${meeting.topic} (${meeting.id})`, + value: meeting.id, + })); + }, + optional: true, + }, + includeAudioRecordings: { + type: "boolean", + label: "Include Audio Recordings", + description: + "This source emits video (MP4) recordings only by default. Set this prop to true to include audio recordings", + optional: true, + default: false, + }, + includeChatTranscripts: { + type: "boolean", + label: "Include Chat Transcripts", + description: + "This source emits video (MP4) recordings only by default. Set this prop to `true` to include chat transcripts", + optional: true, + default: false, + }, + }, + methods: { + _baseUrl() { + return "https://api.zoom.us/v2/"; + }, + _getHeaders() { + return { + "Authorization": `Bearer ${this.$auth.oauth_access_token}`, + "Content-Type": "application/json", + }; + }, + async _makeRequest(args = {}) { + const { + method = "GET", + headers, + path, + $ = this, + ...otherArgs + } = args; + const config = { + method, + headers: { + ...headers, + ...this._getHeaders(), + }, + url: `${this._baseUrl()}${path}`, + ...otherArgs, + }; + return axios($, config); + }, + async getPastMeetingDetails(meetingId, params) { + return this._makeRequest({ + path: `past_meetings/${meetingId}`, + params, + }); + }, + async listMeetings(params) { + return this._makeRequest({ + path: "users/me/meetings", + params, + }); + }, + async listWebinars(params) { + return this._makeRequest({ + path: "users/me/webinars", + params, + }); + }, + async listWebinarMetrics(params) { + return this._makeRequest({ + path: "metrics/webinars", + params, + }); + }, + async listRecordings(params) { + return this._makeRequest({ + path: "users/me/recordings", + params, + }); + }, + }, }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 61c2a15243f43..60d56235b94e5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -765,6 +765,9 @@ importers: dependencies: '@pipedream/platform': 0.10.0 + components/isn: + specifiers: {} + components/jellyreach: specifiers: {} @@ -1542,12 +1545,18 @@ importers: lodash.pickby: 4.6.0 mime: 3.0.0 + components/triggercmd: + specifiers: {} + components/twilio: specifiers: twilio: ^3.54.2 dependencies: twilio: 3.77.1 + components/twitch_developer_app: + specifiers: {} + components/twitter: specifiers: axios: ^0.21.1 @@ -1587,6 +1596,9 @@ importers: components/vbout: specifiers: {} + components/vectera: + specifiers: {} + components/vend: specifiers: '@pipedream/platform': ^0.10.0 @@ -1728,7 +1740,10 @@ importers: '@pipedream/platform': 0.10.0 components/zoom: - specifiers: {} + specifiers: + '@pipedream/platform': ^1.1.0 + dependencies: + '@pipedream/platform': link:../../platform components/zoom_admin: specifiers: @@ -14731,6 +14746,7 @@ packages: /mkdirp/0.5.6: resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true dependencies: minimist: 1.2.6 dev: true @@ -16898,6 +16914,7 @@ packages: /rimraf/2.7.1: resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true dependencies: glob: 7.2.0 dev: true @@ -17050,6 +17067,7 @@ packages: /semver/6.3.0: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true /semver/7.0.0: resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==}