Mailbox API for mailcow — instalare și ghid API

Instalare

  1. Modulul vine în mailcow Toolkit 0.5.0 sau mai nou (un singur pachet, o licență per produs). Pe serverul mailcow, ca root, rulează instalatorul Toolkit ca de obicei: sudo ./install.sh --mailcow-dir /opt/mailcow-dockerized --name <instanță>. Copiază data/web/mlw-mailbox-api/, adaugă intrarea din meniu, sarcina agentului și cron-ul la fiecare minut și reîncarcă php-fpm.
  2. Deschide System → Mailbox API în meniul de administrare mailcow. Pagina arată bara de licență și, dedesubt, setările.

Licență

Deschide System → Updates (Toolkit) și caută cardul Mailbox API for mailcow: lipește cheia și activeaz-o, sau pornește proba de 30 de zile. Din shell, același lucru: php /web/mlw-toolkit/cli.php activate mailcow-mailbox-api <CHEIE> în php-fpm-mailcow. Licența se verifică zilnic; fără internet, modulul merge 7 zile de la ultima verificare reușită.

Fără licență validă, API-ul răspunde 503 not_licensed, cron-ul nu trimite nimic, iar pagina spune că lipsește licența. Nimic nu se șterge.

Setări

În System → Mailbox API:

  • API pornit: pornește sau oprește API-ul (licența se verifică oricum).
  • Adresa publică a API-ului: adresa folosită în linkurile semnate de atașamente, de exemplu https://mail.exemplu.ro/mlw-mailbox-api/. Gol = se ia din pagină.
  • Mesaje pe pagină (1–200) și atașamentul maxim (1–100 MB).
  • Token bot Telegram: de la @BotFather; se păstrează criptat (se arată doar ultimele patru caractere). Un bot deservește toate cutiile.
  • Utilizator master dovecot (opțional): doar dacă ai setat unul propriu în mailcow.conf; implicit modulul citește datele master pe care mailcow le creează la pornire.

Chei API

În cardul Chei API: dă cheii un nume, bifează drepturile — citire, trimitere, organizare — alege cutiile în care are voie să lucreze și apasă Creează cheia. Cheia (mbx_…) se arată o singură dată; păstreaz-o. Lista arată prefixul, drepturile, cutiile și ultima folosire; Revocă o oprește imediat. În baza de date se păstrează doar SHA-256.

Se trimite la fiecare apel:

Authorization: Bearer mbx_…

Referința API

Toate rutele se apelează pe https://<gazda mail>/mlw-mailbox-api/?r=<ruta> (nginx-ul mailcow nu are PATH_INFO, deci ruta stă în query string). Răspunsurile sunt JSON. Toate rutele, în afară de linkul semnat de atașament, cer cheia, iar cheia trebuie să permită cutia și dreptul.

Metodă și rută Drept Ce face
GET /v1/me oricare Numele cheii, drepturile, cutiile, limitele
GET /v1/mailboxes oricare Cutiile permise, numărul de foldere și UIDNEXT al INBOX
GET /v1/folders&mailbox=… citire Numele folderelor
GET /v1/messages&mailbox=…&folder=INBOX&limit=20&offset=0&q=…&unseen=1 citire Lista mesajelor (cele mai noi primele): uid, subiect, de la, către, dată, mărime, citit
GET /v1/messages/{uid}&mailbox=…&folder=… citire Mesajul complet: text, HTML, antete, atașamente (nume, tip, mărime, link semnat)
POST /v1/messages/{uid}/read corp {"read":true} organizare Marchează citit sau necitit
POST /v1/messages/{uid}/move corp {"folder":"Archive"} organizare Mută în alt folder
DELETE /v1/messages/{uid}&mailbox=…&folder=… organizare Șterge (cu expunge)
POST /v1/send&mailbox=… corp {"to":"a@b.c","subject":"…","text":"…"} trimitere Trimite ca acea cutie (cc, bcc, html, reply_to); o copie merge în Sent
GET /v1/attachments&…&t=… link semnat Descarcă un atașament

Exemple:

curl -H "Authorization: Bearer $KEY" \
  "https://mail.exemplu.ro/mlw-mailbox-api/?r=/v1/messages&mailbox=office@exemplu.ro&limit=5&unseen=1"

curl -X POST -H "Authorization: Bearer $KEY" -H 'Content-Type: application/json' \
  -d '{"to":"client@exemplu.org","subject":"Factura ta","text":"Atașat."}' \
  "https://mail.exemplu.ro/mlw-mailbox-api/?r=/v1/send&mailbox=office@exemplu.ro"

Erorile sunt JSON cu status HTTP: 401 cheie lipsă sau greșită, 403 cheia nu are dreptul pe cutia aceea, 404 rută sau mesaj necunoscut, 422 date invalide, 429/502 limite sau eroare de server.

Webhook-uri

În cardul Cutii monitorizate adaugă o cutie, folderul de urmărit (implicit INBOX), o adresă https de webhook și, opțional, id-ul chatului Telegram. Modulul caută la fiecare minut mesaje noi (UIDNEXT pe folder; prima rulare doar stabilește punctul de pornire, nu retrimite poșta veche).

Fiecare mesaj nou produce un POST JSON:

{
  "event": "message.received",
  "mailbox": "office@exemplu.ro",
  "folder": "INBOX",
  "uid": 1234,
  "received_at": "2026-10-18T06:12:00+00:00",
  "message": {
    "message_id": "…", "date": "…", "from": "Facturare <facturare@exemplu.com>", "to": "…", "cc": "",
    "subject": "Factura 42", "size": 12345, "text": "…", "html": "…", "headers": {"…": "…"},
    "attachments": [{"name": "factura.pdf", "type": "application/pdf", "size": 23112,
      "sha256": "…", "url": "https://mail.exemplu.ro/mlw-mailbox-api/?r=/v1/attachments&…&t=…"}]
  }
}

Verifică semnătura înainte de a folosi corpul:

X-MLW-Signature: t=1792300000,v1=<HMAC-SHA256 hex(secret, "t.body")>
X-MLW-Event: message.received

Compară cu secretul tău (fiecare monitor are al lui, generat la prima folosire: pagina îl arată la creare și cu butonul Secret) și refuză timestamp-urile mai vechi de cinci minute. Livrările eșuate se reîncearcă după 30 s, 1 min, 2 min … până la cinci încercări; cardul Livrări recente arată starea și răspunsul. Livrările stau în coadă în baza de date și pleacă din cron-ul de la fiecare minut.

Telegram

Lipește tokenul botului la Setări, apoi pune id-ul chatului (un utilizator, un grup sau un canal; botul trebuie să fie membru, iar la canale administrator) pe fiecare cutie monitorizată. Butonul Telegram de lângă o cutie trimite un mesaj de test. Notificarea arată expeditorul, subiectul și primele 400 de caractere din text.

Dacă nu merge

  • 503 not_licensed: activează licența (System → Updates (Toolkit)); fără internet modulul merge 7 zile de la ultima verificare.
  • 502 server_error cu „no dovecot master credentials”: mailcow n-a creat /etc/sogo/sieve.creds; verifică faptul că dovecot-mailcow și sogo-mailcow rulează, sau setează manual utilizatorul și parola master.
  • 403 not_allowed: cheia nu acoperă cutia aceea sau nu are dreptul; fă o cheie nouă din pagina de administrare.
  • Nu vine niciun webhook: verifică faptul că monitorul e activ, adresa e https și răspunde 2xx, și uită-te la Livrări recente; cron-ul rulează la fiecare minut (systemctl status mlw-mailcow-mailapi-<nume>.timer).
  • Nu vine poșta veche după ce adaugi un monitor: intenționat, prima rulare doar notează poziția curentă; de atunci încolo sosește poșta nouă.

Descărcarea necesită o licență sau perioada de probă gratuită de 30 de zile.