# Contacts API

Com o link encurtado haverá um redirecionamento para o link-alvo e o registro do evento `redirect_request` ou `pixel_request`.&#x20;

O `pixel_request` é utilizado para identificar seu usuário quando acessa um email de engajamento, no qual pode-se identificar a abertura desta uma mensagem por meio da pixel requisitado.&#x20;

### Introdução

Contacts API é o micro serviço para encurtar URLs, redirecionamento e criação de links para pixel de e-mails. O Contacts API absorveu as antigas api's, API Redirect Links e API Pixel, criando apenas em um único *endpoint* para gerar esses recursos.&#x20;

Agora, você tem um único local para enviar os dados de contato, criar um link encurtado e o pixel, automaticamente. Com esses recursos é possível colocar estes links em suas mensagens de SMS, E-mail ou campanhas melhorando a experiências dos usuários, além de oferecer um link de pixel de identificação que pode ser utilizado em campanhas por e-mail, para gerenciar os envios e identificar as etapas em que o cliente se encontram.

### O que você precisa saber sobre Contacts API antes de começar?

1. Todos os campos enviados no payload serão salvos para cada contato e podem ser utilizados para interpolação.
2. Os nomes dos campos serão mantidos como CASE SENSITIVE onde NOME, Nome, nome são campos diferentes.
3. Você precisará fornecer o modelo desta base de contatos enviando no `payload.model_name`.
4. Você precisará enviar uma descrição do modelo enviando no `payload.model_description`.
5. Você precisará enviar os campos enviados em um forma de uma lista separada por vírgulas em `payload.model_fields`. Os campos informados aqui serão utilizados para analytics, ou seja, serão enviados para o `destination` definido pelo cliente, por exemplo, Elastic.&#x20;
   1. Esses campos não são públicos para o destino do link por exemplos os clientes que clicaram no link enviado.
   2. Esses campos serão automaticamente adicionados ao evento `redirect_request` como [extra\_data](#introducao) (42). Desta forma, times de operações como Marketing e Customer Success podem acompanhar de forma granular e analítica a interação do contato com cada link. O evento redirect\_request é disparado quando um link AgnosticData é clicado.&#x20;
   3. Os campos enviados no payload e não informados em `model_fields` somente poderão ser acessados via consulta de banco de dados. Isso é útil quando o time de dados tem interesse em determinadas informações, mas elas não podem ficar disponíveis para os times operacionais.&#x20;
6. No máximo 2.000 contatos são processos por requisição.
7. Para a criação de urls encurtadas automaticamente requer informar o campo `hash` de cada contato com o texto `"auto"`
   1. Caso seja necessário (não recomendado) poderá enviar seu próprio hash, mas precisará garantir que seja único em toda a base enviada, pois LEMBRE-SE: se um documento existente der erro salvar por conflito de hash, por exemplo dos 2.000 enviados, irá cancelar toda a requisição de todos os itens da lista (lote) não sendo possível identificar individualmente qual deles estava duplicado.
8. É requerida uma URL para compor a rota. Disponibilizamos por padrão `https://agno.cc/HASH`. Mas, você pode criar um domínio para ser implementado como seu domínio encurtado.&#x20;

```javascript
// EXEMPLO:
 
 url_encurtada = "https://agno.cc/HASH_CODE" 
 // hash_code sempre será a chave primária do link
```

### Aspectos técnicos

#### O que é e como utilizar a interpolação via qs\_target

**qs\_target** é um string que contém toda a querystring para interpolação de variáveis para a URL de destino ou redirecionamento esperado.&#x20;

````python
```python
{
  "qs_target": "?&acid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}"
}
```
````

Você deverá enviar *obrigatoriamente* o campo **`qs_target`** para realizar a interpolação dos valores dos campos enviados (lembre-se que são CASE SENSITIVE) .&#x20;

**Exemplo:**&#x20;

Quando você envia um campo chamado `CODE` e desejar que ele seja exposto na *querystring* da URL de destino preencha o `qs_target` com algo como `"?campanha={{CODE}}".` Ao receber o campo CODE e o qs\_target com {{CODE}} algoritmo irá entender que deverá interpolar a *querystring,* substituindo a expressão {{CODE}} pelo valor do campo enviado do item de contato.&#x20;

#### Interpolação de pixel\_url

De forma similar, você pode criar uma url com uma imagem de 1px para ser inserida no e-mail e acompanhar como o padrão de mercado, a interação básica de leitura sobre aquela mensagem.

**Note**: *as soluções de e-mail já informam ao remetente quando um determinado usuário (destinatário) ler uma mensagem, porém essa configuração pode ser alterada pelos usuários, por isso o mercado utiliza atualmente um pixel que permite interpretar esse cenário*.

{% hint style="warning" %}
**IMPORTANTE**: você não precisa criar pixel\_url a partir da v2 desta API (31 agosto de 2024). A API irá retornar o campo shorten\_url\_v2 que contém o shorten\_url + "?agp=true". Ao adicionar agp=true a uma shorten url o comportamento do redirecionamento será de devolver um pixel e não um redirecionamento de URL. Obviamente deve ser inserido dentro de uma tag \<img com src="shorten+agp=true" />
{% endhint %}

É **requerido** para interpolar enviar para cada "linha" do contato o campo `pixel_url` com a PIXEL\_URL\_BASE do Agnostic Data + doc (identificador do pixel ou apid) + variáveis. Abaixo temos um exemplo.

* PIXEL\_URL\_BASE = `https://utils.agnosticdata.ai/v2/?api_key=API_KEY&project_id=PROJECT_ID&f=pixel&doc=UNIQUE_PIXEL_ID`
  * `onde:`&#x20;
    * URL\_PIXEL = `https://utils.agnosticdata.ai/v2/`
    * `api_key = chave do projeto`
    * `project_id = identificador do projeto no Agnostic Data`
    * `f = função de leitura de pixel`
    * `doc = identificador único do pixel, geralmente sha256 do identificador do cliente.`&#x20;
* **Interpolação**: E você poderá concatenar mais dados, além da variável doc, tornando-os mais lúcido para estratégias de (re)marketing como utm\_source, utm\_content, etc, conforme o exemplo: `https://utils.agnosticdata.ai/v2/?api_key=API_KEY&project_id=PROJECT_ID&f=pixel&doc={{hash}}&acid={{acid}}&apid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}`

Por fim, para utilizar uma `pixel_url` do Agnostic Data, se essa eventualmente existir, basta acessar a url do serviço:

```
https://utils.agnosticdata.ai/v2/?api_key=CHAVE_DO_PROJETO&project_id=ID_DO_PROJETO&f=pixel&doc={{hash}}
```

{% hint style="info" %}
**Fique por dentro**

O `hash_code` da URL encurtada sempre será a chave primária (id) dos links e/ou pixel. Contudo você poder localizar um pixel por um campo específico, no caso, o identificador do usuário ou um identificador único. Coloque `` &fdoc=NOME_DO_CAMPO` ``como querystring do atributo "`pixel_url`", onde `NOME_DO_CAMPO` é um campo enviado no payload `{data:{...}},` com isso você identificar o usuário que abriu o e-mail`.`&#x20;
{% endhint %}

#### Exemplos de interpolação

Suponha que você tenha as variáveis `campanha`,`utm_source`, `utm_medium`, `utm_campaign` e `utm_content` com valores, `ABC`, `cenprot`, `email`, `campanha01` e `pf`, respectivamente. Para interpolar para a querystring final, teremos uma `qs_target` parecida com:

```
?campanha={{CODE}}utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}
```

que resultará em (exemplo):

```
?campanha=ABC&utm_source=cenprot&utm_medium=email&utm_campaign=campanha01&utm_content=pf
```

Para isso você enviou junto ao payload, os dados abaixo:

```javascript
{ data: {
    //... dados do payload
    "model_name": "meu_modelo_01", 
    "model_description": "dados de cnpj", 
    "model_fields": "CODE, utm_source, utm_medium, utm_campaign, utm_content",
    contacts:[
        {
            "CODE": "ABC", 
            "utm_source": "cenprot", 
            "utm_medium": "email", 
            "utm_campaign": "campanha01", 
            "utm_content": "pf"
        }
    ]
}
```

#### **Exemplo de aplicação do PIXEL em e-mails HTML**

Crie uma imagem no seu template, coloque no atributo src a url `pixel_url` gerada nesta API.&#x20;

```html
<!-- seu código ou template de email -->
<img width="1px" height="1px" src="https://utils.agnosticdata.ai/v2/?api_key=CHAVE_DO_PROJETO&project_id=ID_DO_PROJETO&f=pixel&doc={{UNIQUE_PIXEL_ID}}" />
```

**✅ doc é requerido:** `doc` refere-se ao hash do pixel de um determinado usuário. É o identificador único. Veja mais sobre fdoc para alterar o atributo que será utilizado como "chave primária".&#x20;

### Atribuições

#### Atributos complementares que podem ser mapeados da querystring do pixel URL

Os campos a seguir são previamente conhecidos e podem ser utilizados no Agnostic Data para ajudar no seu compromisso da melhor prestação de serviço e suporte. Os campos que também podem ser enviados como querystring são:

* `acid`: identificação direta (chave primária) de um usuário do seu sistema (aplicativo, ambiente). NÃO USE DOCUMENTOS PESSOAIS.
* `apsid`: identificação de um usuário anônimo
* `vv`: o valor desta interação
* `cc`: moeda sobre o custo (custo de marketing, aquisição, click, envio de email, etc)

além das UTMs

* `utm_source`: Identifica a fonte do tráfego, como o nome do mecanismo de busca, boletim informativo ou outro referenciador Exemplo: utm\_source=google
* `utm_medium`: Define o meio de marketing utilizado, como e-mail, CPC (custo por clique), banner, entre outros. Exemplo: utm\_medium=cpc
* `utm_campaign`: Usado para identificar uma campanha de marketing específica. É útil para segmentar dados de diferentes campanhas. Exemplo: utm\_campaign=primavera\_sale
* `utm_term`: Principalmente usado para rastreamento de palavras-chave em campanhas de publicidade paga. Identifica os termos de pesquisa pagos. Exemplo: utm\_term=sapatos+de+corrida
* `utm_content`: Usado para diferenciar anúncios ou links semelhantes que apontam para a mesma URL. Pode ser útil em testes A/B. Exemplo: utm\_content=logotipo\_link ou utm\_content=texto\_link
* `utm_id`: Um parâmetro menos comum que pode ser usado para identificar especificamente uma campanha com um ID único.

#### 🪪 \[avançado] Atribuições com dados pessoais: Complete Data para Contacts

Ao criar seus contatos você passou campos padronizados de dados complementares de usuários (complete\_data), além dos seus campos personalizados e do seu interesse, eles serão utilizados para permitir conhecer seu cliente (KYC), que é bastante útil para times de Customer Success e Atendimento (pode responder questões como *qual cliente está navegando neste funcionalidade agora?*).&#x20;

Na etapa de criação dos contatos é possível enviar os campos complementares que chamamos de \`complete\_data\`. São eles:

* `complete_data_save` // se true informará ao serviço contacts para salvar os dados pessoais junto a mesma tupla (ou documento) dos links.&#x20;
* `complete_data_has_hash` || "base64" // pode ser base64 ou sha256 ou plain; se não informado será base64. Use "plain" se desejar que os dados sejam humanamente legíveis pera time de suporte, operações e customer success.
* `complete_data_email` || null
* `complete_data_phone` || null
* `complete_data_firstname` || null
* `complete_data_lastname` || null
* `complete_data_date_born` || null
* `complete_data_gender` || null
* `complete_data_city` || null
* `complete_data_neighborhood` || null
* `complete_data_state` || null
* `complete_data_zipcode` || null
* `complete_data_country` || null
* `complete_data_order_id` || null
* `complete_data_ps_id_ga` || null // pseudo id dos caras google measurement id
* `complete_data_ps_id_fb` || null // pseudo id facebook pixel id
* `complete_data_ps_id_uc` || null // pseudo id uxcam
* `complete_data_ps_id_sg` || null // pseudo id segment
* `complete_data_ps_id_hj` || null // pseudo id hotjar
* `complete_data_ps_id_ap` || null // pseudo id amplitude
* `complete_data_install_id` || null // application install hash id apple ou android

#### IMPORTANTE: hash e fdoc

**hash**

Por padrão o hash gerado é a chave primária do redirect e pixel (Ex.: https//curta.url/hash) e também o campo ***doc***. Assim o hash e doc serão os mesmos e significa que o pixel será localizado pelo hash. Contudo, em alguns casos isso pode ser um impeditivo ou porque um HASH de 6 dígitos seja insuficiente e/ou não representativo para o pixel que geralmente contém a identificação de um usuário específico com SHA256 de um documento pessoal.

**fdoc**

Para modificar o \`doc\` você pode informar qual campo terá o identificador único utilizando `fdoc` ou (acrônimo de field document) para identificar o campo que irá representar o `doc` para a pixel\_url.

No exemplo abaixo, a chave primária será o atributo do payload chamado CODE. Consulte o exemplo do payload em "Exemplos de interpolação".&#x20;

```javascript
//...
let pixel_url = `${PIXEL_URL_BASE}&fdoc=CODE&doc={{hash}}...`
```

### Enviando via javascript

```javascript
// PROJECT SETUP
const api_key = process.env.AGNOSTIC_API_KEY
const project_id = process.env.AGNOSTIC_PROJECT_ID

// DEFAULT URL-TARGETs
const URL_CONTACT_API = 'https://contacts.agnosticdata.ai/v2/?api_key=' + api_key + '&project_id=' + project_id + '&f=contacts'
const PIXEL_URL_BASE = 'https://utils.agnosticdata.ai/v2/?api_key=' + api_key + '&project_id=' + project_id + '&f=pixel'

// SAMPLE qs_target
let qs_target = "?campanha={{CODE}}&apid={{CODE}}&acid={{acid}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}";
// SAMPLE pixel_url
let pixel_url = `${PIXEL_URL_BASE}&fdoc=CODE&doc={{CODE}}&acid={{acid}}&apid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}`;

// SAMPLE data 
const payload = {data: { // contactsData
  model_name: "contacts",
  model_description: "contacts",
  model_fields: "name,email,phone",
  contacts: [{ // array of contacts
      CODE: "test-91817-4151-8f24-3910c7cadb13", hash: "auto", 
      qs_target: "?campanha={{CODE}}&apid={{CODE}}&acid={{acid}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}", 
      pixel_url: `${PIXEL_URL_BASE}&fdoc=CODE&doc={{CODE}}&acid={{acid}}&apid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}`,
      shorten_url: "https://rslv.cc/", target_url: "https://resolve.cenprot.org.br/app/", 
      utm_source: "fonte", utm_medium: "email", utm_campaign: "campanhaX", utm_content: "pf", utm_term: "livros%2Bcadernos%2Bcanetas", 
      acid: "meu-uuid-uniq-user",
      _controle: "seu_controle_de_envios_ou_lista_nome"}]
    }
  }

// POST 
const response = await request.post(URL_CONTACT_API)
  .set('Content-Type', 'application/json')
  .set('Accept', 'application/json')
  .send(payload);

// console.log(response) 
// { 
//    status: 200, 
//    data: JSON.stringify(outputData), 
//    message: `#[adai][utils][set_contacts] ${contacts.length} contacts saved successfully` 
}    
```

**Analogamente a uma planilha os dados de envio teriam as colunas**

Onde `shorten_url` e `target_url` precisam terminar com barra (/).&#x20;

A `shorten_url` é a url base para automaticamente compor algo similar a `https://shorten_url/hash/` . **Obs.: Barra no final**&#x20;

A `target_url` a url da página é a página para onde o usuário será redirecionado ao clicar na shorten\_url que foi gerada automaticamente. E, a target\_url é automaticamente composta com os *Dados de Marketing* para localização das campanhas que irá gerar a `redirect_to`.  Geralmente, o time de marketing não precisa da redirect\_to, pois é utilizada pelo algoritmo redirecionador.&#x20;

<figure><img src="https://2995894881-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBD2WDS4DaY1QhGFZ1hqU%2Fuploads%2FC2a0hBxGomGKQQAPo4nW%2Fdados_de_interpolacao.png?alt=media&#x26;token=857836bd-4b67-4f5e-ad6d-373f5cef1269" alt=""><figcaption><p>Dados de interpolação</p></figcaption></figure>

<figure><img src="https://2995894881-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBD2WDS4DaY1QhGFZ1hqU%2Fuploads%2FN7WbtWhimg0dxQYuWIjU%2Fdados_de_marketing.png?alt=media&#x26;token=68080324-3fa8-4a0f-9709-0d0d80f864c6" alt="" width="375"><figcaption><p>Dados de Marketing</p></figcaption></figure>

<figure><img src="https://2995894881-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FBD2WDS4DaY1QhGFZ1hqU%2Fuploads%2F3g7H2rQWR2ltRveNAiSr%2Fdados_de_controle.png?alt=media&#x26;token=52afb77a-a7e7-4721-9ae1-2845f65f16a6" alt="" width="201"><figcaption><p>Dados de controle</p></figcaption></figure>

**Retorno**

```json
{
	"status": 200,
	"message": "#[adai][utils][set_contacts] 1 contacts saved successfully",
	"data": [
		{
			"NR_CHAVE": "NR_CHAVE",
			"firstname": "firstname",
			"LAST_NM_SACADO": "LAST_NM_SACADO",
			"lastname": "lastname",
			"DT_NASCIMENTO_SACADO": "DT_NASCIMENTO_SACADO",,
			"CODE": "CODE", // Exemplo: id do user em sha256
			"hash": "BY288K", // vc envou "auto" e a API gerou esse
			"ACID": "ACID", // user ID não obrigatório
			"utm_souce": "utm_souce", // campos de marketing
			"utm_medium": "utm_medium", // campos de marketing
			"utm_campaign": "utm_campaign", // campos de marketing
			"utm_content": "utm_content", // campos de marketing
			"utm_term": "utm_term", // campos de marketing
			"pixel_url": "", //DEPRECATED: não necessário (url interpolada para utilizar marketing)
			"shorten_url": "shorten_urlBY288K", // url encurtada recebida
			"target_url": "target_url", // *obrigatório: url de destino
			"qs_target": "", // querystring para completar a target_url (opcional)
			"redirect_to": "target_url", // url gerada como destino da shorten_url
			"scope": "api_key:project_id",
			"model_fields": "nome,lugar,objeto",
			"model_name": "newco_padrao_01",
			"model_description": "contém dados de usuários de protestos",
			"is_active": true,
			"user_id": "Rei Naldo Benny", // quem enviou 
			"created": {
				"_seconds": 1709891619,
				"_nanoseconds": 351000000
			},
			"updated": {
				"_seconds": 1709891619,
				"_nanoseconds": 351000000
			}
		}
	]
}
```
