Lewati ke konten

Webhook: kabar otomatis dari Posto

Terakhir diperbarui

Di artikel ini

Webhook membuat Posto mengirim kabar ke server atau alat otomasi (mis. n8n) setiap kali sesuatu terjadi, misalnya carousel selesai atau posting terbit. Webhook ada di halaman yang sama dengan API key, jadi butuh akses API & MCP. Lihat API dan MCP.

Menambah webhook

  1. Buka Brand & akun medsos → API & MCP (/app/settings/api), bagian Webhook, lalu klik Tambah webhook.
  2. Isi URL endpoint. Wajib https:// dan alamat publik; alamat privat atau internal (mis. localhost atau 192.168.x.x) ditolak. Pilih Event, lalu klik Tambah webhook.
  3. Klik Salin rahasia untuk menyimpan rahasia penanda tangan (whsec_…). Rahasia hanya tampil sekali.
  4. Klik Kirim ping untuk mengetes. Hasilnya muncul di Riwayat.

Event yang bisa dipilih: carousel.ready, carousel.failed, image.ready, post.published, post.failed, credits.low, approval.decided, series.paused (jadwal berulang dijeda), dan series.ended (jadwal berulang selesai atau diakhiri). Maksimal 10 webhook per workspace.

Isi kiriman

Posto mengirim POST JSON seperti ini:

{
  "id": "b2f6c1e0-…",
  "type": "post.published",
  "createdAt": "2026-10-17T12:30:41Z",
  "workspaceId": "0b6e2d14-…",
  "apiVersion": "v1",
  "data": { "scheduleId": "…", "carouselId": "…", "platform": "instagram", "permalink": "…" }
}

Header yang ikut: X-Posto-Event, X-Posto-Delivery, X-Posto-Timestamp (detik Unix), dan X-Posto-Signature. Balas 2xx dalam 10 detik; redirect tidak diikuti. Kiriman yang sama bisa datang lebih dari sekali, jadi abaikan id event yang sudah pernah diproses.

Memverifikasi tanda tangan

X-Posto-Signature berisi v1=<hex>: HMAC-SHA256 dengan rahasia webhook atas teks <X-Posto-Timestamp>.<raw body>.

  1. Ambil raw body persis seperti diterima. Jangan di-parse lalu diubah lagi jadi teks.
  2. Tolak kiriman bila selisih X-Posto-Timestamp dengan jam server lebih dari 5 menit (300 detik).
  3. Hitung HMAC, lalu bandingkan dengan setiap v1= di header memakai perbandingan waktu-konstan (timingSafeEqual).

Contoh Node.js (Express):

import crypto from 'node:crypto'
import express from 'express'

const app = express()
const SECRET = process.env.POSTO_WEBHOOK_SECRET // whsec_...

app.post('/webhook/posto', express.raw({ type: 'application/json' }), (req, res) => {
  const ts = req.get('X-Posto-Timestamp') || ''
  const header = req.get('X-Posto-Signature') || ''
  const raw = req.body // Buffer: raw body, not parsed

  if (!/^[0-9]+$/.test(ts) || Math.abs(Date.now() / 1000 - Number(ts)) > 300) {
    return res.status(400).send('stale')
  }
  const expected = crypto.createHmac('sha256', SECRET).update(ts + '.').update(raw).digest()
  const ok = header.split(',').some((part) => {
    const m = /^v1=([0-9a-f]{64})$/.exec(part.trim())
    return m !== null && crypto.timingSafeEqual(Buffer.from(m[1], 'hex'), expected)
  })
  if (!ok) return res.status(401).send('bad signature')

  const event = JSON.parse(raw.toString('utf8'))
  res.status(200).end() // reply fast, process event.id in the background (skip ids already seen)
})

Gagal kirim, dimatikan, dan rotasi rahasia

  • Kiriman yang gagal diulang 6 kali (1 menit, 5 menit, 30 menit, 2 jam, 8 jam, 24 jam). Setiap percobaan tercatat di Riwayat.
  • Bila 3 kiriman berturut-turut gagal dan kegagalan berlangsung 3 hari, webhook dimatikan otomatis dan pemilik serta admin workspace menerima email. Perbaiki endpoint, lalu klik Nyalakan lagi.
  • Rotasi rahasia (di menu aksi lain) membuat rahasia baru. Selama 24 jam header memuat dua tanda tangan (v1=<baru>,v1=<lama>), jadi kamu punya waktu mengganti rahasia di server.

Masih bingung? Hubungi [email protected].

Apakah artikel ini membantu?

Belum ketemu jawabannya?

Tim support siap membantu. Sebutkan judul carousel atau jam kejadian supaya kami cepat menemukannya.

[email protected]

Kembali ke API & integrasi