From 262089d8fc9cd7aebb84c738c7b97c99085a70e6 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 25 Oct 2023 10:36:44 -0300 Subject: [PATCH 1/3] [Components] Spotlightr #8578 Triggers - Video Viewed Actions - Create Video - Delete Video --- .../create-video copy/create-video.mjs | 138 ++++++++++++++++++ .../actions/create-video/create-video.mjs | 138 ++++++++++++++++++ .../actions/delete-videos/delete-videos.mjs | 35 +++++ components/spotlightr/common/utils.mjs | 6 + components/spotlightr/package.json | 9 +- .../sources/video-viewed/test-event.mjs | 28 ++++ .../sources/video-viewed/video-viewed.mjs | 76 ++++++++++ components/spotlightr/spotlightr.app.mjs | 125 +++++++++++++++- pnpm-lock.yaml | 15 +- 9 files changed, 562 insertions(+), 8 deletions(-) create mode 100644 components/spotlightr/actions/create-video copy/create-video.mjs create mode 100644 components/spotlightr/actions/create-video/create-video.mjs create mode 100644 components/spotlightr/actions/delete-videos/delete-videos.mjs create mode 100644 components/spotlightr/common/utils.mjs create mode 100644 components/spotlightr/sources/video-viewed/test-event.mjs create mode 100644 components/spotlightr/sources/video-viewed/video-viewed.mjs diff --git a/components/spotlightr/actions/create-video copy/create-video.mjs b/components/spotlightr/actions/create-video copy/create-video.mjs new file mode 100644 index 0000000000000..1a62d810bb6e9 --- /dev/null +++ b/components/spotlightr/actions/create-video copy/create-video.mjs @@ -0,0 +1,138 @@ +import { ConfigurationError } from "@pipedream/platform"; +import FormData from "form-data"; +import fs from "fs"; +import { checkTmp } from "../../common/utils.mjs"; +import spotlightr from "../../spotlightr.app.mjs"; + +export default { + key: "spotlightr-create-video", + name: "Create Video", + version: "0.0.1", + description: "It let's you to create a video in an application. [See the documentation](https://app.spotlightr.com/docs/api/#create-video)", + type: "action", + props: { + spotlightr, + url: { + type: "string", + label: "URL", + description: "The video URL. `You must provide at least the URL or File.`", + optional: true, + }, + name: { + type: "string", + label: "Name", + description: "The name of the video.", + }, + customS3: { + type: "string", + label: "Custom S3", + description: "**0** or **ID** of custom integration.", + default: "0", + }, + hls: { + type: "integer", + label: "HLS", + description: "The media streaming protocol.", + options: [ + { + label: "To leave as unsecured.", + value: 0, + }, + { + label: "To encode.", + value: 1, + }, + ], + optional: true, + }, + videoGroup: { + propDefinition: [ + spotlightr, + "videoGroup", + ], + optional: true, + }, + create: { + type: "integer", + label: "Create", + description: "The type of the creation.", + options: [ + { + label: "To debug.", + value: 0, + }, + { + label: "To confirm.", + value: 1, + }, + ], + optional: true, + }, + playerSettings: { + type: "object", + label: "Player Settings", + description: "Video ID for coping playerSettings (decoded base64)", + optional: true, + }, + file: { + type: "string", + label: "File", + description: "Full path to the file in `/tmp/` directory. E.g. `/tmp/video.mp4`. `You must provide at least the URL or File.`", + optional: true, + }, + }, + async run({ $ }) { + const { + spotlightr, + url, + file, + ...data + } = this; + + if (!file && !url) { + throw new ConfigurationError("You must provide at least the URL or File."); + } + + let preparedData = {}; + if (file) { + const formData = new FormData(); + + const path = checkTmp(file); + if (!fs.existsSync(path)) { + throw new ConfigurationError("File does not exist!"); + } + formData.append("file", fs.createReadStream(path)); + for (const [ + key, + value, + ] of Object.entries(data)) { + formData.append(key, value); + } + + preparedData = { + defaultRequest: true, + headers: formData.getHeaders(), + data: formData, + }; + + } else { + preparedData = { + data: { + URL: url, + vooKey: this.spotlightr._getApiKey(), + ...data, + }, + }; + } + + const response = await spotlightr.createVideo({ + $, + ...preparedData, + }); + + $.export("$summary", `A new video with ${response.data + ? `URL: ${response.data}` + : `Id: ${response}`} was successfully created!`); + return response.data || response; + }, +}; diff --git a/components/spotlightr/actions/create-video/create-video.mjs b/components/spotlightr/actions/create-video/create-video.mjs new file mode 100644 index 0000000000000..aee5bbd7e2247 --- /dev/null +++ b/components/spotlightr/actions/create-video/create-video.mjs @@ -0,0 +1,138 @@ +import { ConfigurationError } from "@pipedream/platform"; +import FormData from "form-data"; +import fs from "fs"; +import { checkTmp } from "../../common/utils.mjs"; +import spotlightr from "../../spotlightr.app.mjs"; + +export default { + key: "spotlightr-create-video", + name: "Create Video", + version: "0.0.1", + description: "It let's you to create a video in an application. [See the documentation](https://app.spotlightr.com/docs/api/#create-video)", + type: "action", + props: { + spotlightr, + url: { + type: "string", + label: "URL", + description: "The video URL. `You must provide at least the URL or File.`", + optional: true, + }, + name: { + type: "string", + label: "Name", + description: "The name of the video.", + }, + customS3: { + type: "string", + label: "Custom S3", + description: "**0** or **ID** of custom integration.", + default: "0", + }, + hls: { + type: "integer", + label: "HLS", + description: "The media streaming protocol.", + options: [ + { + label: "To leave as unsecured.", + value: 0, + }, + { + label: "To encode.", + value: 1, + }, + ], + optional: true, + }, + videoGroup: { + propDefinition: [ + spotlightr, + "videoGroup", + ], + optional: true, + }, + create: { + type: "integer", + label: "Create", + description: "The type of the creation.", + options: [ + { + label: "To debug.", + value: 0, + }, + { + label: "To confirm.", + value: 1, + }, + ], + optional: true, + }, + playerSettings: { + type: "object", + label: "Player Settings", + description: "Video ID for coping playerSettings (decoded base64)", + optional: true, + }, + file: { + type: "string", + label: "File", + description: "Full path to the file in `/tmp/` directory. E.g. `/tmp/video.mp4`. `You must provide at least the URL or File.`", + optional: true, + }, + }, + async run({ $ }) { + const { + spotlightr, + url, + file, + ...data + } = this; + + if (!file && !url) { + throw new ConfigurationError("You must provide at least the URL or File."); + } + + let preparedData = {}; + if (file) { + const formData = new FormData(); + + const path = checkTmp(file); + if (!fs.existsSync(path)) { + throw new ConfigurationError("File does not exist!"); + } + + formData.append("file", fs.createReadStream(path)); + for (const [ + key, + value, + ] of Object.entries(data)) { + formData.append(key, value); + } + + preparedData = { + formDataRequest: true, + headers: formData.getHeaders(), + data: formData, + }; + + } else { + preparedData = { + data: { + URL: url, + ...data, + }, + }; + } + + const response = await spotlightr.createVideo({ + $, + ...preparedData, + }); + + $.export("$summary", `A new video with ${response.data + ? `URL: ${response.data}` + : `Id: ${response}`} was successfully created!`); + return response.data || response; + }, +}; diff --git a/components/spotlightr/actions/delete-videos/delete-videos.mjs b/components/spotlightr/actions/delete-videos/delete-videos.mjs new file mode 100644 index 0000000000000..00406ca58fa98 --- /dev/null +++ b/components/spotlightr/actions/delete-videos/delete-videos.mjs @@ -0,0 +1,35 @@ +import spotlightr from "../../spotlightr.app.mjs"; + +export default { + key: "spotlightr-delete-videos", + name: "Delete Videos", + version: "0.0.1", + description: "Delete videos from your account. [See the documentation](https://app.spotlightr.com/docs/api/#deleteVideo)", + type: "action", + props: { + spotlightr, + videoId: { + propDefinition: [ + spotlightr, + "videoId", + ], + type: "string[]", + }, + }, + async run({ $ }) { + const { + spotlightr, + videoId, + } = this; + + const response = await spotlightr.deleteVideo({ + $, + params: { + IDs: videoId, + }, + }); + + $.export("$summary", `The videos with Ids: ${videoId.toString()} were successfully deleted!`); + return response; + }, +}; diff --git a/components/spotlightr/common/utils.mjs b/components/spotlightr/common/utils.mjs new file mode 100644 index 0000000000000..dc2ed5a5be34d --- /dev/null +++ b/components/spotlightr/common/utils.mjs @@ -0,0 +1,6 @@ +export const checkTmp = (filename) => { + if (filename.indexOf("/tmp") === -1) { + return `/tmp/${filename}`; + } + return filename; +}; diff --git a/components/spotlightr/package.json b/components/spotlightr/package.json index 5cfd974938446..d61745dce68b8 100644 --- a/components/spotlightr/package.json +++ b/components/spotlightr/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/spotlightr", - "version": "0.0.1", + "version": "0.1.0", "description": "Pipedream Spotlightr Components", "main": "spotlightr.app.mjs", "keywords": [ @@ -11,5 +11,10 @@ "author": "Pipedream (https://pipedream.com/)", "publishConfig": { "access": "public" + }, + "dependencies": { + "@pipedream/platform": "^1.5.1", + "form-data": "^4.0.0", + "fs": "^0.0.1-security" } -} \ No newline at end of file +} diff --git a/components/spotlightr/sources/video-viewed/test-event.mjs b/components/spotlightr/sources/video-viewed/test-event.mjs new file mode 100644 index 0000000000000..23d5f7993327f --- /dev/null +++ b/components/spotlightr/sources/video-viewed/test-event.mjs @@ -0,0 +1,28 @@ +export default { + "id": 123123123, + "videoID": 123123123, + "date": "2023-10-24 17:37:20", + "cookie": "n7mqa33xk123123mtpmn", + "userID": 123123123, + "email": "", + "IP": "", + "phone": "", + "data": "", + "watchedSegments": "", + "percentWatched": 0, + "country": "", + "country_name": "", + "region_name": "", + "city": "", + "zip": "", + "latitude": "0.00000000", + "longitude": "0.00000000", + "currency_code": "", + "currency_name": "", + "device": "", + "browser": "", + "viewerID": 123123123, + "contactData": "", + "referer": "oembed5.cdn.spotlightr.com", + "customViewerID": "" +} \ No newline at end of file diff --git a/components/spotlightr/sources/video-viewed/video-viewed.mjs b/components/spotlightr/sources/video-viewed/video-viewed.mjs new file mode 100644 index 0000000000000..6305a56303efe --- /dev/null +++ b/components/spotlightr/sources/video-viewed/video-viewed.mjs @@ -0,0 +1,76 @@ +import { DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform"; +import spotlightr from "../../spotlightr.app.mjs"; +import sampleEmit from "./test-event.mjs"; + +export default { + key: "spotlightr-video-viewed", + name: "New Video View", + version: "0.0.1", + description: "Emit new event when a specific video is viewed by an user.", + type: "source", + dedupe: "unique", + props: { + spotlightr, + db: "$.service.db", + timer: { + label: "Polling interval", + description: "Pipedream will poll the Spotlightr on this schedule", + type: "$.interface.timer", + default: { + intervalSeconds: DEFAULT_POLLING_SOURCE_TIMER_INTERVAL, + }, + }, + videoId: { + propDefinition: [ + spotlightr, + "videoId", + ], + }, + }, + methods: { + _getLastDate() { + return this.db.get("lastDate") || 0; + }, + _setLastDate(lastDate) { + this.db.set("lastDate", lastDate); + }, + async startEvent(maxResults = 0) { + const { + spotlightr, + videoId, + } = this; + + const lastDate = this._getLastDate(); + const items = spotlightr.paginate({ + fn: spotlightr.getViews, + maxResults, + params: { + videoID: videoId, + }, + }); + + let responseArray = []; + + for await (const item of items) { + if (new Date(item.date) <= new Date(lastDate)) break; + responseArray.push(item); + } + if (responseArray.length) this._setLastDate(responseArray[0].created_time); + + for (const item of responseArray.reverse()) { + this.$emit( + item, + { + id: item.id, + summary: `New view with id: "${item.id}" was created!`, + ts: item.date, + }, + ); + } + }, + }, + async run() { + await this.startEvent(); + }, + sampleEmit, +}; diff --git a/components/spotlightr/spotlightr.app.mjs b/components/spotlightr/spotlightr.app.mjs index 6ee7739fdbed6..86e0b3e4dd7b9 100644 --- a/components/spotlightr/spotlightr.app.mjs +++ b/components/spotlightr/spotlightr.app.mjs @@ -1,11 +1,126 @@ +import axiosPipedream from "@pipedream/platform"; +import axios from "axios"; + export default { type: "app", app: "spotlightr", - propDefinitions: {}, + propDefinitions: { + videoGroup: { + type: "string", + label: "Video Group", + description: "The ID of the project.", + async options() { + const { data } = await this.listGroups(); + + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + videoId: { + type: "string", + label: "Video Id", + description: "The ID of the video.", + async options() { + const { videos: { data } } = await this.listVideos(); + + return data.map(({ + id: value, name: label, + }) => ({ + label, + value, + })); + }, + }, + }, methods: { - // this.$auth contains connected account data - authKeys() { - console.log(Object.keys(this.$auth)); + _apiUrl() { + return "https://api.spotlightr.com/api"; + }, + _getApiKey() { + return this.$auth.api_key; + }, + _getParams(params = {}) { + return { + ...params, + "vooKey": this._getApiKey(), + }; + }, + _makeRequest({ + $ = this, params, path, formDataRequest = false, ...opts + }) { + const config = { + url: `${this._apiUrl()}/${path}`, + params: this._getParams(params), + ...opts, + }; + + if (formDataRequest) return axios(config); + return axiosPipedream.axios($, config); + }, + createVideo(args = {}) { + return this._makeRequest({ + method: "POST", + path: "createVideo", + ...args, + }); + }, + deleteVideo(args = {}) { + return this._makeRequest({ + method: "POST", + path: "deleteVideo", + ...args, + }); + }, + getViews(args = {}) { + return this._makeRequest({ + path: "views/getViews", + ...args, + }); + }, + listGroups(args = {}) { + return this._makeRequest({ + path: "groups", + ...args, + }); + }, + listVideos(args = {}) { + return this._makeRequest({ + path: "videos", + ...args, + }); + }, + async *paginate({ + fn, params = {}, maxResults = null, + }) { + let hasMore = false; + let count = 0; + let page = 0; + + do { + params.page = ++page; + const { + data, + current_page: currentPage, + last_page: lastPage, + } = await fn({ + params, + }); + + for (const d of data) { + yield d; + + if (maxResults && ++count === maxResults) { + return count; + } + } + + hasMore = currentPage != lastPage; + + } while (hasMore); }, }, -}; \ No newline at end of file +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 52ba58dac46b7..5de68c8268d80 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -856,6 +856,9 @@ importers: components/cheddar: specifiers: {} + components/chmeetings: + specifiers: {} + components/circl_hash_lookup: specifiers: {} @@ -5291,6 +5294,9 @@ importers: dependencies: '@pipedream/platform': 0.10.0 + components/signable: + specifiers: {} + components/signaturely: specifiers: '@pipedream/platform': ^1.5.1 @@ -5530,7 +5536,14 @@ importers: '@pipedream/platform': 1.5.1 components/spotlightr: - specifiers: {} + specifiers: + '@pipedream/platform': ^1.5.1 + form-data: ^4.0.0 + fs: ^0.0.1-security + dependencies: + '@pipedream/platform': 1.5.1 + form-data: 4.0.0 + fs: 0.0.1-security components/spreadsheet_com: specifiers: From cf764032585cdc2290d6ba3eabbac942138453d8 Mon Sep 17 00:00:00 2001 From: Luan Cazarine Date: Wed, 25 Oct 2023 11:28:45 -0300 Subject: [PATCH 2/3] remove duplicated action --- .../create-video copy/create-video.mjs | 138 ------------------ 1 file changed, 138 deletions(-) delete mode 100644 components/spotlightr/actions/create-video copy/create-video.mjs diff --git a/components/spotlightr/actions/create-video copy/create-video.mjs b/components/spotlightr/actions/create-video copy/create-video.mjs deleted file mode 100644 index 1a62d810bb6e9..0000000000000 --- a/components/spotlightr/actions/create-video copy/create-video.mjs +++ /dev/null @@ -1,138 +0,0 @@ -import { ConfigurationError } from "@pipedream/platform"; -import FormData from "form-data"; -import fs from "fs"; -import { checkTmp } from "../../common/utils.mjs"; -import spotlightr from "../../spotlightr.app.mjs"; - -export default { - key: "spotlightr-create-video", - name: "Create Video", - version: "0.0.1", - description: "It let's you to create a video in an application. [See the documentation](https://app.spotlightr.com/docs/api/#create-video)", - type: "action", - props: { - spotlightr, - url: { - type: "string", - label: "URL", - description: "The video URL. `You must provide at least the URL or File.`", - optional: true, - }, - name: { - type: "string", - label: "Name", - description: "The name of the video.", - }, - customS3: { - type: "string", - label: "Custom S3", - description: "**0** or **ID** of custom integration.", - default: "0", - }, - hls: { - type: "integer", - label: "HLS", - description: "The media streaming protocol.", - options: [ - { - label: "To leave as unsecured.", - value: 0, - }, - { - label: "To encode.", - value: 1, - }, - ], - optional: true, - }, - videoGroup: { - propDefinition: [ - spotlightr, - "videoGroup", - ], - optional: true, - }, - create: { - type: "integer", - label: "Create", - description: "The type of the creation.", - options: [ - { - label: "To debug.", - value: 0, - }, - { - label: "To confirm.", - value: 1, - }, - ], - optional: true, - }, - playerSettings: { - type: "object", - label: "Player Settings", - description: "Video ID for coping playerSettings (decoded base64)", - optional: true, - }, - file: { - type: "string", - label: "File", - description: "Full path to the file in `/tmp/` directory. E.g. `/tmp/video.mp4`. `You must provide at least the URL or File.`", - optional: true, - }, - }, - async run({ $ }) { - const { - spotlightr, - url, - file, - ...data - } = this; - - if (!file && !url) { - throw new ConfigurationError("You must provide at least the URL or File."); - } - - let preparedData = {}; - if (file) { - const formData = new FormData(); - - const path = checkTmp(file); - if (!fs.existsSync(path)) { - throw new ConfigurationError("File does not exist!"); - } - formData.append("file", fs.createReadStream(path)); - for (const [ - key, - value, - ] of Object.entries(data)) { - formData.append(key, value); - } - - preparedData = { - defaultRequest: true, - headers: formData.getHeaders(), - data: formData, - }; - - } else { - preparedData = { - data: { - URL: url, - vooKey: this.spotlightr._getApiKey(), - ...data, - }, - }; - } - - const response = await spotlightr.createVideo({ - $, - ...preparedData, - }); - - $.export("$summary", `A new video with ${response.data - ? `URL: ${response.data}` - : `Id: ${response}`} was successfully created!`); - return response.data || response; - }, -}; From d6ae71b02742afa7573bed512ccd41b130e71746 Mon Sep 17 00:00:00 2001 From: michelle0927 Date: Wed, 25 Oct 2023 11:43:18 -0400 Subject: [PATCH 3/3] minor updates --- components/spotlightr/actions/create-video/create-video.mjs | 2 +- components/spotlightr/sources/video-viewed/video-viewed.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/components/spotlightr/actions/create-video/create-video.mjs b/components/spotlightr/actions/create-video/create-video.mjs index aee5bbd7e2247..a1a0dc5aad8de 100644 --- a/components/spotlightr/actions/create-video/create-video.mjs +++ b/components/spotlightr/actions/create-video/create-video.mjs @@ -8,7 +8,7 @@ export default { key: "spotlightr-create-video", name: "Create Video", version: "0.0.1", - description: "It let's you to create a video in an application. [See the documentation](https://app.spotlightr.com/docs/api/#create-video)", + description: "Create a video in an application. [See the documentation](https://app.spotlightr.com/docs/api/#create-video)", type: "action", props: { spotlightr, diff --git a/components/spotlightr/sources/video-viewed/video-viewed.mjs b/components/spotlightr/sources/video-viewed/video-viewed.mjs index 6305a56303efe..2af9cfdc6e0af 100644 --- a/components/spotlightr/sources/video-viewed/video-viewed.mjs +++ b/components/spotlightr/sources/video-viewed/video-viewed.mjs @@ -6,7 +6,7 @@ export default { key: "spotlightr-video-viewed", name: "New Video View", version: "0.0.1", - description: "Emit new event when a specific video is viewed by an user.", + description: "Emit new event when a specific video is viewed by a user.", type: "source", dedupe: "unique", props: { @@ -63,7 +63,7 @@ export default { { id: item.id, summary: `New view with id: "${item.id}" was created!`, - ts: item.date, + ts: Date.parse(item.date), }, ); }