Existem vários guias que cobrem diversos usos ou explicações da API.
Este oferece exemplos práticos e abrangentes sobre como utilizá-la.
Todos os exemplos de código neste guia não têm a intenção de demonstrar boas práticas ou serem usados exatamente como estão.
Muitas verificações, tratamento de erros e outros elementos são intencionalmente ignorados ou omitidos para focar puramente no uso da API.
Para que a API é usada?
A maioria das suas ações no Discourse (publicar, curtir, editar uma configuração, etc.) é realizada por meio da API, fazendo solicitações a um endpoint[1].
Por exemplo, quando você cria um tópico no meta, uma solicitação POST é enviada para https://meta.discourse.org/posts.json. A solicitação contém, entre outras coisas, o autor, o título, a categoria, as tags e o conteúdo da sua postagem.
Fazer uso personalizado da API geralmente é feito para realizar tarefas automatizadas e frequentemente em conjunto com outros serviços, como webhooks, scripts, softwares de terceiros e APIs.
Para usar a API, é obrigatório possuir credenciais de API. Isso pode ser feito em alguns cliques, seguindo este guia: Create and configure an API key
Não espere mais e vamos para um primeiro exemplo de caso de uso da API. ![]()
Criando um tópico mensal
Neste exemplo, usaremos curl e cron para criar um tópico mensal de “conversa livre” no seu fórum. Uma prática popular em comunidades online ![]()
Criar a chave da API
Siga o guia de criação de chave da API. Defina o Nível de Usuário como Usuário Único.
O usuário escolhido será o autor do tópico mensal.
Em seguida, você pode optar por um escopo Global ou um escopo Granular. No caso deste último, ele precisará ter pelo menos o acesso Tópicos → escrever.
Anote sua Chave de API gerada. ![]()
Criar um comando curl
No terminal do seu servidor, execute este comando para verificar se está funcionando e se um tópico é criado corretamente usando curl e a API REST do Discourse com sua chave de API:
curl -X POST "https://seu-discourse.com/posts.json" -H "Content-Type: application/json" -H "Api-Key: SUA_CHAVE_API" -H "Api-Username: SEU_USUARIO" -d "{\"title\": \"Criação de tópico de teste com a API\", \"raw\": \"E aqui está o conteúdo do tópico\", \"category\": ID_CATEGORIA }"
Substitua:
seu-discourse.compelo domínio do seu fórumSUA_CHAVE_APIpela sua chave de APISEU_USUARIOpelo nome de usuário escolhido para a chave de APIID_CATEGORIApelo ID da categoria onde deseja publicar seu tópico.
Se tudo estiver configurado corretamente, um novo tópico de teste será criado no seu fórum, como:
A maior parte do trabalho já foi feita nesta etapa! Agora precisamos alterar o título e o conteúdo do tópico para algo mais apropriado e configurar a recorrência da criação do tópico.
Comece alterando o título do tópico de:
Criação de tópico de teste com a API
para:
Conversa livre do mês - $(date +\%B).
Faça o mesmo para o conteúdo, alterando de:
Criação de tópico de teste com a API
para:
O que você mais e menos apreciou durante $(date +\%B -d 'last month')?\nSinta-se à vontade para compartilhar seus sentimentos e fornecer ideias. 🙂
Estou usando o comando Unix date para inserir o nome do mês atual no título e o nome do mês anterior no conteúdo.
\n no conteúdo cria uma nova linha.
Você pode usar o terminal e executar a solicitação curl atualizada. Ela deve ter criado um novo tópico como este no seu fórum:
Configurar o evento recorrente
Vamos criar uma tarefa cron que executará o comando curl no primeiro dia de cada mês. ![]()
Edite o arquivo cron com o seguinte comando:
crontab -e
Insira esta linha no final do arquivo (substitua o conteúdo da solicitação conforme necessário) e salve a modificação.
0 0 1 * * curl -X POST "https://seu-discourse.com/posts.json" -H "Content-Type: application/json" -H "Api-Key: SUA_CHAVE_API" -H "Api-Username: SEU_USUARIO" -d "{\"title\": \"Conversa livre do mês - $(date +\%B)\", \"raw\": \"O que você mais e menos apreciou durante $(date +\%B -d 'last month')?\nSinta-se à vontade para compartilhar seus sentimentos e fornecer ideias. 🙂\", \"category\": 4 }"
A parte 0 0 1 * * define o intervalo em que o comando será executado. Você pode aprender mais sobre a sintaxe aqui: https://crontab.guru
Está feito! Seu servidor agora criará um novo tópico de “conversa livre” no primeiro dia de cada mês, usando a API REST do Discourse, uma solicitação curl e uma tarefa cron. ![]()
Alterar automaticamente o esquema de cores de um tema
Vamos fazer com que nosso tema padrão use um esquema de cores que corresponda à estação atual
![]()
Usaremos Ruby para verificar os meses e uma tarefa cron para executar o script.
Poderíamos usar muitas outras maneiras além de Ruby e cron, mas este guia também visa mostrar como usar a API com várias ferramentas.
Preparar o tema e os esquemas de cores
Escolha o tema para o qual deseja alterar o esquema de cores e obtenha seu ID. Você encontrará o ID na URL do tema. Por exemplo, o ID deste tema é 1:
Crie 4 paletas de cores e anote também seus IDs.
Aqui, o ID da paleta de Outono é 17:
Criando o script
Instale o Ruby no seu servidor.
Crie um arquivo seasons.rb. Para este exemplo, considerarei que ele está em ~/scripts/.
Coloque o seguinte conteúdo neste arquivo. Faremos uma solicitação PUT para nosso endpoint de tema e enviaremos um payload contendo o ID do esquema de cores:
require 'net/http'
require 'json'
require 'date'
current_month = Date.today.month
color_scheme_id = case current_month
when 1..3 then 18 # Inverno
when 4..6 then 15 # Primavera
when 7..9 then 16 # Verão
else 17 # Outono
end
uri = URI('https://seu-discourse.com/admin/themes/THEME_ID.json')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Put.new(uri, {
'Api-Key' => 'SUA_CHAVE_API',
'Api-Username' => 'SEU_USUARIO',
'Content-Type' => 'application/json'
})
request.body = JSON.generate({
"theme" => {
"color_scheme_id" => color_scheme_id
}
})
response = http.request(request)
Substitua:
seu-discourse.compelo domínio do seu fórumSUA_CHAVE_APIpela sua chave de APISEU_USUARIOpelo nome de usuário escolhido para a chave de APITHEME_IDpelo ID do seu tema. Você pode encontrá-lo no final da URL da página de configurações do tema.
Por exemplo, emhttps://seu-discourse.com/admin/customize/themes/38, o ID do tema é38.
Vamos testar manualmente seu script.
Primeiro, defina-o para um esquema de cores não sazonal na interface do Discourse, caso ainda não esteja.
Em seguida, execute o script com o seguinte comando:
ruby ~/scripts/seasons.rb
Atualize seu navegador. O esquema de cores usado pelo seu tema deve ter sido alterado. ![]()
A última coisa a fazer é criar o trabalho cron que executará este script no primeiro dia do mês em cada mudança de estação.
Dê uma olhada no primeiro exemplo se não lembrar como criar uma tarefa cron.
0 0 1 1,4,7,10 * ruby ~/scripts/seasons.rb
Está feito! Seu fórum agora terá novas cores no início de cada nova estação!
![]()
Receber uma solicitação web em um servidor web e usar seus dados para atualizar um tópico do Discourse
Este é mais complexo! ![]()
Nossa ferramenta será PHP, o que significa que assumiremos que você tem um servidor web funcional em algum lugar com PHP instalado.
Neste exemplo, receberemos um payload de webhook do Ko-Fi (um serviço de doações) em uma página PHP, que então usará os dados recebidos para usar a API do Discourse e atualizar o título e o conteúdo de um tópico.
Mais especificamente, atualizará o título do tópico com o valor e a data da doação e adicionará uma nova linha à tabela que lista as doações anteriores (até mesmo empurrará o tópico automaticamente
):
Sempre que um usuário fizer uma doação, o Ko-Fi[2] enviará uma solicitação para nosso script PHP.
Configurando o Ko-Fi
Configurei a configuração na página de webhooks do Ko-Fi simplesmente adicionando a URL do meu arquivo PHP e anotando o token de verificação oculto na seção Avançado.
Em uma doação única, o Ko-Fi enviará um payload como este para nosso script PHP:
data = {
"verification_token": "d8546b84-c698-4df5-9811-39d35813e2ff",
"message_id": "a499df4c-7bbb-4061-b4a6-8b9d969da689",
"timestamp": "2023-10-19T13:35:06Z",
"type": "Donation",
"is_public": true,
"from_name": "Jo Example",
"message": "Good luck with the integration!",
"amount": "3.00",
"url": "https://ko-fi.com/Home/CoffeeShop?txid=00000000-1111-2222-3333-444444444444",
"email": "jo.example@example.com",
"currency": "USD",
"is_subscription_payment": false,
"is_first_subscription_payment": false,
"kofi_transaction_id": "00000000-1111-2222-3333-444444444444",
"shop_items": null,
"tier_name": null,
"shipping": null
}
Vamos receber este payload e depois extrair as duas informações de que precisamos:
-
O valor (
3.00), que arredondaremos para um número inteiro. -
O timestamp (
2023-10-19T13:35:06Z), que formataremos em uma data mais agradável.
Receber o payload do Ko-Fi
Primeiro, colocamos o seguinte código em nossa página PHP para receber a solicitação do Ko-Fi, onde garantimos que recebemos uma solicitação POST e que o valor do token corresponde ao fornecido na página de webhooks do Ko-Fi. Também formatamos o valor e a data como dito anteriormente.
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$jsonData = json_decode($_POST['data'], true);
if ($jsonData['verification_token'] === 'SEU_TOKEN_VERIFICACAO') {
$amount = floor(floatval($jsonData['amount']));
$date = (new DateTime($jsonData['timestamp']))->format('d/m/Y');
}
}
Substitua:
SEU_TOKEN_VERIFICACAOpelo token fornecido pelo Ko-Fi
Atualizar o título do tópico
A próxima etapa é atualizar o título do nosso tópico. Usaremos curl em nosso script PHP para fazer uma solicitação PUT para o endpoint correto.
$putData = json_encode(['title' => '🥳 Nova doação: ' . $amount . '€ em ' . $date]);
$ch = curl_init('https://seu-discourse.com/t/test-new-topic/ID_DO_TOPICO');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $putData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($putData),
'Api-Key: SUA_CHAVE_API',
'Api-Username: SEU_USUARIO'
]);
curl_exec($ch);
Substitua:
seu-discourse.compelo domínio do seu fórumID_DO_TOPICOpelo ID correto do tópicoSUA_CHAVE_APIpela sua chave de APISEU_USUARIOpelo nome de usuário escolhido para a chave de API
Atualizar o conteúdo da postagem
Para poder adicionar novo conteúdo à primeira postagem do tópico, precisamos primeiro recuperar seu conteúdo atual com uma solicitação GET.
$ch_get = curl_init('https://seu-discourse.com/posts/ID_DA_POSTAGEM.json');
curl_setopt($ch_get, CURLOPT_RETURNTRANSFER, true);
$currentContent = json_decode(curl_exec($ch_get), true)['raw'];
Substitua:
ID_DA_POSTAGEMpelo ID correto da postagem[3]
Finalmente, precisamos atualizar o conteúdo da postagem adicionando uma nova linha à tabela com o valor e a data. Faremos isso com uma solicitação PUT.
$updatedContent = $currentContent . "\n| " . $amount . "€ | " . $date . " |";
$putPostData = json_encode(['post' => ['raw' => $updatedContent]]);
$ch_put = curl_init('https://seu-discourse.com/posts/ID_DA_POSTAGEM');
curl_setopt($ch_put, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch_put, CURLOPT_POSTFIELDS, $putPostData);
curl_setopt($ch_put, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($putPostData),
'Api-Key: SUA_CHAVE_API',
'Api-Username: SEU_USUARIO'
]);
curl_exec($ch_put);
Substitua:
seu-discourse.compelo domínio do seu fórumID_DA_POSTAGEMpelo ID correto da postagemSUA_CHAVE_APIpela sua chave de APISEU_USUARIOpelo nome de usuário escolhido para a chave de API
O código final fica assim:
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$jsonData = json_decode($_POST['data'], true);
if ($jsonData['verification_token'] === 'SEU_TOKEN_VERIFICACAO') {
$amount = floor(floatval($jsonData['amount']));
$date = (new DateTime($jsonData['timestamp']))->format('d/m/Y');
$putData = json_encode(['title' => '🥳 Nova doação: ' . $amount . '€ em ' . $date]);
$ch = curl_init('https://seu-discourse.com/t/test-new-topic/ID_DO_TOPICO');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $putData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($putData),
'Api-Key: SUA_CHAVE_API',
'Api-Username: SEU_USUARIO'
]);
curl_exec($ch);
$ch_get = curl_init('https://seu-discourse.com/posts/ID_DA_POSTAGEM.json');
curl_setopt($ch_get, CURLOPT_RETURNTRANSFER, true);
$currentContent = json_decode(curl_exec($ch_get), true)['raw'];
$updatedContent = $currentContent . "\n| " . $amount . "€ | " . $date . " |";
$putPostData = json_encode(['post' => ['raw' => $updatedContent]]);
$ch_put = curl_init('https://seu-discourse.com/posts/ID_DA_POSTAGEM');
curl_setopt($ch_put, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch_put, CURLOPT_POSTFIELDS, $putPostData);
curl_setopt($ch_put, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Content-Length: ' . strlen($putPostData),
'Api-Key: SUA_CHAVE_API',
'Api-Username: SEU_USUARIO'
]);
curl_exec($ch_put);
curl_close($ch);
curl_close($ch_get);
curl_close($ch_put);
} else {
http_response_code(403);
echo "Token de verificação inválido.";
}
} else {
http_response_code(405);
echo "Apenas solicitações POST são permitidas.";
}
?>
Deixe-me enfatizar novamente o aviso no início deste guia ![]()
Todos os exemplos de código neste guia não têm a intenção de demonstrar boas práticas ou serem usados exatamente como estão.
Muitas verificações, tratamento de erros e outros elementos são intencionalmente ignorados ou omitidos para focar puramente no uso da API.
Agora podemos acionar uma solicitação de teste do Ko-Fi e ver como ela atualiza nosso tópico, tanto no título quanto no conteúdo. ![]()
É isso!
Você tem um tópico que será atualizado e empurrado sempre que alguém fizer uma doação no Ko-Fi! ![]()
Este tópico é um wiki. Sinta-se à vontade para corrigir qualquer erro que encontrar e discutir como este guia pode ser melhorado.
Uma URL específica, neste contexto. Por exemplo,
https://seu-discourse.com/posts.json↩︎Um pouco de informação sobre a API deles: https://help.ko-fi.com/hc/en-us/articles/360004162298-Does-Ko-fi-Have-an-API-or-Webhook- ↩︎
O ID da postagem pode ser encontrado no código HTML. É um elemento
<article>com o seguinte atributo:data-post-id="ID_DA_POSTAGEM"↩︎





