Melampaui formulir builder

Melampaui formulir builder6 menit baca

Formulir Framer: kapan menambahkan backend formulir, dan caranya

Formulir Framer sudah mengirim ke email, Sheets, atau webhook; tambahkan Ikiform sebagai webhook untuk kiriman yang tersimpan dan tersaring, notifikasi tim, dan lebih banyak tujuan.

Preet SutharPendiri, Ikiform

Formulir bawaan Framer mengirim setiap kiriman ke email, Google Sheets, atau webhook, dengan perlindungan spam bawaan, jadi untuk satu inbox atau satu sheet Anda mungkin tidak butuh yang lain. Tambahkan Ikiform sebagai tujuan webhook saat Anda ingin setiap kiriman disimpan dengan status spam, divalidasi terhadap field Anda, dikirim lewat email ke tim, dan diteruskan ke beberapa webhook bertanda tangan. Karena Framer mengirim dari server-nya, longgarkan pemeriksaan origin formulir atau taruh relay kecil di antaranya yang memverifikasi tanda tangan Framer.

Apa bedanya di Framer

Framer satu-satunya builder di panduan ini yang tidak punya batas untuk dihindari. Formulirnya bisa mengirim ke email, Google Sheets, atau webhook apa pun, dan Framer punya perlindungan spam bawaan yang menandai atau memblokir kiriman mencurigakan. Webhook-nya bertanda tangan: setiap request membawa header Framer-Signature, yaitu HMAC-SHA256 dari body dan id kiriman, serta Framer-Webhook-Submission-Id. Framer mencoba ulang hingga lima kali saat endpoint Anda tidak menjawab 2xx, dan tidak mengikuti redirect.

Jadi jujurlah tentang alasan Anda menambahkan backend formulir. Berikut yang dicakup masing-masing:

Yang Anda inginkanFramer sajaDengan Ikiform sebagai webhook
Kiriman di satu inbox atau satu sheetYaYa, plus dashboard
Catatan yang bisa dicari dengan tanda spam, dan ekspor CSVInbox atau sheet Anda adalah catatannyaYa
Pemeriksaan sisi server untuk tipe, panjang, dan opsiTidakYa, dengan definisi field
Notifikasi ke beberapa orang, dengan Reply ditujukan ke pengirimTujuan emailHingga 10 penerima, dengan reply-to
Beberapa alat diisi dari satu formulir, masing-masing dengan percobaan ulangSatu webhook per tujuan yang Anda tambahkanHingga 3 endpoint bertanda tangan, dengan percobaan ulang dan log pengiriman
Backend yang sama di Framer, Webflow, dan situs berbasis kodeTidakYa

Jika baris pertama sudah cukup, tetap pakai tujuan bawaan Framer. Sisa halaman ini untuk saat itu tidak cukup.

Kendalanya: Framer mengirim dari server-nya

Tujuan webhook berarti server Framer yang mengirim post, bukan browser pengunjung. Tiga hal berubah di sisi Ikiform:

  • Tanpa origin. Post dari server tidak membawa header Origin, jadi dengan Allowed domains diatur, setiap post dianggap datang dari situs yang salah.
  • Alamat IP bersama. Ikiform menghitung rate limit per alamat IP, dan setiap post datang dari beberapa alamat Framer, bukan dari alamat pengunjung Anda.
  • Tanpa honeypot. Framer hanya mengirim input yang Anda buat, dan formulirnya tidak bisa menjalankan pemeriksaan manusia Ikiform.

Anda bisa menerimanya, atau memperbaikinya dengan relay. Kedua jalur ada di bawah.

Formulir Framer yang mengirim ke Ikiform secara langsung, dan lewat relay bertanda tanganWebhook langsungRelay bertanda tanganFormulirFramerServerFramerJSON, tanpaoriginIkiformdomainkosong, batasRelaxedFormulirFramerServerFramermenandatanganisetiap postWorkerAndamemeriksaFramer-SignatureIkiformsecret keydanidempotencykey401,dibuangkirimwebhookkirimwebhookteruskantanda tangan salahFormulir Framer yang mengirim ke Ikiform secara langsung, dan lewat relay bertanda tanganWebhook langsungRelay bertanda tanganFormulir FramerServer FramerJSON, tanpa originIkiformdomain kosong, batasRelaxedFormulir FramerServer Framermenandatanganisetiap postWorker AndamemeriksaFramer-SignatureIkiformsecret key danidempotency key401,dibuangkirimwebhookkirimwebhookteruskantanda tangan salah
  1. Langsung: pengunjung mengirim formulir Framer, server Framer mengirimnya sebagai JSON tanpa header Origin, dan Ikiform menerimanya dengan Allowed domains kosong dan rate limit Relaxed.
  2. Relay: server Framer menandatangani setiap post dengan secret Anda dan mengirimnya ke Worker yang Anda deploy.
  3. Worker menghitung ulang tanda tangan Framer. Post tanpa tanda tangan valid mendapat 401 dan tidak diteruskan.
  4. Post yang valid diteruskan ke Ikiform dengan secret key Anda dan id kiriman Framer sebagai idempotency key, jadi percobaan ulang Framer tidak pernah menyimpan salinan kedua.
Relay hanya berisi selusin baris logika. Sebagai gantinya, formulir bisa mempertahankan allowed domains yang ketat, karena hanya Worker Anda yang memegang secret key.

Opsi 1: Ikiform sebagai webhook

  1. Di Framer, beri setiap input nama huruf kecil: name, work_email, company, team_size. Framer memakai nama itu sebagai key JSON.
  2. Pilih formulir, dan di sebelah Send To pilih Addโ€ฆ > Webhook. Tempel endpoint Anda. Biarkan secret kosong; Ikiform tidak memeriksa Framer-Signature.
  3. Di pengaturan formulir Ikiform, biarkan Allowed domains kosong, biarkan Spam check mati, dan atur Rate limit ke Relaxed.
  4. Publikasikan. Framer hanya mengirim webhook dari situs yang dipublikasikan.
URL webhook
https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx

Ikiform menjawab 201 setelah kiriman tersimpan, yang dianggap Framer sebagai terkirim. 422 validation_failed gagal dengan cara yang sama di kelima percobaan ulang, jadi perbaiki nama input alih-alih menunggu. Penilaian spam tetap berjalan di setiap post: tautan, frasa spam, alamat sekali pakai, dan pengulangan.

Opsi 2: relay bertanda tangan

Deploy Cloudflare Worker yang memeriksa tanda tangan Framer dan meneruskan post yang valid dengan secret key Anda. Lalu formulir Ikiform bisa mencantumkan domain Framer Anda di Allowed domains dengan Reject, jadi apa pun yang bukan browser di situs Anda atau Worker Anda akan ditolak.

src/index.ts
interface Env {
  FRAMER_SECRET: string;
  IKIFORM_SECRET_KEY: string;
}

const ENDPOINT = "https://ikiform.com/f/frm_xxxxxxxxxxxxxxxx";
const encoder = new TextEncoder();

async function signatureFor(secret: string, body: ArrayBuffer, submissionId: string) {
  const key = await crypto.subtle.importKey(
    "raw",
    encoder.encode(secret),
    { name: "HMAC", hash: "SHA-256" },
    false,
    ["sign"],
  );
  const id = encoder.encode(submissionId);
  const message = new Uint8Array(body.byteLength + id.byteLength);
  message.set(new Uint8Array(body), 0);
  message.set(id, body.byteLength);
  const digest = new Uint8Array(await crypto.subtle.sign("HMAC", key, message));
  return `sha256=${[...digest].map((byte) => byte.toString(16).padStart(2, "0")).join("")}`;
}

function sameText(a: string, b: string) {
  const left = encoder.encode(a);
  const right = encoder.encode(b);
  return left.byteLength === right.byteLength && crypto.subtle.timingSafeEqual(left, right);
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    if (request.method !== "POST") return new Response(null, { status: 405 });
    const signature = request.headers.get("framer-signature") ?? "";
    const submissionId = request.headers.get("framer-webhook-submission-id") ?? "";
    const body = await request.arrayBuffer();
    if (!submissionId || !sameText(signature, await signatureFor(env.FRAMER_SECRET, body, submissionId))) {
      return new Response("Bad signature", { status: 401 });
    }

    const response = await fetch(ENDPOINT, {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
        Authorization: `Bearer ${env.IKIFORM_SECRET_KEY}`,
        "Idempotency-Key": submissionId,
      },
      body,
    });
    if (response.ok) return new Response(null, { status: 204 });
    return new Response(await response.text(), { status: response.status });
  },
};

Deploy

Terminal
npx wrangler secret put FRAMER_SECRET
npx wrangler secret put IKIFORM_SECRET_KEY
npx wrangler deploy
  • FRAMER_SECRET adalah secret yang Anda atur di tujuan webhook Framer. Framer mensyaratkan minimal 32 karakter dan tidak akan menampilkannya lagi, jadi buat, simpan, dan tempel di kedua tempat.
  • IKIFORM_SECRET_KEY adalah secret API key dari dashboard Ikiform. Jangan pernah menaruhnya di Framer.
  • Tanda tangannya adalah sha256= ditambah HMAC heksadesimal dari body mentah diikuti id kiriman. Baca body sekali sebagai byte dan gunakan byte yang sama untuk pemeriksaan dan penerusan.
  • Idempotency-Key membuat percobaan ulang Framer memutar ulang jawaban pertama Ikiform alih-alih menyimpan duplikat. Key disimpan selama 24 jam.
  • Worker meneruskan status dari Ikiform. Framer mencoba ulang jawaban apa pun yang bukan 2xx, hingga lima kali, jadi 429 atau 5xx mendapat kesempatan lagi, sedangkan 422 gagal dengan cara yang sama setiap kali sampai Anda memperbaiki nama input.

Lalu arahkan webhook Framer ke URL Worker alih-alih ke endpoint, dengan secret diisi.

Setiap post kini datang dari Worker Anda. Versi sisi server mengirim dengan secret key, jadi Ikiform melewati Allowed domains dan pemeriksaan manusianya. Setiap post lalu datang dari IP server Anda, dan batas Standard 5 per menit per pengunjung menghitung semua pengunjung Anda bersama-sama. Pilih rate limit Relaxed atau Custom untuk formulir yang Anda kirim lewat server, dan simpan IKIFORM_SECRET_KEY di environment variable khusus server.

Opsi 3: lewati formulir Framer

Code component merender formulir sungguhan dan mengirim dari browser pengunjung, jadi pemeriksaan origin, honeypot, dan rate limit per pengunjung bekerja seperti di situs mana pun. Anda kehilangan pengeditan formulir visual Framer untuk formulir itu. Panduan dokumentasi Framer berisi komponennya.

Pastikan berfungsi di Framer

  1. Publikasikan situs Framer dan kirim formulir di sana, bukan di preview editor.
  2. Buka Submissions di dashboard. Kiriman baru ada di sana dengan setiap field yang Anda kirim.
  3. Periksa bahwa nama field persis sama dengan nama input Anda, tanpa key tambahan dari Framer.
  4. Untuk relay: kirim request ke Worker dengan Framer-Signature karangan dan pastikan jawabannya 401.
  5. Untuk relay: di detail kiriman, origin kosong dan statusnya received, bukan spam.
  6. Cek inbox setiap penerima notifikasi. Masing-masing mendapat email berisi field, dan Reply terkirim ke pengirim formulir jika formulir punya field email.
  7. Jika Anda menambahkan webhook, buka endpoint-nya di Webhooks. Pengiriman menampilkan succeeded dengan jawaban dari server Anda.

Hal yang sering menjebak

MasalahYang harus dilakukan
Setiap post webhook masuk spam dengan origin_mismatchAllowed domains diatur sementara Framer mengirim langsung. Kosongkan, atau taruh relay di antaranya.
Worker menjawab 401 untuk post asliSecret berbeda antara Framer dan Worker, atau ada yang membaca body sebagai teks dan mengubahnya. Tempel secret lagi dan hash byte mentahnya.
429 rate_limited saat peluncuranSemua post berbagi alamat Framer atau Cloudflare. Pilih Relaxed, atau batas Custom.
422 validation_failedKiriman tidak cocok dengan definisi field formulir. error.fields menyebutkan setiap field dan alasannya. Samakan name input dengan ID field.
403 challenge_requiredSpam check formulir diatur ke Ikiform dan kiriman fetch tidak membawa token. Ambil token dengan challenge(formId) dari @ikiform/sdk sebelum setiap pengiriman, atau matikan pemeriksaannya.

Pertanyaan

Mentok di salah satu langkah, atau ingin panduan untuk situasi Anda? Email hello@ikiform.com.