-
Couldn't load subscription status.
- Fork 5.5k
blotato new components #18866
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
blotato new components #18866
Conversation
| The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
WalkthroughAdds a Blotato component with five new action modules (create-post, create-video, delete-video, get-video, upload-media), a revamped app file exposing an internal _makeRequest plus API wrapper methods, and a package.json version/dependency bump. Changes
Sequence Diagram(s)sequenceDiagram autonumber actor User participant Action as Create Post Action participant App as Blotato App participant API as Blotato API User->>Action: run({ accountId, text, mediaUrls, targetType, ... }) Action->>Action: parse additionalPosts & build content/target Action->>App: _makeRequest(path="/v2/posts", method="POST", data) App->>API: POST https://backend.blotato.com/v2/posts (API key header) API-->>App: 200 { id, status, ... } App-->>Action: response Action->>Action: $.export("summary", "Posted with ID: {{id}}") Action-->>User: return response sequenceDiagram autonumber actor User participant Action as Video/Media Action participant App as Blotato App participant API as Blotato API User->>Action: run({ $ }) Action->>App: call (createVideoFromTemplate / deleteVideo / getVideo / uploadMedia / listTemplates) App->>API: HTTP request to /v2/videos/* or /v2/media API-->>App: response App-->>Action: response Action->>Action: $.export("summary", "Operation complete: {{id/status}}") Action-->>User: return response Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Suggested labels
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings, 1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified. |
| Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (4)
components/blotato/actions/delete-video/delete-video.mjs (1)
25-32: Guard for 204 No Content responsesDelete returns 204 No Content per docs, so response may be empty. Consider not relying on a response body and returning a simple
{ id: videoId, deleted: true }or nothing. (help.blotato.com)components/blotato/actions/create-video/create-video.mjs (1)
21-27: Harden options(), JSON parsing, and summary
- Pass $ in options() and default items to avoid crashes.
- Catch JSON.parse errors to return a clear message.
- Optional-chain in $summary to avoid undefined access if API shape changes.
Apply this diff:
async options() { - const { items } = await this.blotato.listTemplates({ - fields: "id,title,description", - }); - return items.map((template) => ({ - label: template.title || template.id, - value: template.id, - })); + const { items = [] } = await this.blotato.listTemplates({ + $: this, + fields: "id,title,description", + }); + return items.map(({ title, id }) => ({ + label: title || id, + value: id, + })); },- const inputs = JSON.parse(this.inputs); + let inputs; + try { + inputs = JSON.parse(this.inputs); + } catch (err) { + throw new Error(`Invalid JSON in "Inputs": ${err.message}`); + }- $.export("$summary", `Successfully created video with ID: ${response.item.id}. Status: ${response.item.status}. To view progress, visit https://my.blotato.com/videos/${response.item.id}`); + $.export("$summary", `Successfully created video with ID: ${response?.item?.id}. Status: ${response?.item?.status}. To view progress, visit https://my.blotato.com/videos/${response?.item?.id}`);This action targets the “new template system” endpoint (/v2/videos/from-templates), which is documented and matches the payload shape used here. Please confirm that your selected templates’ input schema maps to the stringified JSON you pass as
inputs. (help.blotato.com)Also applies to: 56-56, 66-66
components/blotato/blotato.app.mjs (1)
8-22: Optional: add timeout and baseURL for resilienceConsider setting a sensible default
timeout(e.g., 30s) and usingbaseURLwithurl: pathfor clarity. Both are optional improvements for reliability.- return axios($, { - url: `https://backend.blotato.com${path}`, + return axios($, { + baseURL: "https://backend.blotato.com", + url: path, method, headers: { "blotato-api-key": `${this.$auth.api_key}`, "accept": "*/*", ...headers, }, data, + timeout: 30000, ...opts, });components/blotato/actions/upload-media/upload-media.mjs (1)
21-25: Consider adding URL format validation.The
urlprop accepts any string without validation. While the API will reject invalid URLs, adding client-side validation would improve user experience by catching errors earlier.You could add a
validatefunction to the prop:url: { type: "string", label: "URL", description: "The publicly accessible URL of the media to upload. For Google Drive files, use the format: `https://drive.google.com/uc?export=download&id=YOUR_FILE_ID`", + validate: (value) => { + try { + new URL(value); + return true; + } catch { + return "Please provide a valid URL"; + } + }, },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
components/blotato/actions/create-post/create-post.mjs(1 hunks)components/blotato/actions/create-video/create-video.mjs(1 hunks)components/blotato/actions/delete-video/delete-video.mjs(1 hunks)components/blotato/actions/get-video/get-video.mjs(1 hunks)components/blotato/actions/upload-media/upload-media.mjs(1 hunks)components/blotato/blotato.app.mjs(1 hunks)components/blotato/package.json(2 hunks)
🧰 Additional context used
🧬 Code graph analysis (5)
components/blotato/actions/get-video/get-video.mjs (2)
components/blotato/actions/create-video/create-video.mjs (1)
response(58-64)components/blotato/actions/delete-video/delete-video.mjs (1)
response(25-28)
components/blotato/actions/create-video/create-video.mjs (2)
components/blotato/actions/delete-video/delete-video.mjs (1)
response(25-28)components/blotato/actions/get-video/get-video.mjs (1)
response(25-28)
components/blotato/actions/create-post/create-post.mjs (1)
components/blotato/actions/upload-media/upload-media.mjs (1)
response(30-37)
components/blotato/actions/delete-video/delete-video.mjs (2)
components/blotato/actions/create-post/create-post.mjs (1)
response(367-372)components/blotato/actions/get-video/get-video.mjs (1)
response(25-28)
components/blotato/actions/upload-media/upload-media.mjs (1)
components/blotato/actions/create-post/create-post.mjs (1)
response(367-372)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Lint Code Base
- GitHub Check: Publish TypeScript components
- GitHub Check: Verify TypeScript components
🔇 Additional comments (10)
components/blotato/package.json (1)
3-3: Version bump and dependency addition look goodThe package version and @pipedream/platform dependency align with the new actions. No issues.
Also applies to: 15-17
components/blotato/actions/delete-video/delete-video.mjs (1)
1-34: API usage and action wiring look correctEndpoint and header strategy align with Blotato’s Delete Video API. Good use of $summary.
components/blotato/actions/get-video/get-video.mjs (1)
25-32: LGTM: correct endpoint and read-only semanticsMatches the Find Video endpoint and adheres to readOnly usage.
components/blotato/blotato.app.mjs (1)
37-52: API paths and headers match docs
- createVideoFromTemplate → POST /v2/videos/from-templates
- deleteVideo → DELETE /v2/videos/{id}
- getVideo → GET /v2/videos/creations/{id}
- listTemplates → GET /v2/videos/templates
All align with current Blotato docs and header usage (blotato-api-key).
Also applies to: 53-62, 63-71, 85-97
components/blotato/actions/upload-media/upload-media.mjs (2)
1-13: LGTM!The import and metadata configuration are properly structured.
39-39: Verify that the API response always includes aurlfield.The summary message assumes
response.urlexists. If the API doesn't return this field, the summary will display "undefined".Consider adding a defensive check:
-$.export("$summary", `Successfully uploaded media. New URL: ${response.url}`); +$.export("$summary", `Successfully uploaded media${response.url ? `. New URL: ${response.url}` : ""}`);You can verify the API response structure by checking the Blotato API documentation or running this action with test data.
components/blotato/actions/create-post/create-post.mjs (4)
1-61: LGTM!The metadata and base props are well-structured with clear descriptions and appropriate constraints. The use of
reloadProps: truefor dynamic platform-specific fields is a good design choice.
62-267: LGTM!The dynamic props loading is well-implemented with comprehensive platform-specific configuration. The absence of additional props for Twitter and Bluesky appears intentional, as these platforms work with just the base props.
268-299: LGTM!The content building logic is solid with proper error handling for JSON parsing. The webhook-to-"other" platform mapping aligns with the API's requirements.
374-374: Verify that the API response always includes apostSubmissionIdfield.The summary message assumes
response.postSubmissionIdexists. If the API doesn't return this field, the summary will display "undefined".Consider adding a defensive check:
-$.export("$summary", `Successfully submitted post. Post Submission ID: ${response.postSubmissionId}`); +$.export("$summary", `Successfully submitted post${response.postSubmissionId ? `. Post Submission ID: ${response.postSubmissionId}` : ""}`);You can verify the API response structure by checking the Blotato API documentation or testing the action.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
components/blotato/blotato.app.mjs (1)
23-36: Past review issue remains unaddressed: missing $ parameter and incorrect payload structure.This method still has the critical issues flagged in the previous review:
- Missing
$parameter in the function signature (other methods likecreateVideoFromTemplate,deleteVideo,getVideo,uploadMediaall accept$)- Incorrect payload structure - the API expects
{ post, scheduledTime, slot, postDraftId }but this sends{ title, content, media, ...args }The
create-post.mjsaction (line 366) calls_makeRequestdirectly with$, but this helper method should also accept and forward$.Apply the fix from the previous review:
- createPost({ - title, content, media, ...args - } = {}) { - return this._makeRequest({ - method: "POST", - path: "/v2/posts", - data: { - title, - content, - media, - ...args, - }, - }); - }, + createPost({ + $, post, scheduledTime, slot, postDraftId, ...args + } = {}) { + return this._makeRequest({ + $, + method: "POST", + path: "/v2/posts", + data: { + post, + scheduledTime, + slot, + postDraftId, + }, + ...args, + }); + },
🧹 Nitpick comments (1)
components/blotato/actions/upload-media/upload-media.mjs (1)
27-38: Consider defensive access to response.url.The logic is correct and straightforward. However, Line 35 directly accesses
response.urlwithout checking its existence. If the API returns an unexpected format, this could throw an error.Consider adding a fallback:
- $.export("$summary", `Successfully uploaded media. New URL: ${response.url}`); + $.export("$summary", `Successfully uploaded media${response?.url ? `. New URL: ${response.url}` : ""}`);Or validate the response before accessing:
const response = await this.blotato.uploadMedia({ $, url, }); + + if (!response?.url) { + throw new Error("Upload succeeded but no media URL was returned"); + } $.export("$summary", `Successfully uploaded media. New URL: ${response.url}`);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
components/blotato/actions/upload-media/upload-media.mjs(1 hunks)components/blotato/blotato.app.mjs(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/blotato/actions/upload-media/upload-media.mjs (4)
components/blotato/actions/create-video/create-video.mjs (1)
response(58-64)components/blotato/actions/get-video/get-video.mjs (1)
response(25-28)components/blotato/actions/delete-video/delete-video.mjs (1)
response(25-28)components/blotato/actions/create-post/create-post.mjs (1)
response(367-372)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: pnpm publish
- GitHub Check: Verify TypeScript components
- GitHub Check: Publish TypeScript components
- GitHub Check: Lint Code Base
🔇 Additional comments (7)
components/blotato/actions/upload-media/upload-media.mjs (2)
1-13: LGTM!The action metadata and structure follow Pipedream conventions correctly. The key naming, version, annotations, and documentation link are all appropriate.
14-26: LGTM!The props are well-defined with helpful user guidance. The alert about the 200MB limit and the Google Drive URL format example are excellent additions for user experience.
components/blotato/blotato.app.mjs (5)
1-2: LGTM!The import and
_makeRequesthelper are well-structured. The default parameter$ = thisis a good pattern for allowing callers to optionally pass their own$context while having a sensible default.Also applies to: 8-22
37-52: LGTM!The
createVideoFromTemplatemethod is well-structured with proper$parameter handling and correct payload structure. The...argsspread is correctly placed to pass through axios options rather than adding to the request body.
53-62: LGTM!The
deleteVideomethod is correctly implemented with proper$parameter handling and appropriate use of videoId in the path. No data payload for DELETE is correct.
63-71: LGTM!The
getVideomethod is correctly implemented with proper$parameter handling and appropriate path construction. The method correctly relies on the default GET from_makeRequest.
72-84: LGTM! Previous review issue resolved.The
uploadMediamethod has been correctly updated to address the previous review feedback. It now properly sends{ url }in the request body as required by the API specification, and includes the$parameter. This fix aligns perfectly with the API documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @sergio-eliot-rodriguez lgtm! Ready for QA!
Resolves #18675
Summary by CodeRabbit
New Features
Chores