Webhook (JSON)

Kirim setiap respons Google Forms sebagai JSON bertanda tangan ke endpoint Anda sendiri, Zapier, Make, atau n8n, dan verifikasi tanda tangannya

Aturan Webhook mengirim (POST) setiap respons yang cocok sebagai JSON ke URL yang Anda berikan. Gunakan untuk mengisi CRM, alat spreadsheet, server Anda sendiri, atau platform otomasi seperti Zapier, Make, atau n8n.

Membuat aturan webhook

  1. Klik + Aturan baru dan pilih Webhook
  2. Saat: biarkan Setiap jawaban, atau pilih Hanya setelah disetujui / Saat ditolak dan tetapkan pemberi persetujuan. Tambahkan kondisi Hanya jika untuk mengirim hanya respons yang cocok
  3. Kepada: tempel URL endpoint Anda (hanya HTTPS). Tidak ada langkah Pesan: aturan mengirim payload JSON tetap. Lihat payload di bawah URL menampilkannya dengan pertanyaan formulir Anda, siap disalin
  4. Klik Buat aturan, lalu salin rahasia tanda tangan yang ditampilkan sekali (lihat di bawah)

Kirim uji mengirim payload contoh bertanda tangan ke endpoint dan menampilkan status HTTP yang dikembalikan. URL yang tersimpan disimpan terenkripsi dan ditampilkan tersamar; klik Ganti untuk menempel URL baru.

Payload

Setiap permintaan adalah POST, Content-Type: application/json, dengan body berikut:

{
  "version": 1,
  "event": "submitted",
  "form": { "id": "1AbC...", "name": "Workshop sign-up" },
  "response": {
    "id": "a3f1...",
    "submittedAt": "2026-01-31T09:30:00.000Z",
    "respondentEmail": "respondent@example.com",
    "answers": [
      { "questionId": "q1", "title": "Your name", "value": "Ada Lovelace" },
      { "questionId": "q3", "title": "Department", "value": "Ops" }
    ]
  },
  "rule": { "id": "rule id", "name": "Zapier: new lead" }
}
  • event adalah salah satu dari submitted, approved, rejected; nilainya juga dikirim di header X-Skyfield-Event
  • response.respondentEmail bernilai null kecuali formulir mengumpulkan alamat email
  • answers[].value selalu berupa string; jawaban kotak centang digabung dengan ,
  • rule.id dan rule.name mengidentifikasi aturan yang terpicu; name bernilai null jika aturan tidak diberi nama
  • Pada approved dan rejected, disertakan tambahan approval: { "decision": "approved", "decidedBy": "Dana" }. decidedBy adalah nama yang diketik pemberi persetujuan di halaman persetujuan, jika tidak ada maka email pemberi persetujuan, atau null.

version tetap 1 selama bentuk di atas stabil. Kolom baru mungkin ditambahkan; tidak ada yang dihapus atau diganti nama tanpa kenaikan versi.

Memverifikasi tanda tangan

Setiap permintaan membawa header X-Skyfield-Signature: sha256=<hex>, yaitu HMAC-SHA256 dari body permintaan mentah dengan kunci rahasia tanda tangan aturan Anda. Verifikasi sebelum memercayai sebuah permintaan.

Rahasia (whsec_...) ditampilkan sekali, tepat setelah penyimpanan yang memberi aturan URL webhook pertamanya. Salin saat itu juga; rahasia tidak dapat ditampilkan lagi. Mengganti URL di kemudian hari tetap memakai rahasia yang sama. Jika hilang, buka aturan, klik Rahasia tanda tangan baru, lalu simpan: rahasia baru ditampilkan sekali dan rahasia lama langsung berhenti berlaku.

Hitung HMAC atas byte body persis seperti yang diterima. Mem-parse lalu menyerialisasi ulang JSON terlebih dahulu akan mengubah spasi dan merusak perbandingan.

Node.js

import { createHmac, timingSafeEqual } from 'node:crypto'

// rawBody: string or Buffer of the request body, before any JSON parsing
function verify(rawBody, header, secret) {
  const expected = 'sha256=' + createHmac('sha256', secret).update(rawBody).digest('hex')
  const a = Buffer.from(expected)
  const b = Buffer.from(header ?? '')
  return a.length === b.length && timingSafeEqual(a, b)
}

// Express example: use express.raw() so req.body is the untouched bytes
app.post('/hook', express.raw({ type: 'application/json' }), (req, res) => {
  if (!verify(req.body, req.get('X-Skyfield-Signature'), process.env.SKYFIELD_SECRET))
    return res.status(401).end()
  const payload = JSON.parse(req.body)
  res.status(200).end()
})

Python

import hmac, hashlib

def verify(raw_body: bytes, header: str, secret: str) -> bool:
    digest = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest("sha256=" + digest, header or "")

# Flask example
@app.post("/hook")
def hook():
    if not verify(request.get_data(), request.headers.get("X-Skyfield-Signature"), SECRET):
        return "", 401
    payload = request.get_json()
    return "", 200

Balas dengan status 2xx apa pun. Body-nya diabaikan.

Zapier, Make, n8n

Ketiganya menerima webhook JSON generik:

  • Zapier: trigger Webhooks by Zapier, event Catch Hook (atau Catch Raw Hook untuk memverifikasi tanda tangan sendiri). Tempel URL yang ditampilkan Zapier ke dalam aturan
  • Make: tambahkan modul Webhooks, Custom webhook, salin URL-nya
  • n8n: tambahkan node Webhook, metode POST, dan gunakan URL produksinya

Kirim uji dari aturan, lalu petakan kolom response.answers di platform tersebut. Payload contoh menggunakan jawaban placeholder sehingga semua kolom tersedia.

Pengiriman dan batas

  • Endpoint harus dapat dijangkau di internet publik melalui HTTPS. Alamat privat dan lokal ditolak saat Anda menyimpan
  • Pengalihan (redirect) tidak diikuti: gunakan URL akhirnya
  • Endpoint memiliki 5 detik untuk menjawab. Timeout atau respons 5xx dicoba ulang sekali
  • Respons 404 atau 410 berarti endpoint sudah tidak ada: aturan dijeda dan Anda menerima satu email. Tempel URL baru pada aturan untuk melanjutkan
  • Halaman Riwayat mencantumkan setiap pengiriman beserta status HTTP yang dikembalikan endpoint Anda
  • Aturan webhook yang dijeda atau dimatikan tidak menghalangi aturan lain pada formulir

Perlu diketahui

  • Aturan webhook mengikuti Kirim saat, sehingga sebuah endpoint dapat menerima keputusan persetujuan alih-alih setiap kiriman. Lihat Kirim Saat
  • Untuk mengirim hanya respons yang sudah diperiksa, setel Kirim saat aturan ke Hanya setelah disetujui dan pilih pemberi persetujuan. Lihat Persetujuan. Payload kemudian membawa approval.decision
  • Ubah channel… memindahkan aturan webhook ke Email atau channel chat; isi tujuan barunya di sana. Beralih kembali ke Webhook berarti menempel URL lagi
  • Aturan webhook memerlukan lisensi aktif. Uji coba gratis termasuk. Lihat apa yang memerlukan lisensi