RO

Tema

Culoarea de accent

Tema și culoarea te urmează pe satelit.md și în aplicație.

Panou Alege un plan

Digest legislativ

În fiecare dimineață, ce s-a publicat în Monitorul Oficial, pe temele și emitenții care te interesează. Un fișier HTML gata de trimis pe e-mail.

Cum funcționează

  1. Află ce zile au digest, din /v1/law/digests.
  2. Ia digestul celei mai noi zile.
  3. Filtrează actele pe temele și emitenții tăi. Actele importante merg primele.
  4. Scrie digest-YYYY-MM-DD.html, cu linkuri spre pagina oficială a fiecărui act.

Cât costă: 2 credite pentru listă, 2 pentru digest: 4 credite pe zi, 120 pe lună. Încape în planul Start. De la planul Creator poți primi evenimentul law.digest în loc să întrebi.

Cum îl rulezi

bash
export SATELIT_KEY=sat_live_...
TOPICS=business,justice ISSUERS=guvernul node law_digest.mjs

Ce scoate

stdout
digest-2026-10-31.html: 6 of 20 acts, 4 credits

Scriptul complet

law_digest.mjs
#!/usr/bin/env node
// Law digest: what Monitorul Oficial published, on your topics and issuers, as an HTML file ready to e-mail.
//   SATELIT_KEY=sat_live_... TOPICS=taxes,business ISSUERS=guvernul node law_digest.mjs
// No dependencies, Node 18 or newer. Put it in cron: 0 8 * * 1-6 node /path/law_digest.mjs
import { writeFileSync } from "node:fs";

const BASE = process.env.SATELIT_BASE ?? "https://api.satelit.md/v1";
const KEY = process.env.SATELIT_KEY;
const LANG = process.env.DIGEST_LANG ?? "ro";
const TOPICS = (process.env.TOPICS ?? "").split(",").filter(Boolean);
const ISSUERS = (process.env.ISSUERS ?? "").split(",").filter(Boolean);
if (!KEY) throw new Error("Set SATELIT_KEY");

async function api(path, params = {}) {
  const url = new URL(BASE + path);
  for (const [k, v] of Object.entries({ lang: LANG, ...params })) url.searchParams.set(k, v);
  const res = await fetch(url, { headers: { Authorization: `Bearer ${KEY}` } });
  const body = await res.json();
  if (!res.ok) throw new Error(`${path}: ${body.error.code}: ${body.error.message}`);
  return body;
}

const esc = (s = "") => String(s).replace(/[&<>"]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;" })[c]);

const days = await api("/law/digests", { days: 7 });
if (!days.data.length) {
  console.log("No digest in the last 7 days");
  process.exit(0);
}
const { date } = days.data[0];
const digest = await api(`/law/digests/${date}`);

const wanted = (act) =>
  (!TOPICS.length || TOPICS.includes(act.topic)) && (!ISSUERS.length || ISSUERS.includes(act.issuer_key));
const acts = digest.data.items.filter(wanted).sort((a, b) => Number(b.important) - Number(a.important));

const rows = acts.map((a) =>
  `<li${a.important ? ' style="font-weight:600"' : ""}><a href="${esc(a.url)}">${esc(a.heading)}</a><br><small>${esc(a.issuer_name)}, ${esc(a.mo_ref)}</small></li>`,
);
const html = `<!doctype html><html lang="${LANG}"><meta charset="utf-8"><title>${esc(digest.data.title)}</title>
<h1>${esc(digest.data.title)}</h1><p>${esc(digest.data.intro ?? "")}</p>
<ul>${rows.join("\n") || "<li>0</li>"}</ul>
<p><small>${esc(digest.meta.attribution ?? "")}</small></p></html>\n`;

const file = `digest-${date}.html`;
writeFileSync(file, html);
console.log(`${file}: ${acts.length} of ${digest.data.items.length} acts, ${days.meta.credits + digest.meta.credits} credits`);