Integracao com CRM
Sincronize entregas do fast_deliv com seu CRM (Salesforce, HubSpot, Pipedrive, etc.) para acompanhar clientes e automatizar followups.
Estrategias
| Estrategia | Quando usar | Latencia |
|---|---|---|
| Polling periodico | CRM nao aceita webhook | Minutos |
| Webhook → CRM | Atualizacao imediata ao mudar status | Segundos |
Mapeamento de campos
| Campo fast_deliv | Campo CRM sugerido | Descricao |
|---|---|---|
delivery.id |
external_id |
ID externo da atividade |
delivery.title |
subject / deal_name |
Nome da atividade ou negocio |
delivery.status |
stage / status |
Estagio do pipeline |
delivery.origin_address |
pickup_address |
Endereco de coleta |
delivery.destination_address |
delivery_address |
Endereco de entrega |
delivery.driver_earnings |
logistics_cost |
Custo logistico |
delivery.created_at |
activity_date |
Data da atividade |
delivery.completed_at |
closed_date |
Data de conclusao |
driver.full_name |
assigned_to |
Responsavel pela entrega |
Sincronizacao via polling
Script Python que sincroniza entregas periodicamente:
import time
import requests
from datetime import datetime, timezone
BASE_URL = "https://fast-deliv-backend.vercel.app"
CRM_BASE_URL = "https://api.seu-crm.com"
def get_fast_deliv_deliveries(token: str) -> list[dict]:
resp = requests.get(
f"{BASE_URL}/api/v1/deliveries",
headers={"Authorization": f"Bearer {token}"},
)
resp.raise_for_status()
return resp.json()
def upsert_to_crm(crm_token: str, delivery: dict) -> None:
"""Cria ou atualiza um registro no CRM."""
payload = {
"external_id": delivery["id"],
"subject": delivery["title"],
"stage": map_status_to_crm_stage(delivery["status"]),
"pickup_address": delivery["origin_address"],
"delivery_address": delivery["destination_address"],
"logistics_cost": delivery.get("driver_earnings"),
"activity_date": delivery["created_at"],
}
# Verificar se ja existe pelo external_id
search = requests.get(
f"{CRM_BASE_URL}/activities",
headers={"Authorization": f"Bearer {crm_token}"},
params={"external_id": delivery["id"]},
)
existing = search.json().get("results", [])
if existing:
# Atualizar
crm_id = existing[0]["id"]
requests.patch(
f"{CRM_BASE_URL}/activities/{crm_id}",
headers={"Authorization": f"Bearer {crm_token}"},
json=payload,
)
else:
# Criar
requests.post(
f"{CRM_BASE_URL}/activities",
headers={"Authorization": f"Bearer {crm_token}"},
json=payload,
)
def map_status_to_crm_stage(status: str) -> str:
return {
"pending": "Aguardando",
"assigned": "Em Rota de Coleta",
"in_progress": "Em Transito",
"completed": "Entregue",
"cancelled": "Cancelado",
}.get(status, status)
# Loop de sincronizacao a cada 5 minutos
def sync_loop(fast_deliv_token: str, crm_token: str):
while True:
print(f"[{datetime.now(timezone.utc).isoformat()}] Sincronizando...")
deliveries = get_fast_deliv_deliveries(fast_deliv_token)
for d in deliveries:
upsert_to_crm(crm_token, d)
print(f" {len(deliveries)} entregas sincronizadas")
time.sleep(300) # 5 minutos
if __name__ == "__main__":
import os
sync_loop(
fast_deliv_token=os.environ["FAST_DELIV_TOKEN"],
crm_token=os.environ["CRM_TOKEN"],
)
Webhook → CRM (atualizacao imediata)
Configure um endpoint no seu servidor para receber eventos do fast_deliv e repassar ao CRM:
from fastapi import FastAPI, Request, BackgroundTasks
import requests
app = FastAPI()
CRM_BASE_URL = "https://api.seu-crm.com"
CRM_TOKEN = "seu_crm_token"
def push_to_crm(delivery: dict):
"""Enfileirar atualizacao no CRM em background."""
stage = map_status_to_crm_stage(delivery["status"])
# Buscar pelo external_id e atualizar estagio
search = requests.get(
f"{CRM_BASE_URL}/activities",
headers={"Authorization": f"Bearer {CRM_TOKEN}"},
params={"external_id": delivery["id"]},
)
results = search.json().get("results", [])
if results:
crm_id = results[0]["id"]
requests.patch(
f"{CRM_BASE_URL}/activities/{crm_id}",
headers={"Authorization": f"Bearer {CRM_TOKEN}"},
json={"stage": stage},
)
print(f"CRM atualizado: entrega {delivery['id']} -> {stage}")
@app.post("/webhooks/delivery-status")
async def delivery_status_webhook(request: Request, bg: BackgroundTasks):
"""
Configure seu sistema para chamar este endpoint
quando uma entrega mudar de status.
(Implemente sua propria autenticacao aqui)
"""
payload = await request.json()
delivery = payload.get("delivery")
if delivery:
bg.add_task(push_to_crm, delivery)
return {"ok": True}
Tratamento de duplicatas
Sempre use o campo id da entrega como external_id no CRM para evitar duplicatas:
def safe_upsert(crm_client, delivery: dict) -> str:
"""Retorna 'created' ou 'updated'."""
external_id = delivery["id"]
existing = crm_client.find_by_external_id(external_id)
if existing:
crm_client.update(existing["id"], build_payload(delivery))
return "updated"
else:
crm_client.create(build_payload(delivery))
return "created"
Idempotencia
O fast_deliv pode chamar seu webhook mais de uma vez para o mesmo evento. Sempre implemente upsert (nao apenas insert) para evitar duplicatas.