DEV Community

Cover image for Como Usar a API do Hootsuite?
Lucas
Lucas

Posted on • Originally published at apidog.com

Como Usar a API do Hootsuite?

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.

Experimente o Apidog hoje

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
LinkedIn Marketing API Posts, páginas, anúncios
Pinterest 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
  }
};
Enter fullscreen mode Exit fullscreen mode

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();
};
Enter fullscreen mode Exit fullscreen mode

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'
};
Enter fullscreen mode Exit fullscreen mode

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;
};
Enter fullscreen mode Exit fullscreen mode

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();
};
Enter fullscreen mode Exit fullscreen mode

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;
  }
});
Enter fullscreen mode Exit fullscreen mode

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 };
};
Enter fullscreen mode Exit fullscreen mode

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();
};
Enter fullscreen mode Exit fullscreen mode

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);
}
Enter fullscreen mode Exit fullscreen mode

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);
};
Enter fullscreen mode Exit fullscreen mode

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
LinkedIn 100-500 chamadas Por dia
Instagram 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++;
  }
}
Enter fullscreen mode Exit fullscreen mode

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)