> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Personalize com Custom Events

> Use propriedades de Custom Events para personalizar mensagens de Journeys com sintaxe Liquid. Saiba como os eventos sao armazenados, acessados e renderizados em templates de push, e-mail e SMS.

[Custom Events](./custom-events) permitem personalizar mensagens de Journeys usando propriedades de eventos (nomes de produtos, precos, URLs, arrays, etc.).

As propriedades de eventos ficam disponiveis nos templates somente se o evento:

* Aciona a entrada no Journey, ou
* Corresponde a uma condicao **Wait Until** dentro do Journey

As propriedades de eventos armazenadas podem ser acessadas usando [sintaxe Liquid](./using-liquid-syntax).

***

## Como funciona a personalizacao com Custom Events

Adicione propriedades de eventos as suas mensagens de Journey seguindo estes passos:

<Steps>
  <Step title="Enviar um Custom Event com propriedades">
    Exemplo de payload de [Custom Events](./custom-events):

    ```json JSON theme={null}
    {
      "name": "purchase",
      "properties": {
        "item": "Blue Sweater",
        "price": "29.99",
        "order status": "pending",
        "details": [
          {
            "manufacturer": "Company A",
            "model": "1234567890"
          },
          {
            "manufacturer": "Company B",
            "model": "9876543210"
          }
        ]
      },
      "external_id": "user_12345",
      "timestamp": "2025-10-21T19:09:32.263Z",
    }
    ```
  </Step>

  <Step title="Referenciar propriedades de eventos nos templates de mensagem do Journey">
    Use [sintaxe Liquid](./using-liquid-syntax) para acessar propriedades de eventos.

    ### Padroes comuns de acesso Liquid

    | O que voce quer                      | Liquid                                                                | Resultado                      |
    | ------------------------------------ | --------------------------------------------------------------------- | ------------------------------ |
    | Nome do evento                       | `{{ journey.first_event.name }}`                                      | `purchase`                     |
    | Propriedade                          | `{{ journey.first_event.properties.item }}`                           | `Blue Sweater`                 |
    | Propriedades aninhadas               | `{{ journey.first_event.properties.details.first.manufacturer }}`     | `Company A`                    |
    | Propriedade com caracteres especiais | `{{ journey.last_event.properties["order status"] }}`                 | `pending`                      |
    | Timestamp                            | `{{ journey.last_event.timestamp \| date: "%B %d, %Y at %I:%M %p" }}` | `October 21, 2025 at 07:09 PM` |

    #### Padroes de acesso Liquid aninhados

    Voce tambem pode acessar propriedades aninhadas usando notacao de ponto e colchetes:

    ```liquid Liquid theme={null}
    {{ journey.first_event.properties.details.first.manufacturer }} = Company A
    {{ journey.first_event.properties.details.last.manufacturer }} = Company B
    {{ journey.first_event.properties.details[0].manufacturer }} = Company A
    {{ journey.first_event.properties.details[1].manufacturer }} = Company B
    ```

    <Warning>
      Liquid invalido ou propriedades ausentes sao renderizados como strings vazias. As mensagens ainda sao enviadas. Use [filtros default](./using-liquid-syntax#default) para definir um valor de fallback.
    </Warning>
  </Step>

  <Step title="Criar um Journey">
    Configure o Journey para usar o Custom Event como regra de entrada e/ou condicao Wait Until.

    * Consulte [Configuracoes de Journeys](./journeys-settings) para regras de entrada.
    * Consulte [Acoes de Journeys](./journeys-actions) para condicoes Wait Until.

    Adicione nos de mensagem com os templates.
  </Step>
</Steps>

### Regras de armazenamento de propriedades de eventos

* Voce pode usar varios eventos no seu Journey combinando regras de entrada e etapas Wait Until.
* Maximo: **100 propriedades de eventos armazenadas por usuario por instancia de Journey** (as mais antigas sao descartadas).
* As propriedades de eventos sao armazenadas **por usuario, por instancia de Journey**.
* Eventos enviados antes da entrada nao sao acessiveis.
* As propriedades de eventos sao limpas quando o usuario sai do Journey.

<Warning>
  Eventos armazenados em um Journey nao podem ser acessados em outro Journey.
</Warning>

***

## Referencia Liquid de Custom Events

Use estes objetos para acessar eventos armazenados dentro do Journey.

<ParamField body="journey.first_event">
  O primeiro evento armazenado para esta instancia de Journey.

  * Se estiver usando uma **regra de entrada por Custom Event**, este e o evento que causou a entrada no Journey.
  * Se nao estiver usando uma regra de entrada por Custom Event, este e o primeiro evento armazenado ao corresponder a uma condicao Wait Until.

  ```liquid Liquid theme={null}
  Thanks for purchasing {{ journey.first_event.properties.item | default: "your item" }}!
  ```
</ParamField>

<ParamField body="journey.last_event">
  O evento armazenado mais recente para esta instancia de Journey.

  * Se apenas um evento estiver armazenado, `first_event` e `last_event` retornam o mesmo resultado.

  ```liquid Liquid theme={null}
  Your most recent purchase was {{ journey.last_event.properties.item | default: "made" }}!
  ```
</ParamField>

<ParamField body="journey.event.EVENT_NAME">
  O evento armazenado mais recente com um nome especifico.

  * Substitua `EVENT_NAME` pelo nome do seu evento (ex.: `purchase`).
  * Se o mesmo nome de evento for usado varias vezes, este retorna a instancia mais recente.

  ```liquid Liquid theme={null}
  {% assign event = journey.event.purchase %}
  ```

  Se o nome do seu evento inclui espacos ou caracteres especiais, use [notacao de colchetes](https://shopify.dev/docs/api/liquid/basics#referencing-handles).

  **Exemplo de evento:** `"name": "order status"`

  ```liquid Liquid theme={null}
  {% assign event = journey.event["order status"] %}
  ```
</ParamField>

<ParamField body="journey.all_events" type="array">
  Todos os eventos armazenados para esta instancia de Journey, na ordem em que foram armazenados.

  * Use [loops for](./using-liquid-syntax#for-loops) para iterar sobre eles.

  ```liquid Liquid theme={null}
  {% for event in journey.all_events %}
  • {{ event.properties.item | default: "Item" }} — ${{ event.properties.price | default: "0.00" }}
  {% endfor %}
  ```

  * `journey.first_event` e uma abreviacao para `journey.all_events[0]`.
  * `journey.last_event` e uma abreviacao para o evento mais recente no array.
</ParamField>

***

## Exemplo: Templates de carrinho abandonado usando Custom Events

Este exemplo mostra como personalizar mensagens de carrinho abandonado usando Custom Events. Ele se baseia no [tutorial de Carrinho Abandonado](./abandoned-cart).

**Exemplo de conjunto de Custom Events:**

```json JSON theme={null}
{
  "events": [
    {
      "name": "cart_abandoned",
      "properties": {
        "cart_url": "https://yourdomain.com/username/cart",
        "cart": [
          {
            "product_name": "24 Pack of Acorns",
            "product_image": "https://i.imgur.com/ssPCfbC.png",
            "product_price": "$12.99",
            "product_quantity": "1"
          },
          {
            "product_name": "Fancy Sweater",
            "product_image": "https://i.imgur.com/8QWTfV4.png",
            "product_price": "$9.99",
            "product_quantity": "1"
          }
        ]
      },
      "external_id": "ID_OF_THE_USER"
    }
  ]
}
```

### Template de e-mail

Este exemplo mostra como criar um template de e-mail que exibe:

* A quantidade de itens no carrinho
* Cada produto com imagem, nome, quantidade e preco usando um loop for
* Um botao que direciona para a URL unica do carrinho do cliente

<Frame caption="Exemplo de template de e-mail de carrinho abandonado">
  <img src="https://mintcdn.com/onesignal/KSCNwSpBCNSQ8xdF/images/docs/fd61543-Screenshot_2023-08-28_at_10.52.05_AM.png?fit=max&auto=format&n=KSCNwSpBCNSQ8xdF&q=85&s=4128b15d8d53d69c6626e129eee538fa" width="693" height="1477" data-path="images/docs/fd61543-Screenshot_2023-08-28_at_10.52.05_AM.png" />
</Frame>

<Steps>
  <Step title="Criar o template de e-mail">
    Navegue ate **Messages > Templates > New Email Template** e abra o Editor Drag & Drop.
  </Step>

  <Step title="Adicionar a estrutura de layout">
    Crie cinco linhas:

    * Linhas 1, 2 e 4: uma coluna com um bloco **Paragraph**
    * Linha 3: quatro colunas com **HTML | Paragraph | Paragraph | Paragraph**
    * Linha 5: uma coluna com um bloco **Button**

    <Frame caption="Template de e-mail inicial para carrinho abandonado">
      <img src="https://mintcdn.com/onesignal/v-hm59YoewwF90UX/images/email/starter-template-abandoned-cart.png?fit=max&auto=format&n=v-hm59YoewwF90UX&q=85&s=551e9ec4618f64fdc0b6ab610a537c48" width="2968" height="2124" data-path="images/email/starter-template-abandoned-cart.png" />
    </Frame>
  </Step>

  <Step title="Exibir a contagem de itens">
    Na linha 1, adicione:

    ```liquid Liquid theme={null}
    We're holding onto {{journey.first_event.properties.cart.size}} items in your cart, but don't wait too long!
    ```

    Para melhor gramatica, voce poderia usar um condicional para dizer "1 item" vs "2 itens", mas para e-mails de carrinho abandonado, o plural geralmente e aceitavel.

    ```liquid Liquid theme={null}
    {% assign cart = message.custom_data.cart %}
    {% assign item_count = cart.size | plus: 0 %}
    {% if item_count == 1 %}
    We're holding onto {{item_count}} item in your cart, but don't wait too long, other squirrels are getting ahead!
    {% endif %}
    {% if item_count > 1 %}
    We're holding onto {{item_count}} items in your cart, but don't wait too long, other squirrels are getting ahead!
    {% endif %}
    ```
  </Step>

  <Step title="Iniciar o loop for">
    Use um [loop for](./using-liquid-syntax#for-loops) para repetir a linha de exibicao do produto para cada item do carrinho.

    Na linha 2 (inicio do loop), adicione:

    ```liquid Liquid theme={null}
    {% for product in journey.first_event.properties.cart %}
    ```

    **O que isso faz:**

    * Inicia um loop que itera sobre cada objeto no array `cart`
    * Cria uma variavel temporaria `product` representando o item atual
    * Tudo entre `{% for %}` e `{% endfor %}` se repete uma vez por item do carrinho
    * Voce pode nomear `product` como quiser (ex.: `item`, `cartItem`) — apenas mantenha a consistencia

    <Warning>
      Posicionamento do loop for: Certifique-se de que a sintaxe `{% for %}` esteja em sua propria linha de bloco de texto. Nao a coloque dentro de uma linha com varias colunas junto a outro conteudo, pois isso pode quebrar a renderizacao do e-mail em alguns clientes.
    </Warning>
  </Step>

  <Step title="Exibir detalhes do produto">
    Esta linha de 4 colunas mostra imagem, nome, quantidade e preco. Como esta dentro do loop, ela se repete para cada item do carrinho.

    Na linha 3 (detalhes do produto), configure:

    **Coluna 1 - Bloco HTML** (imagem do produto):

    ```html theme={null}
    <img src="{{product.product_image}}" alt="Product image" style="max-width:100%;" />
    ```

    **Colunas 2-4 - Blocos de texto** (nome do produto, quantidade, preco):

    * Coluna 2: `{{product.product_name}}`
    * Coluna 3: `{{product.product_quantity}}`
    * Coluna 4: `{{product.product_price}}`

    **Como o loop funciona:**

    * Na primeira iteracao, `product` = primeiro objeto no array do carrinho
    * `{{product.product_image}}` obtem a imagem do primeiro item
    * Na segunda iteracao, `product` = segundo objeto
    * A linha se repete automaticamente para todos os itens do carrinho

    <Warning>
      **Correspondencia de nomes de campos:** Chaves como `product_image` devem corresponder exatamente ao payload do seu evento (diferencia maiusculas de minusculas). Incompatibilidades sao renderizadas como strings vazias.
    </Warning>
  </Step>

  <Step title="Encerrar o loop for">
    Feche o loop para marcar onde a repeticao termina.

    Na linha 4 (fim do loop), adicione:

    ```liquid Liquid theme={null}
    {% endfor %}
    ```

    <Note>
      Todo `{% for %}` deve ter um `{% endfor %}` correspondente. A ausencia dele quebrara a renderizacao do e-mail.
    </Note>
  </Step>

  <Step title="Adicionar o botao com URL do carrinho">
    No bloco **Button** da linha 5, defina a URL da acao como:

    ```liquid Liquid theme={null}
    {{journey.first_event.properties.cart_url}}
    ```

    <Frame caption="Template de e-mail base finalizado para carrinho abandonado sem estilizacao">
      <img src="https://mintcdn.com/onesignal/v-hm59YoewwF90UX/images/email/finished-template-abandoned-cart-custom-event.png?fit=max&auto=format&n=v-hm59YoewwF90UX&q=85&s=67217e202cc57ca4039e0b34d2501f15" width="2968" height="1716" data-path="images/email/finished-template-abandoned-cart-custom-event.png" />
    </Frame>
  </Step>

  <Step title="Testar o template">
    * Adicione o template a um Journey em branco e defina a regra de entrada como Custom Event.
    * Ative o Journey e entre nele por meio da API de Custom Events.
    * Verifique se os dados sao exibidos corretamente.

    <Check>Sucesso! Agora voce pode aplicar sua propria estilizacao ao template. Consulte [Criar e-mails com drag-and-drop](./design-emails-with-drag-and-drop).</Check>
  </Step>
</Steps>

### Template de push

Notificacoes push tem espaco limitado, entao exiba um item e mencione a contagem total.

**Campo de mensagem:**

Exiba o item e a contagem com gramatica correta usando [instrucoes condicionais](./using-liquid-syntax#if-elsif-else).

```liquid Liquid theme={null}
{% assign cart = journey.first_event.properties.cart %}
{% assign item_count = cart.size | plus: 0 %}
{% if item_count == 1 %}
You left {{cart.first.product_name}} in your cart.
{% endif %}
{% if item_count == 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more item in your cart.
{% endif %}
{% if item_count > 2 %}
You left {{cart.first.product_name}} and {{item_count | minus: 1}} more items in your cart.
{% endif %}
```

**Campo de imagem:**

```liquid Liquid theme={null}
{{journey.first_event.properties.cart.first.product_image | default: "https://i.imgur.com/ssPCfbC.png"}}
```

**Campo de URL de abertura:**

```liquid Liquid theme={null}
{{journey.first_event.properties.cart_url | default: "https://yourdomain.com/cart"}}
```

Envie uma notificacao push de teste adicionando-a ao Journey de teste e entrando nele por meio de outra chamada da API de Custom Events. Voce devera ver uma notificacao semelhante a esta:

<Frame caption="Exemplo de template de push de carrinho abandonado">
  <img src="https://mintcdn.com/onesignal/4HyuQPBpu-4xjmQC/images/docs/d0db985-Screenshot_2023-08-28_at_9.30.23_AM.png?fit=max&auto=format&n=4HyuQPBpu-4xjmQC&q=85&s=6cf03ce9b622ba399656f2b14fb055f3" width="688" height="656" data-path="images/docs/d0db985-Screenshot_2023-08-28_at_9.30.23_AM.png" />
</Frame>

<Check>Sucesso! Agora voce pode criar mais templates e usa-los no [Journey de Carrinho Abandonado](./abandoned-cart).</Check>

***

## Solucao de problemas e melhores praticas

**Erros comuns:**

| Erro                                        | Por que falha                                      | Sintaxe correta                                |
| ------------------------------------------- | -------------------------------------------------- | ---------------------------------------------- |
| `{{ journey.first_event.item }}`            | Faltando `.properties`                             | `{{ journey.first_event.properties.item }}`    |
| `{{ journey.event.purchase.item }}`         | Faltando `.properties`                             | `{{ journey.event.purchase.properties.item }}` |
| `{{ journey.first_event.properties.Item }}` | Maiuscula/minuscula incorreta (deveria ser `item`) | `{{ journey.first_event.properties.item }}`    |
| `{{ event.properties.item }}`               | Faltando o prefixo `journey.`                      | `{{ journey.first_event.properties.item }}`    |

**Melhores praticas:**

* Sempre teste os templates antes de colocar em producao
* Use [filtros default](./using-liquid-syntax#default) para propriedades opcionais
* Valide se o schema do evento corresponde as expectativas do template

***

## Paginas relacionadas

<Columns cols={2}>
  <Card title="Personalizacao de mensagens" href="./message-personalization" icon="sparkles">
    Visao geral de todas as opcoes de personalizacao no OneSignal, incluindo quando usar Custom Events vs outros metodos.
  </Card>

  <Card title="Custom Events" href="./custom-events" icon="bolt">
    Guia completo para implementar e enviar Custom Events via SDK ou API.
  </Card>

  <Card title="Visao geral de Journeys" href="./journeys-overview" icon="route">
    Aprenda a criar fluxos de trabalho de mensagens automatizados com gatilhos, condicoes e acoes.
  </Card>

  <Card title="Configuracoes de Journeys" href="./journeys-settings" icon="gear">
    Configure regras de entrada acionadas por eventos e o comportamento do Journey.
  </Card>

  <Card title="Acoes Wait Until" href="./journeys-actions#wait-until" icon="clock">
    Use nos Wait Until para armazenar eventos adicionais durante a progressao do Journey.
  </Card>

  <Card title="Usando sintaxe Liquid" href="./using-liquid-syntax" icon="droplet">
    Referencia completa de Liquid com filtros, condicionais, loops e manipulacao de strings.
  </Card>

  <Card title="Templates" href="./templates" icon="file">
    Crie e gerencie templates de mensagens reutilizaveis para uso em Journeys.
  </Card>
</Columns>

<Info>
  Precisa de ajuda?

  Converse com nossa equipe de Suporte ou envie email para `support@onesignal.com`

  Por favor inclua:

  * Detalhes do problema que você está enfrentando e passos para reproduzir se disponível
  * Seu OneSignal App ID
  * O External ID ou Subscription ID se aplicável
  * A URL para a mensagem que você testou no Dashboard OneSignal se aplicável
  * Quaisquer [logs ou mensagens de erro](/docs/pt-BR/capturing-a-debug-log) relevantes

  Estamos felizes em ajudar!
</Info>

***
