# DataFirefly Native Live Shopping: documentação

> Visão de conjunto O DataFirefly Native Live Shopping transforma a sua loja WooCommerce numa plataforma de live shopping autónoma, sem depender de um serviço de terceiros como a Bambuser ou…

- Página: <https://www.datafirefly.com/pt/documentation/dfnativeliveshopping/>
- Idioma: pt
- Atualizado em: 2026-09-02
- Outros idiomas: [fr](https://www.datafirefly.com/documentation/dfnativeliveshopping/index.md), [en](https://www.datafirefly.com/en/documentation/dfnativeliveshopping/index.md), [es](https://www.datafirefly.com/es/documentation/dfnativeliveshopping/index.md), [de](https://www.datafirefly.com/de/documentation/dfnativeliveshopping/index.md), [it](https://www.datafirefly.com/it/documentation/dfnativeliveshopping/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfnativeliveshopping/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfnativeliveshopping/index.md)
- Índice: <https://www.datafirefly.com/pt/documentation/llms.txt>

## Visão de conjunto

O DataFirefly Native Live Shopping transforma a sua loja WooCommerce numa plataforma de live shopping autónoma, sem depender de um serviço de terceiros como a Bambuser ou a CommentSold. A difusão usa **WebRTC ponto a ponto em mesh** a partir do navegador do anfitrião para cada espetador, a sinalização passa pela API REST do WordPress, e a gravação do replay é feita do lado do cliente através da API MediaRecorder e guardada como anexos do WordPress.

O plugin fornece:

- Um CPT `dfnls_live_show` para criar e agendar as suas transmissões
- Uma consola de anfitrião integrada na administração do WordPress (pré-visualização de câmara, controlos, produtos, chat)
- Uma experiência de espetador pronta a usar, com produtos clicáveis em sobreposição e chat
- Uma ponte para o carrinho do WooCommerce (adição ao carrinho oficial sem sair da transmissão)
- Um replay automático sincronizado com os eventos da transmissão (destaques, cupões, mensagens)
- Um bloco Gutenberg dedicado e o shortcode `[dfnls_live]`

**Arquitetura**: a topologia WebRTC em mesh é ideal até cerca de 25 espetadores em simultâneo por anfitrião. Acima disso, prever um servidor TURN externo ou ponderar um SFU. A largura de banda de envio do anfitrião deve rondar os 500 kbps por espetador ligado.

## Requisitos

- **WordPress** 6.3 ou superior
- **WooCommerce** 8.0 ou superior (compatível com HPOS)
- **PHP** 8.1 ou superior (testado até à 8.3)
- **HTTPS obrigatório**: o `getUserMedia()` e o `getDisplayMedia()` recusam funcionar em HTTP não seguro
- Navegadores suportados do lado do espetador: Chrome 80+, Firefox 75+, Edge 80+, Safari 14+, Opera 67+
- Um navegador recente do lado do anfitrião, com câmara e microfone acessíveis

**Importante**: sem HTTPS válido (o Let's Encrypt chega), a consola de anfitrião não consegue aceder à câmara nem ao microfone. Teste em `localhost` ou num domínio com certificado TLS.

## Instalação

1. Descarregue o arquivo `df-native-live-shopping.zip` a partir da sua conta DataFirefly.
2. No WordPress, vá a _Plugins → Adicionar_ → _Carregar plugin_.
3. Selecione o ficheiro ZIP e clique em _Instalar agora_.
4. Terminada a instalação, clique em _Ativar plugin_.
5. Aparece um novo menu **Live Shopping** na barra lateral da administração.

Na ativação, o plugin:

- Cria 5 tabelas personalizadas (`wp_dfnls_signaling`, `_sessions`, `_events`, `_replay_parts`, `_chat`)
- Acrescenta as permissões `manage_dfnls_lives` e `host_dfnls_lives` aos perfis `administrator` e `shop_manager`
- Agenda dois crons: limpeza diária dos replays antigos e limpeza horária das mensagens de sinalização obsoletas
- Regista as opções predefinidas (servidores STUN da Google, retenção de 90 dias, máximo de 25 espetadores, etc.)

## Primeira transmissão em 5 minutos

O percurso mais curto para lançar a sua primeira transmissão:

1. Menu **Live Shopping → Nova transmissão**
2. Indique um título (por exemplo «Vendas relâmpago de primavera»)
3. Na metabox _Produtos_, pesquise e selecione os produtos WooCommerce que quer apresentar (arrastar e largar para reordenar)
4. Opcional: em _Agendamento_, defina uma data e hora de início (aparece uma contagem decrescente do lado do espetador)
5. Publique a transmissão
6. Vá a **Live Shopping → Consola de anfitrião** e selecione a sua transmissão
7. Clique em _Iniciar a difusão_ e autorize o acesso à câmara e ao microfone
8. Partilhe o URL público da transmissão (`/live/o-seu-slug/`) com o seu público

## Consola de anfitrião

A consola de anfitrião é o painel a partir do qual anima a sua transmissão. Está acessível em _Live Shopping → Consola de anfitrião_. Funcionalidades:

### Pré-visualização de vídeo e controlos

- **Câmara**: interruptor de ativação e desativação da câmara
- **Microfone**: interruptor de ativação e desativação do microfone
- **Partilha de ecrã**: substitui o fluxo da câmara por uma partilha de ecrã (útil para demonstrações)
- **Iniciar / Parar**: botões de controlo principal da transmissão

### Destaque de produtos

A lista dos produtos ligados à transmissão aparece à direita. Cada produto tem um botão _Destacar_. Clicar nele:

- Faz aparecer de imediato o produto em sobreposição em todos os espetadores
- Regista um evento `product.spotlight` com data e hora para a sincronização do replay
- Um segundo clique no mesmo botão retira a sobreposição

### Difusão de cupões

Introduza um código promocional (por exemplo `LIVE20`) e, se quiser, uma descrição, e clique em _Difundir_. Aparece um destaque animado no ecrã dos espetadores, com um botão «Copiar» para obter o código num clique.

### Mensagens do apresentador

Um campo de texto livre permite enviar uma mensagem que aparece numa faixa temporária do lado do espetador (8 segundos por predefinição).

### Chat em direto

O chat entre apresentador e espetadores está integrado na consola. As mensagens do apresentador são visualmente distintas (distintivo e contorno vermelho) em todas as vistas.

### Registo de atividade

Um registo no fundo da consola mostra em tempo real as ligações e desligações, os eventos difundidos, os carregamentos de blocos de replay e os eventuais erros.

## Vista do espetador

O que o público vive assim que chega ao URL público da transmissão:

- **Antes da transmissão**: se estiver agendada, aparece um ecrã de espera com contagem decrescente até à hora prevista. Consulta automática do estado a cada 5 segundos para detetar o arranque.
- **Durante a transmissão**: vídeo em direto com pastilha «EM DIRETO» a pulsar e contador de espetadores. Barra lateral com dois separadores: _Produtos_ (lista clicável dos produtos da transmissão) e _Chat_.
- **Sobreposição de produto**: quando o apresentador destaca um produto, desliza um cartão no ecrã (por predefinição em baixo à direita) com fotografia, nome, preço e botão _Adicionar ao carrinho_.
- **Adição ao carrinho**: um clique no botão acrescenta o produto ao carrinho oficial do WooCommerce. Aparece um botão flutuante em baixo à direita com o contador de artigos no carrinho.
- **Cupão relâmpago**: difundido pelo apresentador, aparece no topo com animação e botão de copiar.
- **Depois da transmissão**: se o replay estiver ativo, um botão «Ver o replay» permite rever a transmissão com sincronização integral dos eventos.

## Definições globais

Menu **Live Shopping → Definições**. Secções principais:

### Servidores STUN

Por predefinição, são usados os servidores STUN públicos da Google:

```
stun:stun.l.google.com:19302
stun:stun1.l.google.com:19302
```

Pode acrescentar os seus próprios servidores STUN (um por linha).

### Servidores TURN

Opcional, mas recomendado para os espetadores por trás de NAT simétrico (alguns operadores 4G, VPN de empresa). Formato:

```
turn:turn.exemplo.com:3478
turns:turn.exemplo.com:5349
```

Indique as credenciais _TURN username_ e _TURN credential_ associadas.

### Gravação e replay

- **Gravação ativa**: sim / não, global
- **Duração dos blocos** (ms): 5000 por predefinição. Mais curto = mais resiliência a falhas mas mais pedidos; mais longo = menos pedidos mas maior perda em caso de falha
- **Retenção dos replays** (dias): 90 por predefinição. Acima disso, o cron diário elimina automaticamente os ficheiros WebM e as entradas associadas

### Capacidade e sobreposição

- **Número máximo de espetadores por anfitrião**: 25 por predefinição. Ajuste conforme a sua largura de banda de envio
- **Posição da sobreposição**: direita, esquerda ou baixo

### Predefinições por transmissão

- Chat ativo por predefinição
- Replay ativo por predefinição
- Sessão iniciada exigida por predefinição

## Servidores STUN e TURN: quando configurar um TURN

O STUN é um simples servidor de descoberta de IP público, gratuito e suficiente em cerca de 85% dos casos. O TURN, pelo contrário, retransmite efetivamente o tráfego de média: consome largura de banda, mas permite ligar dois clientes que não conseguem chegar um ao outro diretamente.

Configure um TURN se:

- Os seus espetadores se queixarem regularmente de não ver o vídeo (estado da ligação WebRTC bloqueado em «connecting»)
- O seu público tiver muitos telemóveis em 4G/5G em operadores com NAT simétrico
- O seu anfitrião ou os seus espetadores estiverem por trás de uma VPN de empresa estrita

**Solução recomendada**: implantar um [coturn](https://github.com/coturn/coturn) autoalojado num pequeno VPS (5 a 10 € por mês) chega para 30 a 40 espetadores em simultâneo. Alternativa paga: Xirsys, Twilio Network Traversal Service.

## Gravação e replay

### Como funciona a gravação

A gravação é feita inteiramente **no navegador do anfitrião**, através da API MediaRecorder:

1. No arranque da transmissão, o MediaRecorder é instanciado com deteção automática do melhor codec disponível (VP9 > VP8 > H.264, opus para o áudio, cerca de 1,5 Mbps de vídeo mais 96 kbps de áudio)
2. A cada 5 segundos (configurável), é produzido um bloco WebM e carregado através de `POST /wp-json/df-nls/v1/shows/{id}/replay/chunk`
3. O bloco é guardado como anexo do WordPress, com o nome `dfnls-show-{id}-part-{NNNNN}.webm` e `post_parent` a apontar para a transmissão
4. A tabela `wp_dfnls_replay_parts` conserva a ordem e a duração de cada bloco

### Como funciona o replay

No carregamento da página em modo replay:

1. O visualizador chama `GET /wp-json/df-nls/v1/shows/{id}/replay`, que devolve a lista ordenada dos segmentos e a linha temporal dos eventos
2. Os segmentos são carregados sequencialmente através do evento `ended` do `` (recurso nativo)
3. Uma variante MediaSource permite a concatenação transparente se o navegador a suportar
4. A posição de leitura (tempo acumulado) é comparada com o `offset_ms` de cada evento; quando o ponto é ultrapassado, o visualizador desencadeia localmente o mesmo comportamento que em direto (apresentar a sobreposição, destaque do cupão, mensagem)

### Armazenamento e espaço em disco

Ordem de grandeza: uma transmissão de uma hora a 1,5 Mbps de vídeo mais 96 kbps de áudio produz cerca de **720 MB** de ficheiros WebM. Com 90 dias de retenção e 4 transmissões por mês, conte com cerca de 10 GB de espaço em disco dedicado aos replays.

**MIME e carregamento**: o plugin acrescenta um filtro `upload_mimes` para autorizar `video/webm` e `video/mp4` a partir da biblioteca de multimédia. Verifique que o seu servidor não tem uma regra `LimitRequestBody` ou um `upload_max_filesize` demasiado estritos (visar 20 MB no mínimo por bloco).

## Integração: shortcode, bloco, URL direto

### URL público direto

Cada transmissão publicada tem o seu próprio URL gerado automaticamente:

```
https://o-seu-site.com/live/o-seu-slug/
```

É a forma mais simples: partilhe esta ligação com o seu público.

### Shortcode

Para inserir uma transmissão numa página ou num artigo existente:

```
[dfnls_live id="42"]
[dfnls_live id="42" mode="live"]
[dfnls_live id="42" mode="replay"]
[dfnls_live id="42" mode="auto"]
```

Modos disponíveis:

- `auto` (predefinido): deteta o estado da transmissão e apresenta direto / espera / replay conforme o caso
- `live`: força a apresentação em modo difusão (útil para testes)
- `replay`: força o modo replay mesmo que a transmissão ainda esteja em curso

### Bloco Gutenberg

No editor de blocos, procure _«Live Shopping»_. O bloco suporta os alinhamentos `wide` e `full`, e expõe um seletor para escolher a transmissão e um seletor de modo na barra lateral do inspetor.

### Template PHP personalizado

O CPT usa o `templates/single-live-show.php`. Para o substituir, copie este ficheiro para o seu tema em `o-seu-tema/df-native-live-shopping/single-live-show.php`.

## Multilingue com Polylang

O plugin declara o CPT `dfnls_live_show` como traduzível junto do Polylang. Na ativação, se o Polylang já estiver instalado:

- Cada transmissão pode ter uma versão FR, EN, ES, DE, IT, etc.
- Os metadados críticos (`_dfnls_product_ids`, `_dfnls_scheduled_at`, opções da transmissão) são copiados automaticamente entre traduções
- Os 5 idiomas integrados (FR, EN, ES, DE, IT) são carregados automaticamente conforme a locale do WordPress

**Dica para o Polylang Pro**: se usar o Polylang Pro e os seus produtos WooCommerce forem eles próprios traduzidos, cada tradução da transmissão tem de ser associada à versão linguística correspondente dos produtos. O plugin não faz mapeamento automático entre idiomas nos IDs de produto.

## HPOS e compatibilidades

O plugin declara oficialmente a sua compatibilidade com o armazenamento de encomendas de alto desempenho do WooCommerce (HPOS) através do `FeaturesUtil`. Pode ativar o HPOS na sua instalação sem risco de avaria na ponte para o carrinho.

É também compatível com:

- WordPress Multisite (instalação por site, sem modo de rede)
- Alojamento partilhado: a sinalização usa polling REST, sem WebSocket
- Plugins de cache (WP Rocket, WP Super Cache): os endpoints REST do plugin são excluídos automaticamente

## Segurança e permissões

O plugin acrescenta duas permissões dedicadas:

- `manage_dfnls_lives`: criação, edição e eliminação de transmissões; acesso às definições
- `host_dfnls_lives`: acesso à consola de anfitrião, início e fim de uma transmissão

As duas permissões são atribuídas por predefinição aos perfis `administrator` e `shop_manager`. Para dar a um utilizador apenas o direito de animar sem poder criar transmissões:

```
$user = get_user_by('login', 'apresentador');
$user->add_cap('host_dfnls_lives');
```

### Nonces REST

Todas as rotas de ação (POST) estão protegidas por nonce `wp_rest`. O visualizador e o anfitrião recebem o respetivo nonce através do `wp_localize_script` no carregamento da página.

### Validação MIME dos carregamentos

O carregamento de blocos de replay é validado de forma estrita através do `wp_check_filetype_and_ext`, para aceitar apenas `video/webm` e `video/mp4`. Os ficheiros são renomeados no servidor (`dfnls-show-{id}-part-{NNNNN}.webm`).

## Cron e manutenção

São agendados dois crons do WordPress na ativação:

- `dfnls_cleanup_expired_replays`: **diário**. Elimina os replays das transmissões terminadas há mais de N dias (retenção configurável). Usa o `wp_delete_attachment(..., true)` para eliminar também o ficheiro físico.
- `dfnls_cleanup_stale_signaling`: **horário**. Limpa as mensagens de sinalização com mais de 24 h e as sessões inativas há mais de 90 segundos.

**WP-Cron desativado**: se desativou o WP-Cron em favor de um cron de sistema, certifique-se de chamar o `wp-cron.php` pelo menos uma vez por hora para que as limpezas sejam executadas.

## Para programadores: API REST

Todas as rotas estão no namespace `df-nls/v1`.

### Show

- `GET /shows/{id}`: obtém uma transmissão (estado, produtos, opções)
- `POST /shows/{id}/join`: entra como espetador ou anfitrião (corpo: `peer_id`, `role`)
- `POST /shows/{id}/leave`: sai de forma limpa
- `POST /shows/{id}/heartbeat`: mantém a sessão aberta (automático a cada 15 s do lado do espetador)
- `POST /shows/{id}/start`: inicia a transmissão (apenas anfitrião)
- `POST /shows/{id}/end`: termina a transmissão (apenas anfitrião)
- `GET /shows/{id}/viewers`: contador de espetadores ativos

### Sinalização WebRTC

- `POST /signal/send`: envia uma mensagem SDP/ICE a um peer remoto
- `GET /signal/pull?peer={id}`: obtém as mensagens pendentes e faz um heartbeat implícito

### Eventos

- `POST /shows/{id}/event`: regista um evento (destaque, mensagem, cupão)
- `GET /shows/{id}/events?since={id}`: obtém os eventos a partir de um ID dado

### Chat

- `GET /shows/{id}/chat?since={id}`: obtém as mensagens a partir de um ID
- `POST /shows/{id}/chat`: envia uma mensagem

### Ponte para o carrinho

- `POST /cart/add`: acrescenta um produto ao carrinho com rastreio da origem (`show_id`, `product_id`, `quantity`)
- `GET /cart/summary`: contador e total do carrinho atual

### Gravação e replay

- `POST /shows/{id}/replay/chunk`: carregamento multipart de um bloco WebM
- `GET /shows/{id}/replay`: segmentos e linha temporal de eventos para leitura

## Estrutura do plugin (PSR-4)

```
df-native-live-shopping/
├── df-native-live-shopping.php        # Bootstrap
├── uninstall.php
├── readme.txt
├── assets/
│   ├── js/    (host.js, viewer.js, admin.js, block-editor.js)
│   └── css/   (host.css, viewer.css, admin.css)
├── languages/                          # 5 .po/.mo + .pot
├── templates/                          # single-live-show.php, viewer-container.php, ...
└── src/
    ├── Plugin.php
    ├── Activator.php   Deactivator.php
    ├── PostType/       (LiveShow.php)
    ├── Database/       (Schema + 5 Repository.php)
    ├── Admin/          (AdminPages, MetaBoxes, SettingsPage)
    ├── Api/            (RestController, SignalingController, CartController)
    ├── Recording/      (RecordingHandler)
    ├── Replay/         (ReplayHandler)
    ├── Frontend/       (Renderer, Shortcode, Block)
    └── Compat/         (PolylangCompat)
```

Namespace raiz: `DataFireflyNativeLiveShopping`, autoloader manual PSR-4 declarado em `df-native-live-shopping.php`.

## Resolução de problemas

### Os espetadores não veem o vídeo

- Verificar que o site está em HTTPS (obrigatório para WebRTC)
- Abrir a consola do navegador do lado do espetador e procurar os erros `ICE failed` ou `connection state failed`
- Configurar um servidor TURN se o público tiver muitos telemóveis em 4G
- Verificar que a largura de banda de envio do anfitrião é suficiente (utilitário fast.com do lado do anfitrião)

### A consola de anfitrião não deteta a câmara

- Verificar que o navegador concedeu mesmo a autorização (ícone do cadeado na barra de URL)
- Em macOS, verificar as permissões do sistema: _Preferências → Segurança → Câmara_
- Fechar as outras aplicações que usam a câmara (Zoom, Teams, OBS...)

### Os blocos de replay não são carregados

- Verificar o `upload_max_filesize` e o `post_max_size` no php.ini (visar 20 MB no mínimo)
- Verificar o `LimitRequestBody` do lado do Apache, se aplicável
- Consultar o registo de atividade da consola de anfitrião para identificar o erro exato
- Verificar as permissões da pasta `wp-content/uploads`

### O carrinho não conserva as adições

- Verificar que nenhum plugin de cache coloca em cache os endpoints `/wp-json/df-nls/v1/*`
- Verificar que os cookies do WooCommerce (`woocommerce_cart_hash`, `wp_woocommerce_session_*`) são mesmo emitidos
- Em HTTPS estrito, verificar que os cookies têm mesmo a flag `Secure`

### Os replays ocupam demasiado espaço

- Reduzir a retenção (por exemplo, de 90 para 30 dias) nas definições
- Desativar a gravação nas transmissões em que não é necessária (caixa «Permitir o replay» na metabox _Opções_)
- Reduzir o bitrate alterando o `host.js` (variável `videoBitsPerSecond`)

## Desinstalação

Na simples desativação, os dados são conservados e os crons desagendados. Na **remoção completa** do plugin a partir de _Plugins_, o `uninstall.php` executa:

- Eliminação das 5 tabelas personalizadas
- Eliminação de todas as opções `dfnls_*`
- Remoção das permissões dos perfis
- Desagendamento dos crons
- Opcional: eliminação dos CPT e de todos os anexos de replay, se a opção `dfnls_uninstall_delete_data` tiver sido ativada antes da desinstalação

**Atenção**: por predefinição, as transmissões e os seus replays NÃO são eliminados na desinstalação. Para eliminar tudo, ative a opção _Eliminar todos os dados na desinstalação_ nas definições antes de desinstalar.

## Suporte e evoluções

Suporte técnico incluído durante 12 meses através da área de cliente DataFirefly. As atualizações do plugin estão disponíveis a partir da sua conta, com notificação por e-mail das versões principais.

Ideias de evolução no roadmap:

- Passagem automática para SFU acima de um limiar de espetadores
- Sondagens em direto (poll.open / poll.close já reservados no protocolo de eventos)
- Análises nativas (tempo médio de visualização, taxa de conversão por transmissão)
- Vários anfitriões (dois apresentadores em simultâneo)
