Executando verificação de segurança...
66

Documentação da API do TabNews

Visão Geral:

- ATENÇÃO: a API passou por mudanças e, portanto, esta documentação não está completa e pode apresentar erros.

Change log

  • (10/09/2022) - Formatação alterada e atualizadas as funções da API.

Introdução

Todo TabNews foi construído através de APIs públicas e você pode consumir elas da forma que desejar (respeitando as políticas de uso).

A comunicação é feita através de HTTPS usando GET ou POST. Tanto a solicitação quanto a resposta são formatadas como JSON e o tipo de conteúdo de ambas é application/json.

⚠ Para requisições do tipo POST, parâmetros não inclusos na URL devem ser inseridos como um Content-Type de application/json.

Base URL

Todas as URLs incluídas nessa documentação exigem a baseUrl:

https://www.tabnews.com.br/api/v1


Obter conteúdos

Lista de conteúdos da página inicial

GET {{BaseUrl}}/contents?page={pagina}&per_page={porPagina}&strategy={estrategia}
ParâmetroDescrição
{pagina}O número da página que você deseja acessar.
{porPagina}O número de conteúdos que devem ser retornados por página.
{estrategia}Ordem de classificação dos conteúdos, pode ser definida em new, old e relevant.

Lista de conteúdos de um determinado usuário

GET {{BaseUrl}}/{user}?page={pagina}&per_page={porPagina}&strategy={estrategia}
ParâmetroDescrição
{username}O username do usuário que você quer acessar os conteúdos.
{pagina}O número da página que você deseja acessar.
{porPagina}O número de conteúdos que devem ser retornados por página.
{estrategia}Ordem de classificação dos conteúdos, pode ser definida em new, old e relevant.

Obter conteúdo e dados de uma publicação

GET {{BaseUrl}}/contents/{user}/{slug}
ParâmetroDescrição
{user}Usuário que você deseja obter o post.
{slug}Slug do post que você deseja obter.

Obter comentários de uma publicação

GET {{BaseUrl}}/contents/{user}/{slug}/children
Parâmetros
{user}Usuário dono do postque você deseja obter os comentários.
{slug}Slug do post que você deseja obter os comentários.

Obter thumbnail de uma publicação

GET {{BaseUrl}}/contents/{user}/{slug}/thumbnail
Parâmetros
{user}Usuário dono do post que você deseja obter a thumbnail.
{slug}Slug do post que você deseja obter a thumbnail.


Status

Para obter quantos usuários foram criados (por dia):

GET {{BaseUrl}}/analytics/users-created

Para obter quantas publicações foram feitas (por dia):

GET {{BaseUrl}}/analytics/root-content-published

Para obter quantos usuários foram criados (por dia):

GET {{BaseUrl}}/analytics/child-content-published


Autenticação

Criar usuário

POST {{BaseUrl}}/users

Corpo da requisição:

ParâmetroTipoDescrição
usernamestringO username do usuário que você quer criar.
emailstringUm email válido que será usado para o login e outras opções.
passwordstringA senha do usuário que você quer criar.

⚠ Para confirmar a conta, o usuário deve acessar o link de verificação que foi enviado para o email. ⚠

Logar usuário

Depois que o email for verificado, a requisição deve ser feita para este endpoint:

POST {{BaseUrl}}/sessions

Corpo da requisição:

ParâmetroTipoDescrição
emailstringO email no qual o usuário foi criado.
passwordstringA senha que foi definida na criação do usuário.
Exemplo de resposta
{
  "id": "6fbeca8f-13f1-43e3-b3**-************",
  "token": "e5fba39f8c4ec21cfd50d94ec8f659ed3258e301afe51240786d9ecddc8d35aeecae391ffe73e38d8c**************",
  "expires_at": "yyyy-mm-ddT14:34:08.664Z",
  "created_at": "yyyy-mm-ddT14:34:08.664Z",
  "updated_at": "yyyy-mm-ddT14:34:08.664Z"
}
Exemplo de resposta com erro
{
  "name": "UnauthorizedError",
  "message": "Dados não conferem.",
  "action": "Verifique se os dados enviados estão corretos.",
  "status_code": 401,
  "error_id": "4a61276a-8dfc-41cc-a563-7fa4975*****",
  "request_id": "fe12a267-aa3c-4fad-8375-2fe92d6*****",
  "error_location_code": "CONTROLLER:SESSIONS:POST_HANDLER:DATA_MISMATCH"
}

Recuperar senha

POST {{BaseUrl}}/recovery

Corpo da requisição:

ParâmetroTipoDescrição
usernamestringO username do usuário que você deseja recuperar a senha.
emailstringO email do usuário que você deseja recuperar a senha.

⚠ Apenas 1 dos valores devem ser passados na requisição. O usuário receberá uma link no email para a recuperação da senha.



Editar perfil

Para alteração de qualquer informação, a requisição deve ser feita para o seguinte endpoint, onde {username} é o username atual do usuário que você deseja alterar as informações:

POST {{BaseUrl}}/users/{username}

Corpo da requisição:

Todos os parâmetros são opcionais, ou seja, você só precisa enviar o parâmetro da informação que você deseja mudar.

ParâmetrosTipoDescrição
usernamestringPara alterar o nome de usuário.
emailstringPara alterar o email do usuário (ele precisará ser verifificar da mesma forma que foi verificado na criação do usuário).
passwordstringPara alterar a senha do usuário.
notificationsbooleanPara alterar se o usuário deseja receber notificações via email, ou não.


Publicar conteúdos

{{BaseUrl}}/contents

Cabeçalho da requisição:

ParâmetroValorDescrição
Set-Cookiesession_id={seuSessionID}{seuSessionID} é o session_id que foi obtido na resposta ao fazer login.

Corpo da requisição:

ParâmetroTipoDescrição
titlestringO título da publicação. *Obrigatório
bodystringO corpo da sua publicação, com formatação em Markdown ou HTML. *Obrigatório
statusstringPara o conteúdo realmente ser publicado, o valor deve ser published. *Obrigatório
source_urlstringO link que vai ficar como fonte de seu post, no formato https://example.com. Caso não seja definido, a fonte ficará em branco.
slugstringO slug do seu post. Caso não seja definido, o slug será gerado automaticamente com base no título da publicação.

Bom, em breve devem ser adicionadas aqui as funções de alterar senha, alterar username, fazer comentários, editar posts, além da função de publicar conteúdos (que eu testei de várias formas e deu diversos erros, de permissão, de PATCH ou de sintaxe mesmo).

edit: Todas essas funções já foram adicionadas aqui.

Uma pergunta ao @filipedeschamps, onde essa documentação deve ser adicionada? No GitHub?

Quaisquer sugestões ou alterações vocês podem comentar e serão muito bem vindas.

4

Cara, sensacional! Essa documentação é patrimônio nacional 🤩

Uma dúvida, testei a url https://www.tabnews.com.br/api/v1/contents/analytics/users-created aqui no browser google chrome e me retornou essa mensagem:

{"name":"NotFoundError","message":"O \"username\" informado não foi encontrado no sistema.","action":"Verifique se o \"username\" está digitado corretamente.","status_code":404,"error_id":"601eb514-4b6f-45ee-a216-88e7017f34cb","request_id":"40911d5d-87f1-4df7-8691-4dbecaf5d375","error_location_code":"MODEL:USER:FIND_ONE_BY_USERNAME:NOT_FOUND","key":"username"}

O que poderia ser isso?

4

O caminho está incorreto.
Os dados de analytics ficam na raiz e não dentro do content.

https://tabnews.com.br/api/v1/analytics/users-created
https://tabnews.com.br/api/v1/analytics/root-content-published
https://tabnews.com.br/api/v1/analytics/child-content-published
1

verdade, obrigado! vou corrigir.

edit: corrigido! Também me enganei ao colocar que eram por dia no ultimo mês, porém não é só no último mês. Já corrigi.

2

Muito obrigado misters @agjunior e @GabrielSozinho, agora sim está sucesso! Testei todos estes endpoints e estão retornando corretamente os valores das métricas.

Exemplo dos Retornos

https://tabnews.com.br/api/v1/analytics/users-created

[{"date":"18/03","cadastros":49},{"date":"19/03","cadastros":6},{"date":"20/03","cadastros":1},{"date":"21/03","cadastros":3},{"date":"22/03","cadastros":2},{"date":"23/03","cadastros":1},{"date":"24/03","cadastros":0},{"date":"25/03","cadastros":0},{"date":"26/03","cadastros":0},{"date":"27/03","cadastros":1},{"date":"28/03","cadastros":3},{"date":"29/03","cadastros":0},{"date":"30/03","cadastros":1},{"date":"31/03","cadastros":0},{"date":"01/04","cadastros":4},{"date":"02/04","cadastros":0},{"date":"03/04","cadastros":1},{"date":"04/04","cadastros":8},{"date":"05/04","cadastros":2},{"date":"06/04","cadastros":0},{"date":"07/04","cadastros":2},{"date":"08/04","cadastros":0},{"date":"09/04","cadastros":0},{"date":"10/04","cadastros":0},{"date":"11/04","cadastros":1},{"date":"12/04","cadastros":1},{"date":"13/04","cadastros":1},{"date":"14/04","cadastros":0},{"date":"15/04","cadastros":0},{"date":"16/04","cadastros":0},{"date":"17/04","cadastros":0},{"date":"18/04","cadastros":0},{"date":"19/04","cadastros":0},{"date":"20/04","cadastros":0},{"date":"21/04","cadastros":0},{"date":"22/04","cadastros":1},{"date":"23/04","cadastros":0},{"date":"24/04","cadastros":0},{"date":"25/04","cadastros":3},{"date":"26/04","cadastros":0},{"date":"27/04","cadastros":1},{"date":"28/04","cadastros":1},{"date":"29/04","cadastros":1},{"date":"30/04","cadastros":2},{"date":"01/05","cadastros":1},{"date":"02/05","cadastros":2},{"date":"03/05","cadastros":0},{"date":"04/05","cadastros":1},{"date":"05/05","cadastros":0},{"date":"06/05","cadastros":42},{"date":"07/05","cadastros":6},{"date":"08/05","cadastros":4},{"date":"09/05","cadastros":21},{"date":"10/05","cadastros":24},{"date":"11/05","cadastros":14},{"date":"12/05","cadastros":9},{"date":"13/05","cadastros":22},{"date":"14/05","cadastros":12},{"date":"15/05","cadastros":6},{"date":"16/05","cadastros":306},{"date":"17/05","cadastros":172},{"date":"18/05","cadastros":114},{"date":"19/05","cadastros":84},{"date":"20/05","cadastros":44},{"date":"21/05","cadastros":29},{"date":"22/05","cadastros":25},{"date":"23/05","cadastros":36},{"date":"24/05","cadastros":24},{"date":"25/05","cadastros":22},{"date":"26/05","cadastros":29},{"date":"27/05","cadastros":34},{"date":"28/05","cadastros":17},{"date":"29/05","cadastros":17},{"date":"30/05","cadastros":51},{"date":"31/05","cadastros":46},{"date":"01/06","cadastros":36},{"date":"02/06","cadastros":24},{"date":"03/06","cadastros":18},{"date":"04/06","cadastros":6},{"date":"05/06","cadastros":14},{"date":"06/06","cadastros":15},{"date":"07/06","cadastros":14},{"date":"08/06","cadastros":12},{"date":"09/06","cadastros":16},{"date":"10/06","cadastros":14},{"date":"11/06","cadastros":14},{"date":"12/06","cadastros":14},{"date":"13/06","cadastros":24},{"date":"14/06","cadastros":16},{"date":"15/06","cadastros":10},{"date":"16/06","cadastros":9},{"date":"17/06","cadastros":9},{"date":"18/06","cadastros":15},{"date":"19/06","cadastros":10},{"date":"20/06","cadastros":14},{"date":"21/06","cadastros":11},{"date":"22/06","cadastros":10},{"date":"23/06","cadastros":52},{"date":"24/06","cadastros":55},{"date":"25/06","cadastros":19},{"date":"26/06","cadastros":13},{"date":"27/06","cadastros":23},{"date":"28/06","cadastros":17},{"date":"29/06","cadastros":13},{"date":"30/06","cadastros":13},{"date":"01/07","cadastros":13},{"date":"02/07","cadastros":10},{"date":"03/07","cadastros":11},{"date":"04/07","cadastros":18},{"date":"05/07","cadastros":13},{"date":"06/07","cadastros":16},{"date":"07/07","cadastros":16},{"date":"08/07","cadastros":11},{"date":"09/07","cadastros":10},{"date":"10/07","cadastros":5},{"date":"11/07","cadastros":12},{"date":"12/07","cadastros":9},{"date":"13/07","cadastros":5},{"date":"14/07","cadastros":15},{"date":"15/07","cadastros":9},{"date":"16/07","cadastros":11},{"date":"17/07","cadastros":10},{"date":"18/07","cadastros":7},{"date":"19/07","cadastros":11},{"date":"20/07","cadastros":24},{"date":"21/07","cadastros":18},{"date":"22/07","cadastros":11},{"date":"23/07","cadastros":7},{"date":"24/07","cadastros":6},{"date":"25/07","cadastros":5}]

https://tabnews.com.br/api/v1/analytics/root-content-published

[{"date":"04/05","conteudos":1},{"date":"05/05","conteudos":0},{"date":"06/05","conteudos":6},{"date":"07/05","conteudos":3},{"date":"08/05","conteudos":0},{"date":"09/05","conteudos":5},{"date":"10/05","conteudos":9},{"date":"11/05","conteudos":6},{"date":"12/05","conteudos":9},{"date":"13/05","conteudos":11},{"date":"14/05","conteudos":3},{"date":"15/05","conteudos":1},{"date":"16/05","conteudos":29},{"date":"17/05","conteudos":23},{"date":"18/05","conteudos":23},{"date":"19/05","conteudos":12},{"date":"20/05","conteudos":18},{"date":"21/05","conteudos":6},{"date":"22/05","conteudos":5},{"date":"23/05","conteudos":11},{"date":"24/05","conteudos":13},{"date":"25/05","conteudos":18},{"date":"26/05","conteudos":7},{"date":"27/05","conteudos":7},{"date":"28/05","conteudos":5},{"date":"29/05","conteudos":2},{"date":"30/05","conteudos":15},{"date":"31/05","conteudos":15},{"date":"01/06","conteudos":16},{"date":"02/06","conteudos":15},{"date":"03/06","conteudos":3},{"date":"04/06","conteudos":4},{"date":"05/06","conteudos":7},{"date":"06/06","conteudos":5},{"date":"07/06","conteudos":14},{"date":"08/06","conteudos":5},{"date":"09/06","conteudos":12},{"date":"10/06","conteudos":6},{"date":"11/06","conteudos":5},{"date":"12/06","conteudos":1},{"date":"13/06","conteudos":9},{"date":"14/06","conteudos":9},{"date":"15/06","conteudos":14},{"date":"16/06","conteudos":9},{"date":"17/06","conteudos":7},{"date":"18/06","conteudos":3},{"date":"19/06","conteudos":4},{"date":"20/06","conteudos":8},{"date":"21/06","conteudos":6},{"date":"22/06","conteudos":6},{"date":"23/06","conteudos":7},{"date":"24/06","conteudos":18},{"date":"25/06","conteudos":2},{"date":"26/06","conteudos":6},{"date":"27/06","conteudos":5},{"date":"28/06","conteudos":4},{"date":"29/06","conteudos":14},{"date":"30/06","conteudos":10},{"date":"01/07","conteudos":4},{"date":"02/07","conteudos":2},{"date":"03/07","conteudos":10},{"date":"04/07","conteudos":18},{"date":"05/07","conteudos":16},{"date":"06/07","conteudos":13},{"date":"07/07","conteudos":13},{"date":"08/07","conteudos":15},{"date":"09/07","conteudos":7},{"date":"10/07","conteudos":1},{"date":"11/07","conteudos":7},{"date":"12/07","conteudos":11},{"date":"13/07","conteudos":9},{"date":"14/07","conteudos":13},{"date":"15/07","conteudos":12},{"date":"16/07","conteudos":5},{"date":"17/07","conteudos":2},{"date":"18/07","conteudos":10},{"date":"19/07","conteudos":11},{"date":"20/07","conteudos":17},{"date":"21/07","conteudos":10},{"date":"22/07","conteudos":10},{"date":"23/07","conteudos":3},{"date":"24/07","conteudos":4},{"date":"25/07","conteudos":1}]

https://tabnews.com.br/api/v1/analytics/child-content-published

[{"date":"04/05","respostas":3},{"date":"05/05","respostas":2},{"date":"06/05","respostas":27},{"date":"07/05","respostas":3},{"date":"08/05","respostas":4},{"date":"09/05","respostas":14},{"date":"10/05","respostas":27},{"date":"11/05","respostas":32},{"date":"12/05","respostas":29},{"date":"13/05","respostas":16},{"date":"14/05","respostas":34},{"date":"15/05","respostas":6},{"date":"16/05","respostas":127},{"date":"17/05","respostas":103},{"date":"18/05","respostas":173},{"date":"19/05","respostas":66},{"date":"20/05","respostas":154},{"date":"21/05","respostas":39},{"date":"22/05","respostas":57},{"date":"23/05","respostas":70},{"date":"24/05","respostas":61},{"date":"25/05","respostas":59},{"date":"26/05","respostas":54},{"date":"27/05","respostas":33},{"date":"28/05","respostas":21},{"date":"29/05","respostas":14},{"date":"30/05","respostas":87},{"date":"31/05","respostas":70},{"date":"01/06","respostas":72},{"date":"02/06","respostas":24},{"date":"03/06","respostas":32},{"date":"04/06","respostas":27},{"date":"05/06","respostas":32},{"date":"06/06","respostas":38},{"date":"07/06","respostas":39},{"date":"08/06","respostas":32},{"date":"09/06","respostas":45},{"date":"10/06","respostas":27},{"date":"11/06","respostas":26},{"date":"12/06","respostas":22},{"date":"13/06","respostas":53},{"date":"14/06","respostas":13},{"date":"15/06","respostas":36},{"date":"16/06","respostas":31},{"date":"17/06","respostas":15},{"date":"18/06","respostas":22},{"date":"19/06","respostas":10},{"date":"20/06","respostas":42},{"date":"21/06","respostas":18},{"date":"22/06","respostas":30},{"date":"23/06","respostas":39},{"date":"24/06","respostas":71},{"date":"25/06","respostas":16},{"date":"26/06","respostas":22},{"date":"27/06","respostas":41},{"date":"28/06","respostas":18},{"date":"29/06","respostas":37},{"date":"30/06","respostas":14},{"date":"01/07","respostas":16},{"date":"02/07","respostas":10},{"date":"03/07","respostas":25},{"date":"04/07","respostas":82},{"date":"05/07","respostas":47},{"date":"06/07","respostas":38},{"date":"07/07","respostas":26},{"date":"08/07","respostas":40},{"date":"09/07","respostas":22},{"date":"10/07","respostas":12},{"date":"11/07","respostas":45},{"date":"12/07","respostas":37},{"date":"13/07","respostas":34},{"date":"14/07","respostas":46},{"date":"15/07","respostas":46},{"date":"16/07","respostas":23},{"date":"17/07","respostas":28},{"date":"18/07","respostas":33},{"date":"19/07","respostas":30},{"date":"20/07","respostas":30},{"date":"21/07","respostas":11},{"date":"22/07","respostas":42},{"date":"23/07","respostas":10},{"date":"24/07","respostas":3},{"date":"25/07","respostas":17}]
3

Testando aqui, me gerou uma dúvida. Tem alguma forma de filtrar o retorno para devolver somente os posts? para que não retorne os comentarios realizados em outras publicações junto? Digo direto pela API.

1

Antigamente apenas os posts eram fornecidos pela API. Hoje os comentários estão sendo enviados juntos, que eu saiba, não tem.

Mas uma sugestão que você já deve ter pensado, em sua aplicação é só filtrar os conteúdos que não possuem um parent_id, assim você vai conseguir apenas publicações "root".

1

Sim, eu estou fazendo isso. Mas é exatamente o que eu queria evitar, pois o front irá ficar processando n objetos e separando toda vez que fizer a request, o que dependendo da quantidade, pode penalizar o desempenho.

Se tivesse essa opção para já vir filtrado somente as publicações, seria uma "delicinha" 😅

Mas como ainda não é possível, dá pra ir quebrando um galho dessa forma mesmo. Creio que não irá demorar pra ser implementado algo do tipo.

De qualquer forma, multo obrigado pelo feedback! 🖖🤖

2

Sensacional Gabriel, meus sinceros parabéns pela contribuição!!!

Um detalhe importante para que seja economizado um redirect, é mudar a URL de:

https://tabnews.com.br

Para:

https://www.tabnews.com.br

Uma pergunta ao @filipedeschamps, onde essa documentação deve ser adicionada? No GitHub?

Eu queria fazer um teste adicionando no README do projeto, para que a pessoa que estiver lendo a porta de entrada principal repositório, já visse que temos uma API e ela é muito simples de usar, mas não sei exatamente como fazer para ficar legal.

2

@GabrielSozinho, mano ficou TOP essa documentação.

@filipedeschamps Hj mais cedo eu abri a issue #555 justamente dando uma ideia sobre isso rsrs.

Nele eu comentei que a gente poderia implementar a documentação da API a partir de alguma lib que implementa Open API, estilo a Redoc que é usada no BrasilAPI (que particularmente eu gosto muito desse formato de doc).

Aí unindo um pouco com a sua ideia de testar add no README do projeto, a gente poderia criar um tópico dentro dele dando um overview da API junto com algumas explicações gerais, e logo abaixo a gente direciona para a pessoa visitar a página da doc completa.

2
1
2

Oi GabrielSozinho, ficou muito bom a documentação do projeto.

No entanto, eu sugiro que para facilitar a compreensão dos usuários troque A API do TabNews é uma API que retorna divers... por A API do TabNews retorna divers..., desse modo acaba não havendo uma redundância.

Sucesso!!

1
1

Olá Gabriel! obrigado pelo seu post. Me ajudou demais até aqui. Só estou com um problema em uma aplicação, talvez você possa me ajudar. Ao pegar os dados com o axios me retona o seguinte problema no console:

Access to XMLHttpRequest at '<https://www.tabnews.com.br/api/v1/contents/jairotunisse?page=1&strategy=relevant>' from origin '<http://localhost:5173>' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

E continua com alguns erros:

`
https://www.tabnews.com.br/api/v1/contents/jairotunisse?page=1&strategy=relevant net::ERR_FAILED 429 (Too Many Requests)

xhr.js:163 Uncaught (in promise)
AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
fetchPosts @ index.tsx:39
await in fetchPosts (async)
(anonymous) @ index.tsx:43
Show 11 more frames
`

Meu código ficou assim:

`
async function fetchPosts() {
const response = await tabnews.get("contents/jairotunisse", {
params: {
page: 1,
strategy: "relevant",
},
});

const result = response.data.filter((post: any) => post.parent_id === null); // Para procurar somente meu post.

setPosts(result);

}

`

Estou consumindo a api com o axios e rodando o projeto com o vite. Sabe o que pode ser? Desde já muito obrigado.

0
1

Acho que seria interessante e até estimularia a galera a se utilizar mais das APIs se houvesse uma documentação mais explícita e de fácio acesso. Acho que o Swagger 2 (ou OpenAPI 3) serviriam bem. Além de ser uma abordagem legal pra apenas abrir a página e experimentar as requests, é uma maneira bem automatizada de manter a documentação sempre atualizada.

Também há a possibilidade de usar ferramentas como o Read The Docs, mas acho que seria mais trabalhoso.

A lib que eu vi o pessoal mais utilizando é essa aqui: next-swagger-doc. Eu experimentei e não tive problemas

Também tem o Redoc que parece ser interessante e mais bonitinho até ahha A maior vantagem dele é que a interface mobile é bem boa

1

Salve! Muito legal essa documentação e API, pretendo utilizá-la.

Sobre Obter conteúdos, os valores para old e new é em relação à criação do conteúdo ou à atualização do mesmo? Isto é, caso um conteúdo mais antigo e receba maior relevância ou respostas hoje, há como usar isso como critério?

Qual dica daria para quem gostaria de utilizar essa API sem que seja necessário checar se os conteúdos mais antigos foram atualizados?

2

Obrigado teomewhy! 😀

Os valores old e new se referem à data de criação das postagens.

E que eu saiba, não tem como ordenar os posts por data que receberam última resposta/foram atualizados. É uma boa ideia! Seria até legal criar uma issue no repositório sugerindo isso. O que acha?

Qual dica daria para quem gostaria de utilizar essa API sem que seja necessário checar se os conteúdos mais antigos foram atualizados?

Essa perguta eu não entendi muito bem 😕. No entanto, como eu disse ali, atualmente não há como ordenar posts por data de atualização.

Se o objetivo for sempre conseguir os conteúdos de forma atualizada e com os comentários mais recentes, basta fazer uma nova requisição. 👍

2

Perfeito! Super respondido! Seria ótimo ter um endpoint ou critério para ordenar os contents pela atualização.

Aproveito para perguntar, a atualização é referente à ediçãodo mesmo ou comentários e tabcoins também fazem a data de atualização ser alterada?

Valeu e obrigado pelos esclarecimentos.

1

Um bom ponto! Nunca tinha reparado, mas fazendo um teste, acredito que o valor de updated_at se refere a quando o conteúdo foi editado pela última vez. 👍

1
1
1

Opa, tudo bom?
Eu estava mexendo aqui na API e talvez seja útil adicionar a esse post como pegar as infos do user!

Informações do usuário


GET {{BaseUrl}}/user

Cabeçalho da requisição

ParâmetroValorDescrição
Cookiesession={{seuSessionID}}o {{seuSessionID}} é igual ao token recebido depois do login

Retorno

{
  "id": "be666c71-76ec-****-****-************",
  "username": "devlyh",
  "email": "devlyh.****@****.com",
  "notifications": true,
  "features": [
    "create:session",
    "read:session",
    "create:content",
    "create:content:text_root",
    "create:content:text_child",
    "update:content",
    "update:user"
  ],
  "tabcoins": 60,
  "tabcash": 2,
  "created_at": "2022-06-03T12:27:22.999Z",
  "updated_at": "2022-06-03T12:28:21.141Z"
}
1

Nossa, verdade! Eu mesmo fiz uma aplicação usando esse endpoint e não adicionei ele aqui 😅. (O que eu fiz foi o TabStats)

No entanto, estou trabalhando em uma nova documentação com um formato diferente, um formato que foi sugerido pelo Filipe la no Github.

1

Parabéns pela postagem Gabriel. Fiquei com uma dúvida: Se eu quisesse filtrar os posts de um usuário específico através de uma string passada em algum parâmetro, para por exemplo, buscar os posts que tem como título a string "Dicas". Tem alguma forma de fazer isso atualmente, ou não ?

1

Obrigado Matheus! Sobre a sua pergunta, diretamente usando a API do TabNews não. O que você pode fazer é solicitar todos os conteúdos de um usuário pela API, verificar quais tem um parent_id ou não (os que tem são comentários e os que não, são posts) e a partir daí fazer a busca pelo título. 👍🏻

1
1

eu ainda vou adicionar, mas você faz um POST para https://www.tabnews.com.br/api/v1/contents.

Ai no header você bota cookies com session_id={seusessionid}

e no body você bota

title: título, 
body: corpo do seu post,
source_url: link  de fonte (opcional),
status: published
1

Estou tentando fazer o post, mas não está dando certo... O que pode ser?

await axios.post(tabnews + '/contents', {
  title: article.title,
  body: `<p>${article.content}</p>`,
  status: "published",
  source_url: article.source
}, {
  headers: {
    cookies: `session_id=${user.token}`
  }
})
1
1

Consegui arrumar a internet aqui, esse erro que está dando:

data: {
    name: 'ForbiddenError',
    message: 'Usuário não pode executar esta operação.',
    action: 'Verifique se este usuário possui a feature "create:content".',
    status_code: 403,
    error_id: 'ac0ecc0c-0641-4001-975e-fc41754463b4',
    request_id: 'a0bbfb85-be29-48f3-a31b-95b5fbf5f8bb',
    error_location_code: 'MODEL:AUTHORIZATION:CAN_REQUEST:FEATURE_NOT_FOUND'
}

De acordo com o tópico, ele também não conseguiu fazer a chamada pra esse Endpoint.

2

Provavelmente você está enviando um session_id inválido. Eu já passei por isso no passado, não me lembro de como resolvi.

Você pode tentar entrar na comunidade do TabNews no Discord e pedir ajuda por lá: link

Ou então você pode criar uma issue lá no repositório.

1

Consegui! Era isso mesmo, vou deixar o código aqui pra caso alguém estiver passando pelo memso problema.

await axios.post(tabnews + '/contents', {
  title,
  body: content,
  status: "published",
  source_url: article.source
}, {
  headers: {
    Cookie: `session_id=${user.token}`
  }
})
1
1
1

Parabéns pela clareza da documentação! O interessante é que, um material desse, pode ser um ótimo treinamento com dados reais, gerando programa real, que realmente faz algo.

1
1
1

Tem sim, só que você precisa fazer o sistema que manda solicitações a cada página, já que o limite de publicações por request é 100. 😕

Você também pode usar o sistema que o Gustavo33 fez, tá público no GitHub que tá na fonte da publicação: https://www.tabnews.com.br/Gustavo33/arquivo-contendo-todos-os-conteudos-do-tabnews-e-algumas-curiosidades

Dá uma olhada lá. Por curiosidade, qual seria o uso disso? Digo isso porque talvez fosse melhor solicitar somente aa cada vez que precisasse. Existem muitas publicações e demoraria horas para obter todas elas, dependendo da velocidade da internet até dias.

De qualquer forma, espero ter ajudado e boa sorte com o seu projeto. 👍

1

Achei bem interessante a iniciativa da documentação da API. Fiquei com vontade de criar um plugin para Wordpress. Dei uma pesquisada rápida no diretório de plugins do Wordpress e não encontrei nada. Então, achei uma boa criar um plugin Wordpress para compartilhar os posts do blogs aqui no TabNews.

1

Sabe se é possível obter os votos de um post?

Sei que hoje temos o score total (diferença entre votos positivos e negativos), mas tem como saber quantos votos de cada tipo um post recebeu?

Eu queria fazer umas estatísticas dos dados de votação, já que recentemente mudaram as regras de pontuação e queria saber se isso vai ter impacto na forma como as pessoas votam.

1

Boa noite, kht! Desculpe a demora pra responder.

Até onde eu sei, não é possível fazer essa separação pra saber quantos votos positivos/negativos cada publicação resolveu.

No entanto, ando meio afastado do TabNews por questões pessoais, então é possível que isso tenha sido adicionado e eu não saiba. O melhor que você pode fazer é criar uma issue no GitHub do projeto fazendo essa pergunta.

No mais, que baita ideia de "pesquisa"! Se conseguir extrair alguma coisa, seria bastante interessante de postar aqui no TabNews. 😆

Espero ter ajudado, até mais! 🤝