Avvio rapido dei webhook
Collega GrowWriter al tuo sito web e ricevi il tuo primo evento di prova firmato, in una sola pagina, con un solo file di codice.
Ultimo aggiornamento il
Questa pagina ti porta da zero a Evento di prova consegnato. Un solo stack, un solo file, niente teoria. Quando la prova riesce, la guida ti mostra come salvare gli articoli che seguiranno, e il riferimento del payload elenca tutto ciò che contengono.
Questa pagina è per la persona che può aggiungere un file al tuo sito web e distribuirlo. Se non sei tu, mandale questo link; le basta un solo file. Il codice è per Next.js, la configurazione dietro la maggior parte dei siti su Vercel e Netlify. Gli altri stack sono nella guida; i passaggi di questa pagina restano gli stessi.
Connetti il webhook in GrowWriter
Apri la pagina Pubblica, cerca la scheda Webhook nel gruppo Automazione e fai clic su Connetti.
Inserisci l'indirizzo su cui risponderà il codice. Per il file qui sotto è
il dominio del tuo sito più /webhooks/growwriter, per esempio
https://www.example.com/webhooks/growwriter. Usa l'indirizzo esatto che il
tuo sito serve: se reindirizza example.com a www.example.com, inserisci
quello con www. Fai clic su Crea connessione.
La finestra ora mostra il tuo Secret di firma, una stringa che inizia
con whsec_. Fai clic su Copia secret. Viene mostrato una sola volta,
quindi tieni la finestra aperta o incollalo in un posto sicuro.
Aggiungi il file del ricevitore
Crea questo file nel tuo progetto. Legge ogni richiesta esattamente com'è arrivata, controlla che l'abbia firmata GrowWriter e risponde all'evento di prova.
import { createHmac, timingSafeEqual } from 'node:crypto';
// Una richiesta firmata più vecchia di così viene rifiutata, quindi una
// richiesta catturata non può essere rimandata più tardi.
const MAX_AGE_SECONDS = 5 * 60;
function isSignedByGrowWriter(rawBody: string, header: string, secret: string) {
// L'header ha questa forma: t=1756718400,v1=5257a869e7...
const parts = Object.fromEntries(
header.split(',').map((part) => part.split('='))
);
const age = Math.abs(Date.now() / 1000 - Number(parts.t));
if (!(age < MAX_AGE_SECONDS)) {
return false;
}
// Ricalcola l'impronta su "timestamp.corpo" con il tuo secret INTERO
// (prefisso whsec_ incluso) e confronta in tempo costante.
const expected = createHmac('sha256', secret)
.update(`${parts.t}.${rawBody}`)
.digest('hex');
const provided = Buffer.from(parts.v1 ?? '', 'hex');
const wanted = Buffer.from(expected, 'hex');
return provided.length === wanted.length && timingSafeEqual(provided, wanted);
}
export async function POST(request: Request) {
// Leggi il corpo come testo per primo. Farne il parsing prima di
// controllare la firma cambia i byte e il controllo fallisce.
const rawBody = await request.text();
const signature = request.headers.get('x-growwriter-signature') ?? '';
const secret = process.env.GROWWRITER_WEBHOOK_SECRET ?? '';
if (!isSignedByGrowWriter(rawBody, signature, secret)) {
return new Response('Invalid signature', { status: 401 });
}
const payload = JSON.parse(rawBody);
// "Invia evento di prova" manda un ping senza articolo. Rispondere 200
// è ciò che fa riuscire la prova.
if (payload.event === 'ping') {
return new Response('pong');
}
// Un articolo vero (o la sua rimozione: article.unpublished porta solo
// l'id). Per ora, dimostra solo che è arrivato; la guida mostra come
// salvarlo. Quando lo salverai, Response.json({ url }) con l'URL
// pubblico del post darà alla finestra di pubblicazione un link "Vedi
// articolo".
console.log(`${payload.event}: ${payload.article.id}`);
return new Response('OK');
}Dai il secret al tuo sito e distribuisci
Il tuo codice legge il secret da una variabile d'ambiente: un'impostazione che il tuo hosting provider conserva fuori dal codice. Nel pannello del tuo host (Vercel: Settings, poi Environment Variables) aggiungi:
GROWWRITER_WEBHOOK_SECRET=whsec_incolla_qui_il_tuo_secretIncolla il valore intero, whsec_ incluso. Poi distribuisci il tuo sito,
così che il nuovo file e la nuova variabile siano online.
Invia l'evento di prova
Torna nella finestra di GrowWriter e fai clic su Invia evento di prova.
GrowWriter firma un piccolo ping e lo invia al tuo indirizzo. Quando il tuo
file risponde, la finestra mostra Evento di prova consegnato. Fai clic
su Fatto.
Se fallisce, la finestra ne indica il motivo. I due che vedrai più probabilmente:
- L'URL del tuo endpoint reindirizza. Inserisci l'indirizzo a cui
reindirizza e riprova: il tuo sito risponde su un indirizzo diverso (di
solito
wwwcontro senzawww), e il messaggio mostra quale usare. Fai clic su Modifica URL nella riga del webhook per cambiarlo. - Il tuo endpoint ha rifiutato la consegna: con un
401, il secret sul tuo host non corrisponde; con un404, il file non si trova all'indirizzo che hai inserito.
Tutto il resto è nella pagina di risoluzione dei problemi.
Dimostra che il controllo funziona
Facoltativo, ma vale un minuto. Questo script firma un ping esattamente come fa GrowWriter e lo invia al tuo sito:
SECRET="whsec_incolla_qui_il_tuo_secret"
URL="https://www.example.com/webhooks/growwriter"
BODY='{"version":"2026-09-06","event":"ping","deliveryId":"9d2f7c1e-6a3b-4c8d-b5e0-1f2a3b4c5d6e","sentAt":"2026-09-01T09:30:00.000Z"}'
TIMESTAMP=$(date +%s)
SIGNATURE=$(printf '%s.%s' "$TIMESTAMP" "$BODY" | openssl dgst -sha256 -hmac "$SECRET" | sed 's/^.* //')
curl -X POST "$URL" \
-H "Content-Type: application/json" \
-H "X-GrowWriter-Event: ping" \
-H "X-GrowWriter-Delivery: 9d2f7c1e-6a3b-4c8d-b5e0-1f2a3b4c5d6e" \
-H "X-GrowWriter-Signature: t=$TIMESTAMP,v1=$SIGNATURE" \
--data "$BODY"Dovresti ricevere pong. Ora cambia un solo carattere dentro BODY ed
esegui di nuovo: dovresti ricevere 401. È il tuo controllo della firma che
rifiuta una richiesta manomessa, ed è esattamente lo scopo.
Cosa hai adesso
Un endpoint pubblico che accetta solo richieste firmate da GrowWriter, e una
connessione che mostra Connesso nella pagina Canali. Pubblicare un
articolo lo consegnerà a questo file come evento article.published, e la
riga console.log mostrerà il suo id nei log del tuo host.
Prossimo passo: salva l'articolo
Il file qui sopra registra soltanto l'articolo nei log. Per conservarlo, leggi Salva l'articolo nel tuo CMS nella guida: sei brevi regole su id, date, stato di pubblicazione, parole chiave, immagini ed escape, ognuna imparata da un ricevitore vero che le aveva sbagliate. Gli esempi completi di ricevitore che trovi lì le applicano tutte e sei.
Ti incuriosisce perché esistono la firma e il secret? La guida lo spiega in quattro passaggi semplici.
Pubblicare su BaseHub
Collega il tuo repository BaseHub così ogni articolo diventa una riga in una collection che il tuo sito legge già. Senza codice.
Pubblicare con i webhook
Invia ogni articolo che pubblichi in GrowWriter direttamente al tuo sito web. Configura l'integrazione webhook passo dopo passo, con codice pronto all'uso.