CLI command
ugc
Customer video reviews and testimonials collected through a link, each kept with the consent its submitter agreed to and reviewed once.
Invocation#
echo-cli ugc ask --product <product-id> --prompt <what to send> --consent <consent text> --by <who>
echo-cli ugc close --id <request-id> --by <who>
echo-cli ugc collect [--request <request-id>]
echo-cli ugc approve --id <submission-id> --by <who>
echo-cli ugc reject --id <submission-id> --note <why> --by <who>Inputs and output#
ask and close write the request: id, product_id, prompt, consent_text, created_by, created_at, closed_by and closed_at, and ask also share_url, Echo Web's page where customers submit to it. collect writes { requests, submissions }: every request newest first, each with share_url, and every submission (of --request) newest first — id, request_id, submitter_name, submitter_email, media_uri (the Stado object), media_url, content_type, bytes, consent_text (as the submitter agreed to it), consented_at, reviewed_by, reviewed_at, approved and note. approve and reject write the submission.
State effect#
The verbs call Echo Web's authenticated /api/analytics/ugc with ECHO_INTERNAL_BEARER at ECHO_WEB_BASE_URL; the Customer reviews and testimonials section of the ecosystem's analytics and of Echo Desktop's GEO screen do the same and open each request's page, and echo-mcp runs them as echo_ugc, echo_ugc_ask, echo_ugc_close, echo_ugc_approve and echo_ugc_reject. Customers submit on Echo's own page for the request, /share/<request id> on Echo Web (share_url): it shows the product, the prompt and the consent text, and takes their name, email, agreement and one image or video, showing a refusal as Echo Web's sentence; a closed request's page says it takes no more, and an unknown id's page is not found. A product drawing its own form uses the request's public route instead: GET /api/public/ugc?request=<id> answers the prompt, the consent text and whether it is open, and POST takes a multipart form of name, email, consent (true) and media — an image or a video no larger than Echo Web's ECHO_UGC_MAX_BYTES — storing the media as a Stado object under echo/ugc/<request>/ and the consent text exactly as shown. Requests and submissions are kept in ugc_requests and ugc_submissions; a closed request takes nothing more.
Refusals#
- A wrong invocation is refused before anything is sent: "ugc takes ask …; close …; collect …; approve …; reject …; got <word>", "ugc <verb> does not take <flag>; it takes …", "<flag> needs a value" and "ugc <verb> needs <flag>".
- Echo Web answers a bad request with "product_id is required: …", "prompt is required: …", "consent_text is required: …", "note is required: why the submission is rejected", "request <id> was closed by <who> at <time>" or "<field>_by is required: an internal caller has no signed-in user, so it names who is acting"; not found with "no request for customer submissions has id <id>" or "no customer submission has id <id>"; and a conflict with "submission <id> was approved|rejected by <who> at <time>". The public route answers "request <id> closed at <time> and takes no more submissions", "consent must be true: the submitter agrees to \"<consent text>\"", "email must be an email address; got <value>", "media must be an image or a video; got <type>" or "media is <n> bytes, above the <limit> this deployment takes". The command prints Echo Web's sentence and exits 1.