import express from 'express'
const app = express()
app.use(express.urlencoded({ extended: false }))
app.post('/contato', async (req, res) => {
const { nome, email, telefone, empresa } = req.body
const response = await fetch(`${process.env.STEEL_URL}/api/crm/integrations/leads`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.STEEL_CRM_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: nome,
emails: email ? [email] : [],
phones: telefone ? [telefone] : [],
company: empresa || undefined,
source: 'site',
channel: 'formulario-contato',
}),
})
const body = await response.json()
if (body.success) return res.redirect('/obrigado')
if (body.error.code === 'VALIDATION_ERROR') {
return res.status(400).send('Confira o nome e o e-mail.')
}
console.error('Steel respondeu', body.statusCode, body.error.code)
return res.status(502).send('Não conseguimos enviar agora. Tente de novo.')
})
app.listen(3000)
Python (Flask):
import os
import requests
from flask import Flask, redirect, request
app = Flask(__name__)
@app.post("/contato")
def contato():
form = request.form
lead = {
"name": form["nome"],
"emails": [form["email"]] if form.get("email") else [],
"phones": [form["telefone"]] if form.get("telefone") else [],
"source": "site",
"channel": "formulario-contato",
}
if form.get("empresa"):
lead["company"] = form["empresa"]
response = requests.post(
f"{os.environ['STEEL_URL']}/api/crm/integrations/leads",
headers={"Authorization": f"Bearer {os.environ['STEEL_CRM_KEY']}"},
json=lead,
timeout=10,
)
body = response.json()
if body["success"]:
return redirect("/obrigado")
if body["error"]["code"] == "VALIDATION_ERROR":
return "Confira o nome e o e-mail.", 400
app.logger.error("Steel respondeu %s %s", body["statusCode"], body["error"]["code"])
return "Não conseguimos enviar agora. Tente de novo.", 502
4. Os campos
Campo
Tipo
Obrigatório
Observação
name
texto (até 200)
Sim
Nome do contato
emails
lista de e-mails
Um e-mail ou um telefone
E-mails válidos
phones
lista de textos (até 30 cada)
Um e-mail ou um telefone
Com DDI de preferência: +5511999990000
company
texto (até 200)
Não
jobTitle
texto (até 150)
Não
Cargo
city
texto (até 100)
Não
linkedin
texto (até 300)
Não
URL do perfil
source
texto (até 100)
Não
Origem; sem ela, integration
channel
texto (até 100)
Não
Canal; sem ele, API
5. As respostas
201: lead novo, com pontuação e dono.
200: já havia um lead em aberto com o mesmo e-mail ou telefone; a API
devolve esse lead e não cria outro. Um visitante que envia o formulário duas
vezes não vira dois leads.
401 CRM_INTEGRATION_KEY_INVALID: chave errada ou revogada.
422 VALIDATION_ERROR: veja error.details para saber o campo.
429 RATE_LIMITED: mais de 100 envios por minuto com a mesma chave.
Opção B: formulário do CRM
Monte o formulário em CRM › Formulários, com o mapeamento de cada campo
(para lead, pessoa ou empresa), e publique. O formulário ganha uma página pública
em https://<seu-steel>/f/<token>, que você pode linkar do seu site (por
segurança, as páginas do Steel não abrem dentro de iframe em outro domínio). O
token é o último trecho dessa URL.
Se preferir usar o seu próprio HTML, o seu servidor envia as respostas pela API.
O Steel valida as respostas no servidor, com as regras de cada campo do
formulário, mesmo que o seu site já valide no navegador:
campos obrigatórios precisam vir preenchidos (um checkbox obrigatório
precisa ser true);
email precisa ser um e-mail válido; phone, de 8 a 15 dígitos, com +
opcional (espaços, parênteses e hífens são ignorados); number, um número;
url, um endereço http ou https; date, no formato AAAA-MM-DD;
select, um dos valores das opções;
textos têm até 1.000 caracteres (10.000 em textarea);
chaves que não são campos do formulário são descartadas.
Quando algo não passa, a resposta é 422 VALIDATION_ERROR, com um item por
campo em error.details:
A resposta 201 traz o envio registrado, com o id do lead, da pessoa ou da
empresa criada (createdLeadId, createdPersonId, createdCompanyId). O
Referer fica gravado como a origem do envio.
Status
Código
Causa
404
RESOURCE_NOT_FOUND
Token desconhecido ou formulário excluído
403
MODULE_DISABLED
O CRM foi desabilitado no workspace do formulário
422
CRM_FORM_NOT_PUBLISHED
O formulário não está publicado
422
VALIDATION_ERROR
Corpo sem values, campo obrigatório vazio, valor fora do tipo do campo, ou lead sem e-mail nem telefone
429
RATE_LIMITED
Mais de 100 chamadas por minuto do mesmo IP
Antes de ir para produção
Crie a chave (ou publique o formulário) no ambiente de produção: os de
homologação não valem lá.
Teste um envio repetido e confirme que a segunda resposta é 200.
Registre error.code e statusCode quando a resposta não for sucesso.
Combine com o time comercial os valores de source e channel, que aparecem
nos relatórios do CRM.