| name | unipile-v2-messaging |
| description | Padrão para ENVIAR via Unipile v2 — mensagens/chats (LinkedIn, WhatsApp), convites de conexão no LinkedIn, e e-mail (com tracking de abertura/clique). Use ao implementar ou revisar passos de cadência que disparam mensagem, convite ou e-mail. Requer os fundamentos em [[unipile-v2-foundations]]. |
Unipile v2 — Envio (mensagens, convites, e-mail)
Todas as rotas são /v2/{account_id}/... com account_id no PATH. Ver [[unipile-v2-foundations]].
Iniciar/enviar mensagem (LinkedIn, WhatsApp)
Novo chat 1-a-1 — POST /v2/{account_id}/chats/send (application/json):
{ "text": "<msg>", "users_ids": "<PROVIDER_ID>" }
users_ids como string única → chat 1-a-1; como array → grupo.
- Opcional:
name (nome do chat/grupo), attachments (base64 {content,content_type,filename}).
- LinkedIn: sem InMail só dá pra iniciar com conexões; p/ não-conexão → convide antes.
Enviar em chat existente — POST /v2/{account_id}/chats/{chat_id}/messages/send:
{ "text": "<msg>", "quote_id": "<message_id a responder (opcional)>" }
Prefira quando já tiver o chat_id (ex.: respondendo a um webhook message_received).
InMail (LinkedIn) — POST /v2/{account_id}/chats/send com specifics
Confirmado na spec 2.16.0: a flag vai em specifics — NÃO existe
linkedin.api='inmail' nem subject no top-level (shapes do v1 morto).
{ "text": "<msg>", "users_ids": "<PROVIDER_ID>",
"specifics": { "linkedin": { "classic": { "inmail": true } } } }
subject só existe no produto Sales Navigator (lá é obrigatório):
"specifics": { "linkedin": { "sales_navigator": { "subject": "<assunto>" } } }
— exige a conta com SN conectado. ✅ Nosso sendInMail roteia: com subject →
SN; sem subject → classic com inmail: true.
- Gate de crédito:
GET /v2/{account_id}/linkedin/inmail-credits.
Follow e Endorse (LinkedIn) — rotas confirmadas (spec 2.16.0)
- Follow:
POST /v2/{account_id}/users/me/follow/{user_id} (o user_id no
path, sob users/me/ — a forma /users/{id}/follow não existe).
- Endorse:
POST /v2/{account_id}/linkedin/member/{member_id}/endorse-skill
body { "skill_id": "<endorsement_id>" }. O skill_id é o endorsement_id
numérico da skill no perfil — não o nome. Resolva antes:
GET /v2/{acc}/users/{id}?with_sections=linkedin_skills → skills[].endorsement_id
casando por name. ✅ Nosso endorseSkill faz essa resolução (case-insensitive)
e falha claro se a skill não está no perfil.
Convite de conexão (LinkedIn) — POST /v2/{account_id}/users/me/relation-requests
{ "user_id": "<PROVIDER_ID>", "message": "<nota opcional>" }
Fluxo em 2 passos: (1) GET /v2/{account_id}/users/{public_id} → pega provider_id;
(2) POST relation-requests com esse provider_id em user_id. Cancelar/aceitar:
.../relation-requests/{request_id}/cancel | /accept. Detecção de aceite →
webhook new_relation (ver [[unipile-v2-posts-and-webhooks]]).
Cuidados: contas novas têm invite limitado pelo LinkedIn; espace no tempo.
E-mail — POST /v2/{account_id}/emails/send (application/json)
Props: to (obrigatório, [{email, display_name?}]), subject, html, plain_text,
from ({email, display_name?}), cc, bcc, reply_to, custom_headers,
attachments, tracking_options.
{
"to": [{ "email": "john@x.com", "display_name": "John" }],
"subject": "…",
"html": "<p>…</p>",
"tracking_options": { "opens": true, "clicks": true, "label": "<id_nosso opcional>" }
}
Tracking (aberturas/cliques): exige html e tracking_options ligado — senão
NÃO chega evento. Note: os campos são opens e clicks (não links). O envio
devolve tracking_id; o executor persiste em step_runs e correlaciona com os
webhooks mail_opened/mail_link_clicked (ver [[unipile-v2-posts-and-webhooks]]).
No código, sendEmail já surfça res.tracking_id como id do resultado.
Reply/threading: reply_to=<provider_id do e-mail original> + subject Re:.
Mapa código → endpoint v2
| Ação nossa | Endpoint v2 |
|---|
startChat (linkedin_message, whatsapp_message) | POST /v2/{acc}/chats/send (users_ids) |
| responder em chat | POST /v2/{acc}/chats/{chat_id}/messages/send |
sendInMail (linkedin_inmail) | POST /v2/{acc}/chats/send + specifics.linkedin.classic.inmail (ou sales_navigator.subject) |
followUser (linkedin_follow) | POST /v2/{acc}/users/me/follow/{user_id} |
endorseSkill (linkedin_endorse) | POST /v2/{acc}/linkedin/member/{id}/endorse-skill (skill_id = endorsement_id do perfil) |
sendInvitation (linkedin_invitation) | POST /v2/{acc}/users/me/relation-requests (user_id) |
sendEmail (email) | POST /v2/{acc}/emails/send (to[{email}] + html + tracking_options) |
Reações/comentários em post → [[unipile-v2-posts-and-webhooks]]. Fundamentos → [[unipile-v2-foundations]].