Formulário de inscrição em newsletter

Formulário de inscrição em newsletter7 min de leitura

Envie as inscrições do seu próprio formulário de newsletter para o Kit

Conecte seu próprio formulário de newsletter ao Kit com um relay que cria o assinante, o adiciona a um formulário do Kit para o incentive email e marca a posição com uma tag.

Preet SutharFundador, Ikiform

Envie seu próprio formulário ao Ikiform e aponte um webhook do Ikiform para um relay que faz até três chamadas à API v4 do Kit: criar o assinante, adicioná-lo a um formulário do Kit e marcar com uma tag onde ele se inscreveu. Crie-o como inactive e adicione-o a um formulário com o incentive email ligado, e o Kit deve enviar a própria confirmação, que você testa uma vez com um endereço seu, porque o Kit só documenta isso para o endpoint em massa. O relay guarda a chave de API do Kit; sua página nunca a vê.

O que muda com o Kit

O Kit divide uma inscrição em objetos separados. Um subscriber é uma pessoa. Um form é de onde ela veio, e carrega o e-mail de confirmação, que o Kit também chama de incentive email: a etapa de double opt-in dele. Uma tag é um rótulo para segmentar. A API v4 tem um endpoint para cada um, e tanto o endpoint de form quanto o de tag exigem que o assinante já exista. Então uma inscrição no Ikiform vira uma pequena sequência de chamadas, nesta ordem:

As chamadas à API do Kit que o relay faz para uma inscriçãoWebhook doIkiformverificado pelorelayPOST/v4/subscribersstate: inactivePOST/v4/forms/{id}/subscribersenvia oincentive emailPOST/v4/tags/{id}/subscribersmarca a posição123As chamadas à API do Kit que o relay faz para uma inscriçãoWebhook do Ikiformverificado pelo relayPOST /v4/subscribersstate: inactivePOST/v4/forms/{id}/subscribersenvia o incentive emailPOST/v4/tags/{id}/subscribersmarca a posição123
  1. O relay recebe o webhook assinado do Ikiform e o verifica.
  2. Ele cria o assinante no Kit como inativo. Se o endereço já existe, o Kit atualiza o primeiro nome e não mexe no estado.
  3. Ele adiciona o assinante ao seu formulário do Kit. Se o incentive email desse formulário estiver ligado, o Kit envia a confirmação.
  4. Se a origem da inscrição tem uma tag, ele marca o assinante com ela. Esta etapa é opcional.
Cada chamada depende da anterior, então o relay para na primeira falha e deixa o Ikiform tentar de novo.
ChamadaO Kit respondeSignificado
Create subscriber201Novo assinante, criado no estado que você enviou
Create subscriber200Já existe. Primeiro nome atualizado, estado inalterado
Adicionar ao formulário201 ou 200Adicionado, ou já estava no formulário. A documentação do bulk form do Kit diz que quem já está num formulário não recebe o incentive email de novo
Qualquer chamada401Chave de API errada ou ausente
Adicionar ao formulário ou tag404O id do formulário ou da tag não existe nesta conta
Qualquer chamada429Acima do limite de taxa da chave de API

Configure o Kit

  1. No Kit, crie um formulário para essas inscrições, como "Website signup". Você não vai incorporá-lo; ele é o registro de onde os assinantes vieram e a casa do incentive email.
  2. Abra as configurações do formulário e ligue o incentive email se quiser double opt-in. Escreva o e-mail e defina para onde o link de confirmação leva.
  3. Encontre o id numérico do formulário, no app do Kit ou com o endpoint de listar formulários da API. Crie uma tag por posição se quiser, e anote os ids.
  4. Crie uma chave de API v4 nas configurações de desenvolvedor do Kit e guarde-a para o ambiente do relay.
A documentação da API do Kit diz que o acesso à API depende de o plano da conta ser elegível, e a página de preços lista apps e integrações a partir do plano Creator. Confira se o seu plano pode criar uma chave v4 antes de construir em cima dela.

O relay

Um route handler do Next.js recebe o webhook e um pequeno módulo conversa com o Kit. Os mesmos dois arquivos rodam em qualquer host Node ou edge que ofereça uma URL HTTPS pública.

lib/kit.ts
const KIT = "https://api.kit.com/v4";

const TAGS: Record<string, number> = {
  footer: 1111111,
  post: 2222222,
};

function call(path: string, body: Record<string, unknown>) {
  return fetch(`${KIT}${path}`, {
    method: "POST",
    headers: {
      "X-Kit-Api-Key": process.env.KIT_API_KEY!,
      "Content-Type": "application/json",
      Accept: "application/json",
    },
    body: JSON.stringify(body),
  });
}

export async function addToKit(signup: { email: string; firstName?: string; source: string; referrer?: string }) {
  const created = await call("/subscribers", {
    email_address: signup.email,
    first_name: signup.firstName ?? null,
    state: "inactive",
  });
  if (!created.ok) return created;

  const joined = await call(`/forms/${process.env.KIT_FORM_ID}/subscribers`, {
    email_address: signup.email,
    referrer: signup.referrer ?? null,
  });
  if (!joined.ok) return joined;

  const tag = TAGS[signup.source];
  if (!tag) return joined;
  return call(`/tags/${tag}/subscribers`, { email_address: signup.email });
}
app/api/kit/route.ts
import { verifyWebhook, WebhookVerificationError } from "@ikiform/sdk/webhooks";
import { addToKit } from "@/lib/kit";

export async function POST(request: Request) {
  const payload = await request.text();
  let event;
  try {
    event = await verifyWebhook({ payload, headers: request.headers, secret: process.env.IKIFORM_WEBHOOK_SECRET! });
  } catch (error) {
    if (error instanceof WebhookVerificationError) return new Response(error.reason, { status: 400 });
    throw error;
  }
  if (event.type !== "submission.created") return new Response(null, { status: 204 });

  const { email, first_name, consent, source } = event.data.fields;
  if (consent !== true || typeof email !== "string") return new Response("Skipped", { status: 200 });

  const answer = await addToKit({
    email,
    firstName: typeof first_name === "string" ? first_name : undefined,
    source: typeof source === "string" ? source : "unknown",
    referrer: typeof event.data.meta.referrer === "string" ? event.data.meta.referrer : undefined,
  });

  if (answer.status === 429) return new Response("Kit rate limit", { status: 503, headers: { "retry-after": "60" } });
  if (!answer.ok) return new Response(`Kit answered ${answer.status}: ${await answer.text()}`, { status: 502 });
  return new Response(null, { status: 204 });
}
.env.local
IKIFORM_WEBHOOK_SECRET=whsec_...
KIT_API_KEY=your-v4-api-key
KIT_FORM_ID=1234567
  • X-Kit-Api-Key é como a API v4 do Kit recebe uma chave de API pessoal. OAuth é para apps que outras pessoas instalam; um relay para a sua própria lista não precisa dele.
  • Enviar state: "inactive" é o que mantém um novo assinante não confirmado até ele clicar. Sem isso, o Kit o cria como active, e o estado não pode ser alterado depois pelo mesmo endpoint.
  • O referrer da página vai para o Kit como o referrer do formulário, então o Kit mostra de qual artigo o leitor veio.
  • O corpo de erro do Kit vai no 502, então o log de entregas no Ikiform mostra a própria mensagem do Kit.
  • Mapeie cada valor de source para um id de tag em TAGS. Uma origem sem tag pula a terceira chamada.

Adicione a URL da rota em Webhooks no painel do Ikiform, escolha o formulário da newsletter e copie o segredo whsec_ para IKIFORM_WEBHOOK_SECRET. Todas as regras para a URL e cada resposta estão na documentação de webhooks.

Limites de taxa e novas tentativas

O Kit permite 120 requisições a cada 60 segundos corridos por chave de API. Cada inscrição custa duas ou três, então cabem cerca de 40 a 60 inscrições por minuto antes de o Kit responder 429. É mais que suficiente para um formulário de rodapé, e fica apertado no dia em que um post viraliza.

O relay responde 503 com Retry-After quando o Kit diz 429, e o Ikiform espera antes de tentar de novo. Uma nova tentativa roda a sequência inteira desde o início. Isso é seguro: o create devolve 200 para um assinante existente, e adicionar alguém que já está no formulário devolve 200. A documentação do bulk form do Kit diz que quem já está num formulário não recebe o incentive email de novo; o endpoint individual não diz, então teste uma nova tentativa com um endereço seu. Seu próprio servidor mostra como registrar cada webhook-id se você preferir pular tentativas que já concluiu.

Pegadinhas

  • Campos personalizados precisam existir antes. Se você adicionar fields à chamada de create, use a chave de cada campo, como last_name, e crie o campo no Kit antes de enviá-lo.
  • Assinantes ativos continuam ativos. Como o create nunca muda o estado de um assinante existente, um leitor confirmado que se inscreve de novo não precisa confirmar outra vez.
  • Leitores descadastrados. Um leitor que se descadastrou e se inscreve de novo já existe, então o create devolve 200 e não muda o estado dele. Veja no Kit como você quer lidar com esses casos.
  • Um formulário, muitas posições. Use um formulário do Kit para o site e tags para as posições. Vários formulários do Kit significam vários incentive emails para manter em sincronia.
  • Nenhum e-mail do Ikiform. O Ikiform não envia e-mail para quem preenche o formulário. Os e-mails de notificação vão só para você e sua equipe, então não há resposta automática, e-mail de confirmação nem double opt-in. Envie esses e-mails pela sua ferramenta de e-mail, disparados por um webhook.

Confira se funciona

  1. Escolha Send test no endpoint no Ikiform. A entrega mostra 204, e nada muda no Kit.
  2. Inscreva-se na sua página com um endereço seu. A entrega mostra 204.
  3. No Kit, o assinante aparece no seu formulário como não confirmado, com a tag da posição.
  4. O incentive email chega. Clique no link e o assinante fica confirmado.
  5. Inscreva-se de novo com o mesmo endereço. A entrega mostra 204 e nenhum segundo incentive email chega.
  6. Defina um KIT_FORM_ID errado por um momento. A entrega mostra 502 com a mensagem 404 do Kit.

Perguntas

Travou em algum passo ou quer um guia para o seu caso? Envie um e-mail para hello@ikiform.com.