Dados do site
Com a API de dados, o Qorum pergunta ao seu site o nome e o cartão das pessoas (foto, selos, cores). Os comentários mostram sempre o visual atual de cada pessoa, sem o seu site precisar mandar nada.
Para que serve
- Cartão sempre atual: a pessoa trocou a foto ou ganhou um selo no seu site, e em até 30 minutos os comentários mostram a mudança.
- Quem não entra há tempo: comentários antigos ou importados de outro sistema ganham nome e foto, mesmo que a pessoa nunca tenha entrado pelo Qorum.
- Token mais simples: o token de login pode levar só o
sube oname. O resto o Qorum busca.
Se você também manda o card no token, ele é usado na hora em que a pessoa entra. A API de dados mantém atualizado depois disso.
Como o Qorum chama
Quando uma lista de comentários tem alguém sem cartão, ou com cartão de mais de 30 minutos, o Qorum chama a sua API em segundo plano. A página não espera por isso: a pessoa vê o cartão que já existe, e o novo aparece nas próximas leituras. Cada pessoa é pedida no máximo uma vez a cada 10 minutos, e os pedidos vão em lotes de até 100.
POST https://meusite.com/qorum/usuarios
Content-Type: application/json
User-Agent: Qorum-Dados/1
X-Qorum-Event: users.lookup
X-Qorum-Timestamp: 1794171698
X-Qorum-Signature: sha256=...
{ "ids": ["123", "77", "15"], "site": "meu-blog" }
A assinatura é a mesma dos webhooks: HMAC-SHA256 com o segredo do webhook sobre timestamp + "." + corpo. Confira sempre: sem isso, qualquer um consegue listar os dados dos seus usuários.
O que responder
Código 200 com os usuários que você encontrou. Quem não existir, deixe de fora.
{
"users": {
"123": { "name": "Ana Lima", "card": { "username": "ana_lima", "displayName": "Ana Lima", "avatar": "https://...",
"rank": { "name": "Assinante", "nameColor": "#7c3aed" } } },
"77": { "name": "Bruno", "card": { "username": "bruno", "avatar": "https://..." } }
}
}
O card segue as mesmas regras do cartão do login: objeto livre de até 8 KB. As chaves de users são os mesmos ids que o seu site manda no sub do token.
Responda em até 8 segundos. Se a sua API falhar, o Qorum continua usando o cartão que já tem e tenta de novo depois de 10 minutos.
Ligar
- Crie a rota no seu site
Veja os exemplos abaixo.
- Informe o endereço
Em Configurações → API de dados do seu site no painel, ou com
PUT /v1/site/settingse{"config": {"apiDados": "https://..."}}. - Teste
Em Testar conexão → API de dados, informe o id de um usuário real. O teste mostra o que o seu site respondeu e já grava o cartão. Pela API:
POST /v1/site/data-api/testcom{"userId": "123"}.
Exemplos
const crypto = require('crypto');
app.post('/qorum/usuarios', express.raw({ type: 'application/json' }), async (req, res) => {
// mesma conferência do webhook
const ts = req.get('X-Qorum-Timestamp') || '';
const esperado = 'sha256=' + crypto.createHmac('sha256', process.env.QORUM_WEBHOOK_SECRET)
.update(ts + '.').update(req.body).digest('hex');
const recebido = req.get('X-Qorum-Signature') || '';
if (recebido.length !== esperado.length || !crypto.timingSafeEqual(Buffer.from(recebido), Buffer.from(esperado))
|| Math.abs(Date.now() / 1000 - Number(ts)) > 300) return res.sendStatus(401);
const { ids } = JSON.parse(req.body);
const usuarios = await db.usuarios.findMany({ where: { id: { in: ids.map(Number).filter(Boolean) } } });
const users = {};
for (const u of usuarios) {
users[String(u.id)] = {
name: u.nome,
card: { username: u.usuario, displayName: u.nome, avatar: u.fotoUrl, isStaff: u.admin },
};
}
res.json({ users });
});
<?php
$corpo = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_QORUM_TIMESTAMP'] ?? '';
$esperado = 'sha256=' . hash_hmac('sha256', $ts . '.' . $corpo, getenv('QORUM_WEBHOOK_SECRET'));
if (!hash_equals($esperado, $_SERVER['HTTP_X_QORUM_SIGNATURE'] ?? '') || abs(time() - (int) $ts) > 300) {
http_response_code(401); exit;
}
$ids = array_filter(array_map('intval', json_decode($corpo, true)['ids'] ?? []));
$users = [];
if ($ids) {
$marcas = implode(',', array_fill(0, count($ids), '?'));
$q = $pdo->prepare("SELECT id, nome, usuario, foto_url, admin FROM usuarios WHERE id IN ($marcas)");
$q->execute(array_values($ids));
foreach ($q as $u) {
$users[(string) $u['id']] = [
'name' => $u['nome'],
'card' => ['username' => $u['usuario'], 'displayName' => $u['nome'], 'avatar' => $u['foto_url'], 'isStaff' => (bool) $u['admin']],
];
}
}
header('Content-Type: application/json');
echo json_encode(['users' => (object) $users]);
API de busca (link com #)
Quem comenta digita # e o nome de alguma coisa do seu site (uma obra, um produto, um post). O Qorum pergunta ao seu site quais páginas combinam e mostra uma lista. A escolhida entra no texto como [Nome](https://seu-site/pagina) e vira link clicável. Sem resultado, a pessoa pode colar um link de fora.
POST https://meusite.com/qorum/busca
X-Qorum-Event: links.search
X-Qorum-Timestamp: 1794171698
X-Qorum-Signature: sha256=... (mesma assinatura dos webhooks)
{ "q": "solo lev", "site": "meu-blog", "lang": "pt" }
// resposta 200: até 8 resultados
{ "results": [
{ "title": "Solo Leveling", "url": "https://meusite.com/obra/solo-leveling",
"image": "https://meusite.com/capas/solo.webp", "subtitle": "Manhwa" }
] }
Responda em até 4 segundos. O Qorum guarda cada busca por 5 minutos. Ligue informando o endereço em Configurações → API de busca do seu site (ou {"config": {"apiBusca": "https://..."}}) e teste em Testar conexão → API de busca.
Quando a mudança precisa aparecer na hora
A API de dados atualiza em até 30 minutos. Se alguém comprou algo e precisa ver o novo visual imediatamente, avise o Qorum logo depois da compra com PUT /v1/site/users/:userId/card na API de gerência. Para muita gente de uma vez (uma migração, um selo novo para todos), use PUT /v1/site/users/cards, com até 1000 pessoas por pedido no mesmo formato desta resposta.