feat: append SDK analytics signature to delivery URLs#12
Open
eitanp461 wants to merge 4 commits into
Open
Conversation
Delivery URLs built by Transform operations now carry the obfuscated `?_a=` SDK-analytics signature (Algorithm B, integration code I) so Cloudinary can measure n8n usage, matching the official SDKs. The CDN strips it before delivery, so it has no effect on the asset served. - buildAnalyticsSignature / encodeAnalyticsVersion in cloudinary.utils (hand-rolled base64 packing, no runtime deps), appended by buildDeliveryUrl behind a new opt-in `analytics` flag. - New "Send Usage Analytics" credential toggle (default on, opt-out), threaded through as `creds.analytics !== false`. - Suppressed when the public_id carries a `?`, matching the SDKs. - Version bump 0.2.1 -> 0.3.0. Requires the parser to register code I (INFRA-18644) before n8n traffic is attributed on the analytics dashboard. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
eitanp461
requested review from
const-cloudinary and
sveta-slepner
as code owners
July 7, 2026 12:23
…Resize The Resize op offered every pad background to both media types, but Cloudinary's support is media-specific: b_auto and b_gen_fill are image-only, b_blurred is video-only. Resize Image wrongly offered Blurred (invalid b_blurred) and Resize Video wrongly offered Auto (invalid b_auto). Split Pad Background into two same-named `resizePadBackground` fields (one per op) so each shows only the backgrounds Cloudinary supports — Image: Black/Auto/Generative Fill/Solid Color; Video: Black/Blurred/ Solid Color. Keeping the param name identical preserves saved-workflow compatibility; only the two always-invalid combos disappear. Generative fill previously shipped only as a boolean under Crop Image, where users didn't look for it. It is really an AI pad fill (b_gen_fill,c_pad), so it now appears as a Pad Background option on Resize Image with an optional prompt, matching where users expect it. The existing Crop Image toggle is untouched for backwards compatibility. padBackgroundSuffix gains an optional gen-fill prompt arg (image op only; ignored on video). No version bump: rides the existing 0.3.0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend generative fill to Compose: Combine Transformations so a Multi-Step resize step can pad with AI-generated content, matching the standalone Resize Image op. Adds a "Generative Fill" option to the step's Pad Background plus an optional prompt field, wired through the shared padBackgroundSuffix builder (so the single-op and Multi-Step paths stay in sync). Multi-Step is a media-neutral compose surface, so it keeps offering all pad fills regardless of asset type (as it already does for b_auto and b_blurred) — media-specific gating there would be a separate change. The prompt field is placed in alphabetical displayName order within the fixedCollection so the collection sort rule does not fire (its autofix strips displayOptions in this eslint-plugin version). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The @n8n/scan-community-package check (valid-author rule) fails when the package.json author has no email. Add support@cloudinary.com so the published package passes verification. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
Hi @sveta-slepner 👋 — when you have a moment, would you mind reviewing this PR? It appends the SDK analytics signature to delivery URLs, plus a couple of follow-ups (Generative Fill pad background in the Multi-Step resize step, and gating pad backgrounds by media type). No rush — thanks so much! 🙏 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Delivery URLs built by Transform operations now carry the obfuscated
?_a=SDK-analytics signature — the same mechanism the official Cloudinary SDKs use — so Cloudinary can measure n8n usage on the SDK dashboard. The CDN strips the param before the cache key and delivery, so it has zero effect on the asset served.We emit Algorithm B (the integrations variant): a fixed 9-char token
algoVersion(B) · product(B=Integrations) · code(I=n8n) · sdkVer(3) · techVer(2) · feature(0).A real token from this node is
BBIAEsTG0→ n8n / v0.3.0 / Node 22.12.Changes
cloudinary.utils.ts—buildAnalyticsSignature+encodeAnalyticsVersion(hand-rolled standard-base64 packing, no runtime deps), appended bybuildDeliveryUrlbehind a new opt-inanalyticsflag.analytics, default on → opt-out), threaded through ascreds.analytics !== false. Credentials saved before this field still emit analytics.?(fetch / upload-mapping sources), matching the SDKs (spec "Limitations").buildAnalyticsSignature(incl. spec worked-example +Efallback) andbuildDeliveryUrlanalytics behavior;testCredsdefaults analytics off so existing URL assertions stay exact.Dependency / follow-up
Ibefore n8n traffic is attributed on the dashboard: INFRA-18644 (change staged inCloudinaryLtd/analytics, mirrors the React CLI PR #435).I → n8nrow to Confluence Appendix C.Notes
embed_url(that's the player widget, not a delivery URL) or to uploadsecure_url(server-built).🤖 Generated with Claude Code