Skip to content

Add multi client video automation example - #15

Open
musab123-afk wants to merge 3 commits into
masterfrom
add-multi-client-video-automation-example
Open

Add multi client video automation example#15
musab123-afk wants to merge 3 commits into
masterfrom
add-multi-client-video-automation-example

Conversation

@musab123-afk

Copy link
Copy Markdown
Collaborator

Companion code for A guide to automating video content production for multiple clients (https://shotstack.io/learn/automating-video-production-multiple-clients/) — the live article already links this directory, so its GitHub link 404s until this merges. One master template renders branded promos for three clients in three aspect ratios; renders.jsonl records which render belongs to which client, since the API has no endpoint that lists renders.

Gated live twice (including from a fresh clone following the README verbatim): template created, 9/9 submitted, all nine done with URLs. A wrong key prints one-line errors and exits non-zero. Second commit addresses code review: the API base derives from SHOTSTACK_ENV (stage default, v1 for production) instead of hand-editing two files, status.mjs catches network failures with one line instead of a stack trace, and API errors reduce to their message across both response shapes. Prettier passes.

Companion code for the "A guide to automating video content
production for multiple clients" guide: one master template renders
branded promos for three clients in three aspect ratios, with a
JSON-lines file recording which render belongs to which client. The
live article already links this directory.
Derive the API base from SHOTSTACK_ENV (stage default, v1 for
production) instead of hand-editing two files, catch network failures
in status.mjs so they print one line instead of a stack trace, and
widen apiError to the {success, message, response} error shape.
@vercel

vercel Bot commented Sep 1, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
reelestate Ignored Ignored Preview Sep 9, 2026 11:45am UTC

@dazzatronus dazzatronus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — STANDARDS.md must be followed

Public cookbook code must match STANDARDS.md and examples/_template/. Product teaching is solid; blocking on standards/correctness gaps.

Blockers (STANDARDS)

  1. .env.example incomplete — example requires SHOTSTACK_TEMPLATE_ID and optionally SHOTSTACK_ENV. Document each with empty value + comment/URL above the line (same pattern as SHOTSTACK_API_KEY).
  2. README template curl hardcodes edit/stage while the scripts honor SHOTSTACK_ENV. STANDARDS: every command in the README must stay correct. Use the same env in the curl URL (or say explicitly: create the template in the same environment as SHOTSTACK_ENV).
  3. README shape / STE — prefer _template’s Related guide: line; keep instructions ≤20 words and descriptions ≤25.

Already good

  • Lean core (clients → merge → JSONL → status)
  • Concurrent append rationale in db.mjs
  • Second commit: SHOTSTACK_ENV, network errors, clearer API errors
  • No stack traces on the happy failure paths

Re-run the STANDARDS pre-PR checklist after fixes.

@@ -0,0 +1,2 @@
# https://dashboard.shotstack.io/register
SHOTSTACK_API_KEY=

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STANDARDS — API keys: also document SHOTSTACK_TEMPLATE_ID (required) and SHOTSTACK_ENV (optional, stage|v1) with empty values and a comment above each. Empty placeholders so a missing var fails with your message, not a vague API error.

```bash
curl --fail-with-body \
--request POST \
"https://api.shotstack.io/edit/stage/templates" \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STANDARDS — correct commands: this curl always hits edit/stage, but render.mjs / status.mjs use SHOTSTACK_ENV. Point the curl at the same environment (or state that the template must be created in that env). Wrong-env template ids are a common footgun.

footage, music and brand mark. A JSON-lines file records which render belongs to which client,
because the API has no endpoint that lists renders.

Companion code for [A guide to automating video content production for multiple clients](https://shotstack.io/learn/automating-video-production-multiple-clients/).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

STANDARDS — README: match examples/_template (Related guide: …) and Simplified Technical English sentence limits.

@dazzatronus dazzatronus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow-up from a STANDARDS / correctness pass:

  1. Footage URLsclients.mjs uses shotstack-ingest-api-v1-sources/.../35tqpmb0ya/... paths. They respond 200 today, but ingest-owner prefixes are fragile for a public example. Prefer durable shotstack-assets (or other documented public) URLs so a fresh clone still renders months later.
  2. WIDTH / HEIGHT merge types — template uses "{{ WIDTH }}" / "{{ HEIGHT }}" strings; mergeFieldsFor currently passes numbers. Stringify the replaces so merge stays string-in/string-out.
  3. render.mjs network errors — align with status.mjs: one actionable line + non-zero exit (STANDARDS failures section), not a raw fetch rejection message via allSettled.
  4. db.mjs all() — don’t swallow corrupt JSONL as []; fail with one line so a bad notebook isn’t silently empty.

Still blocked on the earlier STANDARDS items (.env.example, stage-hardcoded template curl, README/STE).

headline: 'Twelve new listings this week.',
font: 'Montserrat',
footage:
'https://shotstack-ingest-api-v1-sources.s3.ap-southeast-2.amazonaws.com/35tqpmb0ya/zzz01m08-qxa25-864e6-zty3t-3sttne/source.mp4',

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer public durable assets (e.g. shotstack-assets) over ingest-bucket owner-prefixed URLs. Fresh clones must keep working after the source account rotates media.

{ find: 'BRAND_MARK', replace: client.brandMark },
{ find: 'FOOTAGE', replace: client.footage },
{ find: 'MUSIC', replace: client.music },
{ find: 'WIDTH', replace: variant.width },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Template placeholders are strings ("{{ WIDTH }}"). Pass String(variant.width) / String(variant.height) (or template literals) so merge replace values stay strings.

.env.example documents SHOTSTACK_TEMPLATE_ID and SHOTSTACK_ENV with empty
values and a comment above each. Scripts use || so an empty SHOTSTACK_ENV in
.env falls back to stage.

README follows the _template shape (Related guide line, five sections) and
STE sentence limits. The template curl targets ${SHOTSTACK_ENV:-stage} so it
creates the template in the same environment the scripts use, and the setup
adds the copy-id-then-reload step.

clients.mjs points footage at durable shotstack-assets URLs instead of
ingest-bucket owner-prefixed paths, and passes WIDTH/HEIGHT as strings to
match the string placeholders in the template.

render.mjs turns network failures and 401/403 into one actionable line per
variant with a 30 s timeout and exits non-zero when the notebook cannot be
written. db.mjs returns [] only when renders.jsonl does not exist and fails
with one line on a corrupt line; status.mjs reports that and exits 1, and
says what to do when no renders are recorded yet.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants