Nyhetsbrev
På Zkrinet: lägg till blocket under Byggblock i panelen — ett klick, din egen kod rörs inte och en ögonblicksbild tas först. Installationsstegen nedan gäller om du kör PocketBase själv, till exempel efter en export.
Prenumerationslista med dubbel opt-in, avregistrering med ett klick i varje utskick, och utskick i omgångar från adminpanelen. Inga externa tjänster — mejlen går via din egen SMTP.
Kräver Mejl-pluginet. Testat mot PocketBase 0.40.4.
#Installation
- Installera Mejl först (och ställ in SMTP), kopiera sedan
pb_hooks/ochpb_migrations/till din PocketBase och starta om. - Kontrollera Settings → Application URL — länkarna i mejlen byggs på den (
https://din-pb.se/api/zk/nyhetsbrev/...). zk_nyhetsbrev_installningarhar redan en rad:per_timme(anmälningar per IP och timme, standard 5),omgang(mejl per omgång, standard 50) ochhemlighet(skapas automatiskt, dold). Hemligheten kan i stället sättas med miljövariabelnZK_NYHETSBREV_HEMLIGHET.- Bakom en proxy (Cloudflare, nginx)? Ställ in Settings → Trusted proxy, annars delar alla besökare samma gräns.
- Mejlmallarna
nyhetsbrev_bekraftaochnyhetsbrev_redanfinns izk_mejlmallaroch kan redigeras där.
#Anmälan från din sajt
await fetch("https://din-pb.se/api/zk/nyhetsbrev/prenumerera", {
method: "POST", headers: { "Content-Type": "application/json" },
body: JSON.stringify({ epost: "anna@exempel.se" }),
})
// 200 { ok: true, meddelande: "Om adressen är giltig får du strax ett mejl…" } · 400 ogiltig adress · 429 för många försök
Eller utan JavaScript:
<form method="post" action="https://din-pb.se/api/zk/nyhetsbrev/prenumerera">
<input name="epost" type="email" required placeholder="din@adress.se">
<button>Prenumerera</button>
</form>
Så går det till:
- Anmälan → raden skapas med
status = vantaroch ett bekräftelsemejl skickas. - Länken i mejlet öppnar en sida med en knapp. Ingenting bekräftas förrän man trycker — mejlskannrar (Outlook, Gmail, företagsfilter) öppnar länkar men trycker inte på knappar. Länken gäller i 7 dagar och fungerar en gång.
- Knappen →
status = bekraftad. Först nu får adressen utskick.
#Skicka ett utskick
- Skapa en rad i
zk_nyhetsbrev_utskick:amne,innehall(HTML, redigeraren i adminpanelen), valfritttext(ren textversion — annars görs en av HTML:en),status = utkast. - Starta (superuser, t.ex. från adminverktyg eller curl):
POST /api/zk/nyhetsbrev/skicka/{id}
→ { status: "skickas", skickade_nu: 50, antal: 50, fel: 0 }
Första anropet skickar en omgång. Resten skickas automatiskt, en omgång i minuten (cron). Anropa igen om du vill köra nästa omgång direkt. När alla är klara blir status = skickat; ett skickat utskick kan inte skickas igen (409).
Varje mottagare får en rad i zk_nyhetsbrev_leveranser (skickat / fel). En unik nyckel på (utskick, prenumerant) gör att samma brev aldrig går två gånger till samma adress, även om cron och ett manuellt anrop kör samtidigt. Misslyckas ett mejl (t.ex. SMTP nere) avbryts omgången och mottagaren tas igen nästa omgång, högst 3 försök.
Varje utskick får automatiskt en sidfot med avregistreringslänk — den går inte att glömma. I innehållet kan du använda {{app}} (appnamnet) och {{avregistrera}} (länken) om du vill ha den på fler ställen. Innehållet låses när utskicket startar: ändrar du det under tiden får alla ändå samma brev.
#Avregistrering
Länken i varje utskick avregistrerar direkt med ett klick och fungerar hur många gånger som helst (idempotent). Den är signerad med serverns hemlighet (HMAC), så ingen kan avregistrera någon annan genom att gissa id:n. POST mot samma adress fungerar också, enligt RFC 8058 (one-click).
Den som anmäler sig igen efter att ha avregistrerat sig måste bekräfta på nytt.
#Säkerhet och integritet
- Ingen uppräkning: prenumerera svarar alltid exakt likadant för en giltig adress — ny, väntande, bekräftad eller avregistrerad. Den som redan prenumererar får i stället ett mejl om att ingenting ändrats (med avregistreringslänk), så att varje fall skickar ett mejl och tar ungefär lika lång tid.
- Mejlbombning: högst ett mejl per adress och tio minuter från anmälan, oavsett hur många gånger någon trycker. Plus rate limit per IP.
- Bekräftelse-token sparas bara som SHA-256-hash och nollas när den använts. Läcker databasen går det inte att bekräfta någon med den.
- Avregistreringslänkarna sparas inte alls — de räknas fram med HMAC. Byter du
hemlighetslutar alla gamla avregistreringslänkar att fungera (och nya mejl får nya). - IP sparas aldrig. Räknaren lagrar en hash av hemlighet + IP + timme och raderas efter en till två timmar. IP behandlas ändå tillfälligt — nämn det i din integritetspolicy.
- Alla samlingar är bara läsbara för superusers. Gäster och inloggade användare kan inte se listan; bara superusers kan skicka.
- Samtycke:
bekraftad(tid) är ditt bevis på när adressen bekräftades. Avregistrerade rader ligger kvar medavregistrerad(tid) så att de inte får fler utskick; radera raden om personen vill bli helt borttagen (leveransloggen raderas med).
#Begränsningar
- Varje utskick har
List-UnsubscribeochList-Unsubscribe-Post: List-Unsubscribe=One-Click(RFC 8058) — Gmails och Yahoos avregistreringsknapp fungerar. Kräver att appens adress (Application URL) är https; annars sätts huvudena inte (länken i sidfoten finns alltid). Gmail/Yahoo kräver också SPF/DKIM/DMARC för din avsändardomän — det sköts i din SMTP/DNS, inte här. - Avregistrering med ett klick betyder att en mejlskanner som öppnar alla länkar kan råka avregistrera någon. Vi valde det framför en extra knapp: att avregistrera ska vara lätt, och ett felaktigt avregistrerat är det ofarliga felet.
- Svarstiden är ungefär lika i alla fall, inte exakt — mejlet skickas medan anropet väntar. Den som mäter tider noga mot en långsam SMTP kan möjligen se skillnad mellan fallen. Svaret i sig är identiskt.
- Ingen segmentering, inga listor, ingen statistik över öppningar eller klick (och inga spårningspixlar).
- Takten är
omgangmejl per minut. Din SMTP-leverantör har egna gränser — sättomgangdärefter. - Kraschar servern mitt i ett mejl kan en mottagare bli kvar som
skickaroch hoppas över (hellre ett missat mejl än ett dubbelt).
#Testa
./bank.py nyhetsbrev
18 tester mot bänkens SMTP-fälla (inget når internet): dubbel opt-in med knapp, token hash-lagrad/engångs/utgången, ingen uppräkning, paus mot mejlbombning, skiftlägesokänslig unik adress, utskick bara till bekräftade, omgångar utan dubbletter, avregistrering (ett klick, idempotent, RFC 8058-POST, förfalskad länk nekas), ny anmälan kräver ny bekräftelse, behörighet, rate limit och SMTP-avbrott mitt i ett utskick. Säkerhetstesterna är mutantverifierade.