Resumo
A API do Hootsuite permitia integrações robustas para gerenciamento de mídias sociais, utilizando autenticação OAuth 2.0 e endpoints RESTful para perfis, publicações, análises e gerenciamento de equipes, com limites de 50-200 requisições por minuto (dependendo do plano). Este guia é prático: mostra como configurar autenticação, agendar posts, recuperar dados de análise, gerenciar equipes e aplicar integrações em produção.
Nota: O Hootsuite encerrou sua API pública em 2024. Aqui você aprende abordagens alternativas: integrações de parceiros, webhooks e APIs de terceiros para obter funcionalidades equivalentes.
Introdução
O Hootsuite gere mais de 30 milhões de contas de mídias sociais para 200.000+ empresas em 175+ países. Se você desenvolve ferramentas para social media, marketing ou dashboards de análise, integrar APIs de mídias sociais é fundamental para atender esse público.
A realidade: quem gerencia 20+ contas gasta 25-35h/semana em tarefas manuais. Automatizando via API, você distribui conteúdo, monitora engajamento, analisa sentimentos e gera relatórios de desempenho sem esforço manual.
Status e Alternativas da API do Hootsuite
Situação Atual da API
Em 2024, a API pública do Hootsuite foi descontinuada. Suas opções práticas de integração são:
| Abordagem | Descrição | Melhor Para |
|---|---|---|
| APIs Nativas da Plataforma | Integração direta (Facebook, Twitter, LinkedIn) | Controle total |
| Audiense | Inteligência de audiência (Hootsuite Partner) | Análise de audiência |
| HeyOrca | API de agendamento social | Calendário de conteúdo |
| Buffer API | Gerenciamento de mídias sociais | Pequenas equipes |
| Sprout Social API | Gestão social empresarial | Grandes organizações |
| Agorapulse API | CRM de mídias sociais | Gerenciamento de comunidade |
Abordagem Recomendada: APIs Nativas da Plataforma
Para a maioria dos casos, integre-se diretamente nas APIs das plataformas sociais:
| Plataforma | Nome da API | Principais Recursos |
|---|---|---|
| Facebook/Instagram | Graph API | Posts, insights, comentários |
| Twitter/X | API v2 | Tweets, análises, streams |
| Marketing API | Posts, páginas, anúncios | |
| API v5 | Pins, boards, análises | |
| TikTok | Display API | Vídeos, informações do usuário |
| YouTube | Data API | Vídeos, playlists, análises |
Começando: Autenticação Multiplataforma
Passo 1: Registrar Aplicativos de Desenvolvedor
Registre seus apps em cada plataforma e armazene credenciais de forma segura:
// Armazene credenciais de forma segura
const SOCIAL_CREDENTIALS = {
facebook: {
appId: process.env.FB_APP_ID,
appSecret: process.env.FB_APP_SECRET,
redirectUri: process.env.FB_REDIRECT_URI
},
twitter: {
apiKey: process.env.TWITTER_API_KEY,
apiSecret: process.env.TWITTER_API_SECRET,
redirectUri: process.env.TWITTER_REDIRECT_URI
},
linkedin: {
clientId: process.env.LINKEDIN_CLIENT_ID,
clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
redirectUri: process.env.LINKEDIN_REDIRECT_URI
},
instagram: {
appId: process.env.FB_APP_ID, // Usa login do Facebook
appSecret: process.env.FB_APP_SECRET
}
};
Passo 2: Implementar Fluxo OAuth 2.0
Implemente um handler OAuth para múltiplas plataformas:
const getAuthUrl = (platform, state) => {
const configs = {
facebook: {
url: 'https://www.facebook.com/v18.0/dialog/oauth',
params: {
client_id: SOCIAL_CREDENTIALS.facebook.appId,
redirect_uri: SOCIAL_CREDENTIALS.facebook.redirectUri,
scope: 'pages_manage_posts,pages_read_engagement,instagram_basic,instagram_content_publish',
state
}
},
twitter: {
url: 'https://twitter.com/i/oauth2/authorize',
params: {
client_id: SOCIAL_CREDENTIALS.twitter.apiKey,
redirect_uri: SOCIAL_CREDENTIALS.twitter.redirectUri,
scope: 'tweet.read tweet.write users.read offline.access',
state,
response_type: 'code'
}
},
linkedin: {
url: 'https://www.linkedin.com/oauth/v2/authorization',
params: {
client_id: SOCIAL_CREDENTIALS.linkedin.clientId,
redirect_uri: SOCIAL_CREDENTIALS.linkedin.redirectUri,
scope: 'w_member_social r_basicprofile',
state,
response_type: 'code'
}
}
};
const config = configs[platform];
const params = new URLSearchParams(config.params);
return `${config.url}?${params.toString()}`;
};
// Callback OAuth
const handleOAuthCallback = async (platform, code) => {
const tokenEndpoints = {
facebook: 'https://graph.facebook.com/v18.0/oauth/access_token',
twitter: 'https://api.twitter.com/2/oauth2/token',
linkedin: 'https://www.linkedin.com/oauth/v2/accessToken'
};
const response = await fetch(tokenEndpoints[platform], {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: new URLSearchParams({
client_id: SOCIAL_CREDENTIALS[platform].apiKey || SOCIAL_CREDENTIALS[platform].appId || SOCIAL_CREDENTIALS[platform].clientId,
client_secret: SOCIAL_CREDENTIALS[platform].appSecret || SOCIAL_CREDENTIALS[platform].apiSecret,
redirect_uri: SOCIAL_CREDENTIALS[platform].redirectUri,
code,
grant_type: 'authorization_code'
})
});
return response.json();
};
Passo 3: Armazenar Tokens de Forma Segura
Salve os tokens com criptografia e mapeie o usuário/plataforma:
// Esquema de banco de dados para tokens sociais
const SocialToken = {
userId: 'user_123',
platform: 'facebook',
accessToken: 'encrypted_token_here',
refreshToken: 'encrypted_refresh_token',
tokenExpiry: Date.now() + 5183999, // 60 dias
scopes: ['pages_manage_posts', 'pages_read_engagement'],
pageId: 'page_456', // Facebook/Instagram
pageName: 'Minha Página'
};
Agendamento e Publicação de Posts
Criando um Post Multiplataforma
Publique em várias plataformas simultaneamente:
const createSocialPost = async (postData) => {
const results = {};
if (postData.platforms.includes('facebook')) {
results.facebook = await postToFacebook({
pageId: postData.facebookPageId,
message: postData.message,
link: postData.link,
photo: postData.photo
});
}
if (postData.platforms.includes('twitter')) {
results.twitter = await postToTwitter({
text: postData.message,
media: postData.photo
});
}
if (postData.platforms.includes('linkedin')) {
results.linkedin = await postToLinkedIn({
authorUrn: postData.linkedinAuthorUrn,
text: postData.message,
contentUrl: postData.link
});
}
if (postData.platforms.includes('instagram')) {
results.instagram = await postToInstagram({
igAccountId: postData.igAccountId,
imageUrl: postData.photo,
caption: postData.message
});
}
return results;
};
Exemplo de implementação para cada plataforma:
// Facebook
const postToFacebook = async (postData) => {
const token = await getFacebookPageToken(postData.pageId);
const params = new URLSearchParams({
message: postData.message,
access_token: token
});
if (postData.link) params.append('link', postData.link);
if (postData.photo) params.append('photo', postData.photo);
const response = await fetch(
`https://graph.facebook.com/v18.0/${postData.pageId}/feed?${params.toString()}`,
{ method: 'POST' }
);
return response.json();
};
// Twitter
const postToTwitter = async (postData) => {
const token = await getTwitterToken();
let mediaIds = [];
if (postData.media) {
const mediaUpload = await uploadTwitterMedia(postData.media, token);
mediaIds = [mediaUpload.media_id_string];
}
const response = await fetch('https://api.twitter.com/2/tweets', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
text: postData.text,
media: mediaIds.length > 0 ? { media_ids: mediaIds } : undefined
})
});
return response.json();
};
// LinkedIn
const postToLinkedIn = async (postData) => {
const token = await getLinkedInToken();
const post = {
author: postData.authorUrn,
lifecycleState: 'PUBLISHED',
specificContent: {
'com.linkedin.ugc.ShareContent': {
shareCommentary: { text: postData.text },
shareMediaCategory: postData.contentUrl ? 'ARTICLE' : 'NONE',
media: postData.contentUrl ? [{
status: 'READY',
media: postData.contentUrn,
description: { text: postData.text }
}] : []
}
},
visibility: {
'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC'
}
};
const response = await fetch('https://api.linkedin.com/v2/ugcPosts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
'X-Restli-Protocol-Version': '2.0.0'
},
body: JSON.stringify(post)
});
return response.json();
};
// Instagram
const postToInstagram = async (postData) => {
const token = await getInstagramToken();
// 1. Criar container de mídia
const containerResponse = await fetch(
`https://graph.facebook.com/v18.0/${postData.igAccountId}/media`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({
image_url: postData.imageUrl,
caption: postData.caption
})
}
);
const container = await containerResponse.json();
// 2. Publicar
const publishResponse = await fetch(
`https://graph.facebook.com/v18.0/${postData.igAccountId}/media_publish`,
{
method: 'POST',
headers: { 'Authorization': `Bearer ${token}` },
body: JSON.stringify({ creation_id: container.id })
}
);
return publishResponse.json();
};
Agendando Posts
Implemente agendamento de posts com banco de dados e fila de jobs:
const schedulePost = async (postData, scheduledTime) => {
// Salve no banco para execução posterior
const scheduledPost = await db.scheduledPosts.create({
message: postData.message,
platforms: postData.platforms,
scheduledTime: scheduledTime,
status: 'pending',
media: postData.media,
link: postData.link
});
// Adicione à fila de jobs
await jobQueue.add('publish-social-post', {
postId: scheduledPost.id
}, {
delay: scheduledTime - Date.now()
});
return scheduledPost;
};
// Processador de jobs
jobQueue.process('publish-social-post', async (job) => {
const post = await db.scheduledPosts.findById(job.data.postId);
try {
const result = await createSocialPost(post);
await db.scheduledPosts.update(post.id, {
status: 'published',
publishedAt: new Date(),
results: result
});
return result;
} catch (error) {
await db.scheduledPosts.update(post.id, {
status: 'failed',
error: error.message
});
throw error;
}
});
Análises e Relatórios
Obtendo Análises Multiplataforma
Agregue métricas de diferentes redes de forma programática:
const getSocialAnalytics = async (accountId, dateRange) => {
const analytics = {
facebook: await getFacebookAnalytics(accountId.facebook, dateRange),
twitter: await getTwitterAnalytics(accountId.twitter, dateRange),
linkedin: await getLinkedInAnalytics(accountId.linkedin, dateRange),
instagram: await getInstagramAnalytics(accountId.instagram, dateRange)
};
const totals = {
impressions: sum(analytics, 'impressions'),
engagement: sum(analytics, 'engagement'),
clicks: sum(analytics, 'clicks'),
shares: sum(analytics, 'shares'),
comments: sum(analytics, 'comments'),
newFollowers: sum(analytics, 'newFollowers')
};
return { analytics, totals };
};
Exemplo para Facebook:
const getFacebookAnalytics = async (pageId, dateRange) => {
const token = await getFacebookPageToken(pageId);
const metrics = [
'page_impressions_unique',
'page_engaged_users',
'page_post_engagements',
'page_clicks',
'page_fan_adds'
];
const params = new URLSearchParams({
metric: metrics.join(','),
since: dateRange.from,
until: dateRange.until,
access_token: token
});
const response = await fetch(
`https://graph.facebook.com/v18.0/${pageId}/insights?${params.toString()}`
);
return response.json();
};
Siga a mesma lógica para Twitter, LinkedIn e Instagram.
function sum(analytics, metric) {
return Object.values(analytics).reduce((total, platform) => {
return total + (platform.data?.[metric] || 0);
}, 0);
}
Gerenciamento de Equipe
Controle de Acesso Baseado em Função
Defina roles e permissões para times de social media:
const TEAM_ROLES = {
ADMIN: 'admin',
MANAGER: 'manager',
CONTRIBUTOR: 'contributor',
VIEWER: 'viewer'
};
const ROLE_PERMISSIONS = {
[TEAM_ROLES.ADMIN]: ['create', 'read', 'update', 'delete', 'manage_team', 'billing'],
[TEAM_ROLES.MANAGER]: ['create', 'read', 'update', 'approve_posts'],
[TEAM_ROLES.CONTRIBUTOR]: ['create', 'read'],
[TEAM_ROLES.VIEWER]: ['read']
};
const checkPermission = (userRole, requiredPermission) => {
const permissions = ROLE_PERMISSIONS[userRole] || [];
return permissions.includes(requiredPermission);
};
Limitação de Taxas
Limites de Taxa da Plataforma
| Plataforma | Limite | Janela |
|---|---|---|
| Facebook Graph | 200 chamadas | Por hora/usuário |
| Twitter API v2 | 300 tweets | Por 15 min |
| 100-500 chamadas | Por dia | |
| 200 chamadas | Por hora |
Implementando o Tratamento de Limite de Taxa
Gerencie limites de API para evitar bloqueios:
class SocialMediaRateLimiter {
constructor() {
this.limits = {
facebook: { limit: 200, window: 3600000 },
twitter: { limit: 300, window: 900000 },
linkedin: { limit: 500, window: 86400000 },
instagram: { limit: 200, window: 3600000 }
};
this.counters = {};
}
async request(platform, endpoint, options) {
await this.waitForCapacity(platform);
const response = await fetch(endpoint, options);
this.incrementCounter(platform);
return response;
}
async waitForCapacity(platform) {
const limit = this.limits[platform];
const counter = this.counters[platform] || { count: 0, resetTime: Date.now() };
if (Date.now() > counter.resetTime + limit.window) {
counter.count = 0;
counter.resetTime = Date.now();
}
if (counter.count >= limit.limit) {
const waitTime = counter.resetTime + limit.window - Date.now();
await new Promise(resolve => setTimeout(resolve, waitTime));
}
this.counters[platform] = counter;
}
incrementCounter(platform) {
if (!this.counters[platform]) {
this.counters[platform] = { count: 0, resetTime: Date.now() };
}
this.counters[platform].count++;
}
}
Lista de Verificação para Implantação em Produção
Antes do deploy, garanta:
- [ ] OAuth 2.0 implementado para todas as plataformas
- [ ] Tokens armazenados de forma segura e criptografada
- [ ] Atualização automática de tokens configurada
- [ ] Limitação de taxa por plataforma
- [ ] Tratamento de erros robusto
- [ ] Logging para todas as chamadas de API
- [ ] Fluxos de aprovação de posts implementados
- [ ] Moderação de conteúdo ativa
- [ ] Agregação de análises configurada
- [ ] Mecanismos de postagem de backup
Casos de Uso do Mundo Real
Painel de Mídias Sociais
- Desafio: Gerenciar 50+ contas de clientes em múltiplas plataformas
- Solução: Painel centralizado com postagem multiplataforma e automações
- Resultado: 60% de economia de tempo, marca consistente
Distribuição Automatizada de Conteúdo
- Desafio: Compartilhamento manual de novos conteúdos/artigos
- Solução: Publicação automática em todas as redes
- Resultado: Distribuição imediata, 3x mais tráfego social
Conclusão
Com o fim da API pública do Hootsuite, foque nas APIs nativas de cada plataforma para gerenciamento completo de mídias sociais. Pontos principais:
- Implemente OAuth 2.0 individualmente por plataforma
- Respeite os limites de taxa de cada API
- A postagem unificada exige lógica customizada por rede
- Agregue análises para relatórios multiplataforma
- O Apidog acelera testes de API e colaboração do time
Seção de Perguntas Frequentes
O Hootsuite ainda tem uma API?
Não. A API pública foi descontinuada em 2024. Use APIs nativas de cada rede ou plataformas alternativas como Buffer, Sprout Social ou Agorapulse.
Como faço para postar em várias plataformas de uma vez?
Implemente OAuth para cada rede e crie uma função de postagem unificada que chama as APIs em paralelo.
Quais são os limites de taxa para as APIs de mídias sociais?
Variam por rede: Facebook (200/hora), Twitter (300/15min), LinkedIn (100-500/dia), Instagram (200/hora).
Como faço para agendar posts?
Salve as informações do post no banco de dados com scheduled_time e use uma fila de jobs (Bull, Agenda) para publicar no horário certo.
Posso obter análises de todas as plataformas?
Sim. Cada rede fornece APIs de análise. Basta agregar os dados para consolidar os relatórios.
Top comments (0)