Automated daily news digest with a QA-in-the-loop.
Pipeline: RSS scrape -> GPT-4o summarize -> human QA (edit/approve/reject) -> daily email with the top 10 approved stories to every active subscriber.
index.html,styles.css,app.js- dashboard with Compose, Review queue, Scraper, and History views.supabase/schema.sql- subscribers, articles (with status workflow), per-recipient delivery log, digest log.supabase/cron.sql- pg_cron schedule for scrape / summarize / send.supabase/functions/scrape-news- pulls RSS feeds, dedupes by URL, insertspendingrows.summarize-articles- calls GPT-4o on pending rows, ranks top 50, promotes tosummarized.list-articles- feeds the QA dashboard (?status=summarized|approved|rejected|sent).review-article- acceptsapprove | reject | editactions from the dashboard.send-daily-digest- picks top 10 approved articles, renders one polished HTML email, fans out via Amazon SES (or Brevo fallback), logs deliveries, markssent.corporate-case-agent- selects one source-backed Indian company case from the last five days and drafts the 400-600 word Corporate Case format for editor review.editorial-topic-agent- builds Real Estate, Policy Partner, Money Matters, and Wellness drafts with topic-specific sources, formats, safety rules, and editor checklists.send-article- legacy single-article send (still works for manual one-offs).
src/scraper-adapter.ts- adapter for external scrapers that already produce a finished payload.
pending -> summarized -> approved -> sent
\-> rejected
- Copy
.env.exampleto.envand fill in real values. - Run
supabase/schema.sqlin the Supabase SQL editor. - Set function secrets:
supabase secrets set SUPABASE_URL="..." SUPABASE_SERVICE_ROLE_KEY="..." \ AWS_REGION="ap-south-1" AWS_ACCESS_KEY_ID="..." AWS_SECRET_ACCESS_KEY="..." \ SHORTLY_AGENT_SHARED_TOKEN="YOUR_SHARED_LOGIN_TOKEN" \ FROM_EMAIL="Shortly Dailywrap <dailywrap@shortlyindia.com>" \ OPENAI_API_KEY="..." OPENAI_MODEL="gpt-4o"
- Optional fallback while testing:
supabase secrets set SMTP_PASS="YOUR_BREVO_API_KEY"
- Deploy functions:
supabase functions deploy scrape-news summarize-articles list-articles review-article send-daily-digest send-article corporate-case-agent editorial-topic-agent
- Edit
supabase/cron.sql- replace<PROJECT_REF>and<SERVICE_ROLE_KEY>- then run it in the SQL editor. - In
index.html(or your hosting layer), inject the endpoints beforeapp.js:<script> window.SHORTLY_LIST_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/list-articles"; window.SHORTLY_REVIEW_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/review-article"; window.SHORTLY_DIGEST_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/send-daily-digest"; window.SHORTLY_SCRAPE_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/scrape-news"; window.SHORTLY_SUMMARIZE_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/summarize-articles"; window.SHORTLY_EMAIL_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/send-article"; window.SHORTLY_CORPORATE_CASE_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/corporate-case-agent"; window.SHORTLY_EDITORIAL_TOPICS_ENDPOINT = "https://YOUR_PROJECT.functions.supabase.co/editorial-topic-agent"; window.SHORTLY_REVIEWER = "qa-username"; </script>
- The dashboard now expects a shared token before it unlocks.
- It accepts the token either:
- in the URL as
?token=... - or via
window.postMessage({ type: "shortly-agent-token", token })
- in the URL as
- The token is verified by the
verify-agent-tokenEdge Function usingSHORTLY_AGENT_AUTH_SECRET. - The accepted token format is
base64url(payload).base64url(hmac_sha256(payload, secret)). SHORTLY_AGENT_SHARED_TOKENis still supported as an optional legacy fallback.- After successful verification, the dashboard stores the token locally and reuses the session on later visits.
- Verify your sending domain in Amazon SES before switching live traffic.
- Request production access in SES, otherwise you stay in sandbox mode.
- The shared mailer now prefers SES automatically when
AWS_REGION,AWS_ACCESS_KEY_ID, andAWS_SECRET_ACCESS_KEYare present. - If those AWS variables are missing, it falls back to Brevo using
SMTP_PASS.
| Time | Job | Function |
|---|---|---|
| 07:00 | Scrape sources | scrape-news |
| 07:30 | Summarize w/ GPT-4o | summarize-articles |
| 15:00 | Send approved digest | send-daily-digest |
QA window: 07:30-15:00 UTC. Adjust to your team's timezone in cron.sql.
Open the dashboard -> Review queue. For each summarized article you can:
- Edit the summary inline -> Save
- Approve
- Reject
Top of the panel has Run scrape, Summarize, and Send buttons for manual runs.
Configured in supabase/functions/_shared/sources.ts.
Corporate Case sources are configured separately in supabase/functions/_shared/corporate-case-sources.ts: The Ken, Inc42, Moneycontrol business reporting, and ET Prime. The weekday cron runs at 10:00 IST and stores each generated draft in corporate_cases for editor review.
The additional editorial topics are configured in supabase/functions/_shared/editorial-topics.ts. Real Estate and Money Matters use the five-brief-plus-feature hybrid; Policy Partner and The Wellness Daily use the 100-word summary plus 300-500-word detail structure. They run Monday-Saturday on staggered schedules and store drafts in editorial_drafts.