Documentação da API - Tribuna VTuber

Esta documentação explica como integrar os feeds RSS, Atom, JSON e sitemaps da Tribuna VTuber em seu site ou sistema.

Introdução

A Tribuna VTuber oferece várias formas de acessar nosso conteúdo programaticamente:

  • Feeds RSS 2.0 - Padrão tradicional para sindicação de conteúdo
  • Feeds Atom 1.0 - Padrão moderno e extensível
  • JSON Feed 1.1 - Formato JSON para aplicações modernas
  • Sitemaps XML - Para indexação por motores de busca
  • Google News Sitemap - Específico para Google News
  • Dados Estruturados - Schema.org para rich snippets
Base URL: https://tribunavtuber.com.br

Feeds RSS/Atom

Os feeds RSS e Atom fornecem acesso às últimas notícias em formato XML padronizado.

Endpoints Disponíveis

GET /feed/rss

Feed RSS principal com todas as notícias

GET /feed/atom

Feed Atom principal com todas as notícias

GET /feed/rss/categoria/{categoria}

Feed RSS filtrado por categoria

GET /feed/atom/categoria/{categoria}

Feed Atom filtrado por categoria

GET /feed/rss/busca?q={termo}

Feed RSS com resultados de busca

Parâmetros de Query

Parâmetro Tipo Obrigatório Descrição
q string Sim (para busca) Termo de busca
limit number Não Número máximo de itens (padrão: 50)

Exemplo de Uso

Feed RSS Principal

https://tribunavtuber.com.br/feed/rss

Feed por Categoria

https://tribunavtuber.com.br/feed/rss/categoria/Eventos

Feed de Busca

https://tribunavtuber.com.br/feed/rss/busca?q=hololive

JSON Feed

O JSON Feed é um formato moderno que facilita a integração com aplicações JavaScript e APIs.

GET /feed/json

Feed JSON principal com todas as notícias

GET /feed/json/categoria/{categoria}

Feed JSON filtrado por categoria

GET /feed/json/busca?q={termo}

Feed JSON com resultados de busca

Estrutura do JSON Feed

{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Tribuna VTuber - Notícias VTuber",
  "description": "Portal de notícias dedicado à comunidade VTuber",
  "home_page_url": "https://tribunavtuber.com.br",
  "feed_url": "https://tribunavtuber.com.br/feed/json",
  "language": "pt-BR",
  "icon": "https://tribunavtuber.com.br/images/logo.png",
  "authors": [
    {
      "name": "Tribuna VTuber",
      "url": "https://tribunavtuber.com.br",
      "email": "[email protected]"
    }
  ],
  "items": [
    {
      "id": "https://tribunavtuber.com.br/noticia/exemplo",
      "url": "https://tribunavtuber.com.br/noticia/exemplo",
      "title": "Título da Notícia",
      "content_html": "Conteúdo em HTML...",
      "content_text": "Conteúdo em texto puro...",
      "summary": "Resumo da notícia",
      "date_published": "2024-01-01T12:00:00Z",
      "date_modified": "2024-01-01T12:00:00Z",
      "authors": [
        {
          "name": "Nome do Autor",
          "url": "https://tribunavtuber.com.br/u/autor"
        }
      ],
      "tags": ["VTuber", "Eventos"],
      "language": "pt-BR",
      "image": "https://tribunavtuber.com.br/images/thumbnail.jpg"
    }
  ]
}

Sitemaps XML

Os sitemaps XML ajudam motores de busca a indexar todo o conteúdo do site.

GET /sitemap.xml

Sitemap principal (redireciona para /sitemap/)

GET /sitemap/index.xml

Índice de todos os sitemaps

GET /sitemap/static.xml

Páginas estáticas do site

GET /sitemap/recent.xml

Artigos dos últimos 30 dias

Parâmetros de Paginação

Parâmetro Tipo Padrão Descrição
page number 1 Número da página
limit number 50000 Itens por página

Google News Sitemap

Sitemaps específicos para o Google News, otimizados para indexação de conteúdo jornalístico.

GET /news-sitemap.xml

Sitemap principal do Google News

GET /news-sitemap/today.xml

Artigos publicados hoje

GET /news-sitemap/weekly.xml

Artigos da última semana

GET /news-sitemap/popular.xml

Artigos mais populares

Critérios de Elegibilidade

  • Artigos publicados nos últimos 2 dias
  • Título entre 10 e 150 caracteres
  • Conteúdo original e não duplicado
  • Estrutura adequada para notícias

Dados Estruturados (Schema.org)

Todos os artigos incluem dados estruturados em formato JSON-LD para rich snippets nos motores de busca.

Tipos de Schema Implementados

  • NewsArticle - Para artigos individuais
  • NewsMediaOrganization - Para a organização
  • WebSite - Para o site principal
  • Person - Para perfis de usuários
  • BreadcrumbList - Para navegação
  • ItemList - Para listas de artigos

Exemplo de Schema NewsArticle

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "NewsArticle",
  "headline": "Título da Notícia",
  "description": "Descrição da notícia",
  "url": "https://tribunavtuber.com.br/noticia/exemplo",
  "datePublished": "2024-01-01T12:00:00Z",
  "dateModified": "2024-01-01T12:00:00Z",
  "author": {
    "@type": "Person",
    "name": "Nome do Autor",
    "url": "https://tribunavtuber.com.br/u/autor"
  },
  "publisher": {
    "@type": "NewsMediaOrganization",
    "name": "Tribuna VTuber",
    "logo": {
      "@type": "ImageObject",
      "url": "https://tribunavtuber.com.br/images/logo.png",
      "width": 200,
      "height": 60
    }
  },
  "image": {
    "@type": "ImageObject",
    "url": "https://tribunavtuber.com.br/images/thumbnail.jpg",
    "width": 1200,
    "height": 675
  },
  "articleSection": "Eventos",
  "keywords": "VTuber, Eventos, Hololive",
  "inLanguage": "pt-BR",
  "isAccessibleForFree": true
}
</script>

Integração

Headers HTTP

Os feeds retornam os seguintes headers:

Content-Type: application/rss+xml; charset=utf-8
Cache-Control: public, max-age=300
Last-Modified: Mon, 01 Jan 2024 12:00:00 GMT

Rate Limiting

Para evitar sobrecarga do servidor, implementamos rate limiting:

  • 100 requests/minuto por IP
  • 1000 requests/hora por IP
  • Headers de rate limit incluídos nas respostas

Caching

Recomendamos implementar cache local para melhor performance:

  • Cache de 5 minutos para feeds
  • Cache de 1 hora para sitemaps
  • Verificar headers Last-Modified e ETag

Exemplos Práticos

JavaScript (Fetch API)

// Buscar feed JSON
async function buscarFeed() {
  try {
    const response = await fetch('https://tribunavtuber.com.br/feed/json');
    const feed = await response.json();
    
    console.log('Título:', feed.title);
    console.log('Itens:', feed.items.length);
    
    feed.items.forEach(item => {
      console.log(`- ${item.title} (${item.date_published})`);
    });
  } catch (error) {
    console.error('Erro ao buscar feed:', error);
  }
}

// Buscar por categoria
async function buscarPorCategoria(categoria) {
  const response = await fetch(`https://tribunavtuber.com.br/feed/json/categoria/${categoria}`);
  return await response.json();
}

// Buscar por termo
async function buscarPorTermo(termo) {
  const response = await fetch(`https://tribunavtuber.com.br/feed/json/busca?q=${encodeURIComponent(termo)}`);
  return await response.json();
}

PHP

<?php
// Buscar feed RSS
function buscarFeedRSS() {
    $url = 'https://tribunavtuber.com.br/feed/rss';
    $xml = simplexml_load_file($url);
    
    if ($xml) {
        echo "Título: " . $xml->channel->title . "\n";
        echo "Descrição: " . $xml->channel->description . "\n";
        
        foreach ($xml->channel->item as $item) {
            echo "- " . $item->title . " (" . $item->pubDate . ")\n";
        }
    }
}

// Buscar feed JSON
function buscarFeedJSON() {
    $url = 'https://tribunavtuber.com.br/feed/json';
    $json = file_get_contents($url);
    $feed = json_decode($json, true);
    
    if ($feed) {
        echo "Título: " . $feed['title'] . "\n";
        echo "Itens: " . count($feed['items']) . "\n";
        
        foreach ($feed['items'] as $item) {
            echo "- " . $item['title'] . " (" . $item['date_published'] . ")\n";
        }
    }
}
?>

Python

import requests
import json
import xml.etree.ElementTree as ET

def buscar_feed_json():
    """Buscar feed JSON"""
    url = 'https://tribunavtuber.com.br/feed/json'
    response = requests.get(url)
    
    if response.status_code == 200:
        feed = response.json()
        print(f"Título: {feed['title']}")
        print(f"Itens: {len(feed['items'])}")
        
        for item in feed['items']:
            print(f"- {item['title']} ({item['date_published']})")

def buscar_feed_rss():
    """Buscar feed RSS"""
    url = 'https://tribunavtuber.com.br/feed/rss'
    response = requests.get(url)
    
    if response.status_code == 200:
        root = ET.fromstring(response.content)
        
        # Extrair informações do canal
        channel = root.find('channel')
        title = channel.find('title').text
        description = channel.find('description').text
        
        print(f"Título: {title}")
        print(f"Descrição: {description}")
        
        # Listar itens
        for item in channel.findall('item'):
            item_title = item.find('title').text
            item_date = item.find('pubDate').text
            print(f"- {item_title} ({item_date})")

def buscar_por_categoria(categoria):
    """Buscar por categoria"""
    url = f'https://tribunavtuber.com.br/feed/json/categoria/{categoria}'
    response = requests.get(url)
    return response.json() if response.status_code == 200 else None

def buscar_por_termo(termo):
    """Buscar por termo"""
    url = f'https://tribunavtuber.com.br/feed/json/busca?q={termo}'
    response = requests.get(url)
    return response.json() if response.status_code == 200 else None

Node.js

const axios = require('axios');
const xml2js = require('xml2js');

// Buscar feed JSON
async function buscarFeedJSON() {
    try {
        const response = await axios.get('https://tribunavtuber.com.br/feed/json');
        const feed = response.data;
        
        console.log('Título:', feed.title);
        console.log('Itens:', feed.items.length);
        
        feed.items.forEach(item => {
            console.log(`- ${item.title} (${item.date_published})`);
        });
    } catch (error) {
        console.error('Erro ao buscar feed:', error);
    }
}

// Buscar feed RSS
async function buscarFeedRSS() {
    try {
        const response = await axios.get('https://tribunavtuber.com.br/feed/rss');
        const parser = new xml2js.Parser();
        const result = await parser.parseStringPromise(response.data);
        
        const channel = result.rss.channel[0];
        console.log('Título:', channel.title[0]);
        console.log('Descrição:', channel.description[0]);
        
        channel.item.forEach(item => {
            console.log(`- ${item.title[0]} (${item.pubDate[0]})`);
        });
    } catch (error) {
        console.error('Erro ao buscar feed RSS:', error);
    }
}

// Buscar por categoria
async function buscarPorCategoria(categoria) {
    const response = await axios.get(`https://tribunavtuber.com.br/feed/json/categoria/${categoria}`);
    return response.data;
}

// Buscar por termo
async function buscarPorTermo(termo) {
    const response = await axios.get(`https://tribunavtuber.com.br/feed/json/busca?q=${encodeURIComponent(termo)}`);
    return response.data;
}

Suporte

Contato

Para dúvidas sobre a API ou integração:

Changelog

v1.0.0 (27-09-2025)

  • Lançamento inicial da API
  • Suporte a feeds RSS, Atom e JSON
  • Sitemaps XML dinâmicos
  • Google News Sitemap
  • Dados estruturados Schema.org

FAQ

RSS 2.0 é o padrão mais antigo e amplamente suportado. Atom 1.0 é mais moderno e extensível. JSON Feed é o mais novo, usando JSON para facilitar integração com aplicações modernas.

Os feeds são atualizados em tempo real quando novos artigos são publicados. Recomendamos cache de 5 minutos para melhor performance.

Sim, os feeds são de uso livre. Pedimos apenas que mantenha os créditos e links para o site original.