SDK JavaScript/TypeScript
O @pliic/sdk é um cliente tipado, sem dependências, que envolve a API do widget (/widget/*) do Pliic. Ele é para quem quer construir uma interface própria de sugestões e tickets (um mural custom, uma caixa de sugestão com o seu próprio visual, uma central de suporte integrada ao seu produto), em vez de embutir o widget pronto.
Se o widget embutido já atende (janela flutuante, botão de feedback), você não precisa do SDK. Use o SDK quando quiser controlar 100% da interface e consumir os dados diretamente.
Instalação
Seção intitulada “Instalação”Via <script> (hospedado)
Seção intitulada “Via <script> (hospedado)”Sem build, sem npm, carregue o script hospedado e use o global PliicSDK:
<script src="https://pliic.com/sdk/v1.js"></script><script> const { Pliic } = window.PliicSDK;</script>O global se chama
PliicSDK, diferente doPliicdo widget embutido, os dois podem coexistir na mesma página sem conflito.
Via npm
Seção intitulada “Via npm”npm install @pliic/sdkimport { Pliic } from '@pliic/sdk';Autenticação
Seção intitulada “Autenticação”Crie o cliente com a chave pública do seu app e, opcionalmente, um token de usuário:
const client = new Pliic({ appKey: 'pk_live_...', userToken: '<jwt do usuário>', // opcional baseUrl: 'https://pliic.com', // opcional, padrão: origem da página/script timeoutMs: 10000, // opcional, padrão 10s});appKey(pk_live_...) identifica o app e a equipe. Encontre-a na aba Instalação do app.userTokenidentifica o usuário final e libera ações como votar. Ele é um JWT gerado no seu servidor com a chave secreta (sk_...) do app: o fluxo completo de geração está documentado em Autenticação de usuários. Sem token, as ações do SDK funcionam como anônimas (sem votação).- O navegador envia o header
Originautomaticamente em cada requisição: o domínio da sua página precisa estar nos domínios permitidos do app (aba Geral), do mesmo jeito que no widget embutido.
Inicialização
Seção intitulada “Inicialização”const init = await client.init(); // { app, config, user }await client.ping();init() retorna as configurações do app e, se houver userToken válido, os dados do usuário identificado. Use ping() para verificar rapidamente se as credenciais e o domínio estão corretos.
Sugestões
Seção intitulada “Sugestões”// Listar (com busca e filtro por status)const list = await client.suggestions.list({ search: 'dark mode', status: 'open' });
// Criarconst created = await client.suggestions.create({ title: 'Modo escuro', description: 'Seria ótimo ter um tema escuro.',});// { id, title, status }
// Editar (só o autor, e só enquanto ninguém mais se envolveu)await client.suggestions.update(created.id, { title: 'Modo escuro para todo o app',});
// Excluir (mesma regra do autor)await client.suggestions.delete(created.id);
// Votarawait client.suggestions.vote(created.id);
// Comentáriosconst comments = await client.suggestions.comments(created.id, { page: 1 });const comment = await client.suggestions.addComment(created.id, { body: 'Concordo!' });
// Checar duplicadas antes de criarconst { duplicates, has_duplicates } = await client.suggestions.checkDuplicates({ title: 'Modo escuro',});Tickets
Seção intitulada “Tickets”// Listarconst tickets = await client.tickets.list({ page: 1 });
// Criarconst ticket = await client.tickets.create({ subject: 'Não consigo fazer login', body: 'Recebo erro 500 ao entrar.', type: 'bug',});// { id, ticket_number, subject, status }
// Buscar um ticket (com mensagens)const { ticket: full, messages } = await client.tickets.get(ticket.id);
// Responderawait client.tickets.reply(ticket.id, { body: 'Ainda estou com o problema.' });
// Marcar como resolvido (só enquanto o ticket estiver aberto ou pendente)await client.tickets.resolve(ticket.id);// { id, status: 'resolved', resolved_at }Responder a um ticket resolved reabre ele automaticamente, sem precisar de nenhuma chamada extra. Não existe um método para reabrir nem para fechar (closed) um ticket pelo SDK, essas transições ficam com a equipe.
Enquetes
Seção intitulada “Enquetes”O SDK expõe apenas o lado de consumo das enquetes: buscar a enquete ativa para o usuário identificado, responder e dispensar. Criação e gestão de enquetes ficam no painel do app.
// Buscar a enquete ativa para o usuário atualconst survey = await client.surveys.active();// null quando não há enquete elegível no momento
if (survey) { // Responder await client.surveys.submit(survey.id, { answers: survey.questions.map((question) => ({ question_id: question.id, value: '5', })), });
// ou dispensar, se o usuário fechar sem responder await client.surveys.dismiss(survey.id);}Cada pergunta de survey.questions traz type (single_choice, rating ou text), label, options (quando single_choice), rating_low_label/rating_high_label (quando rating), placeholder e is_required, o suficiente para renderizar o formulário sem chamadas extras.
Tratamento de erros
Seção intitulada “Tratamento de erros”Qualquer resposta que não seja 2xx lança PliicApiError, com status (código HTTP) e body (corpo bruto da resposta, quando disponível):
import { Pliic, PliicApiError } from '@pliic/sdk';
try { await client.suggestions.create({ title: '' });} catch (error) { if (error instanceof PliicApiError) { console.error(error.status, error.message, error.body); }}Erros comuns:
- 401:
appKeyinválida,userTokenausente/expirado, ou domínio fora da lista de domínios permitidos. - 422: dados de validação inválidos (ex.: título vazio).
- 403:
update/deletenuma sugestão que não é do usuário identificado, ou numa sugestão que já saiu do controle do autor (recebeu voto de outra pessoa, comentário, resposta oficial ou mudou de status). Veja Editando ou excluindo sua sugestão. O mesmo código cobretickets.resolvenum ticket que não é do usuário identificado ou que já não estáopen/pending. Veja Marcando seu chamado como resolvido. - 429 ou erro de limite: o app atingiu o limite do plano (sugestões ou tickets por mês).
Requisições que excedem o timeoutMs configurado também são rejeitadas como PliicApiError.
Próximos passos
Seção intitulada “Próximos passos”- Autenticação de usuários: como gerar o
userToken - Instalando o widget: a alternativa pronta, sem código
- Solução de problemas: erros de domínio e chave também se aplicam ao SDK