codinggames

Publicando Reels no Instagram usando Node.js e a arte de superar limitações

Afinal, por que gastar 30 segundos fazendo algo manualmente quando você pode gastar 30 horas automatizando-o?

Escrito em 14 de outubro de 2023 - 🕒 7 min. de leitura

Fala aí, pessoal! É difícil ser nerd nos dias de hoje, tantos eventos são exclusivos para pessoas da mídia e influenceres - até a E3 foi um evento apenas para o comércio por muitos anos. Então, digamos que você já esteja feliz com o seu trabalho e realmente não queira se tornar um jornalista. A sua melhor aposta é se tornar um influencer e talvez ser convidado para o próximo evento de lançamento do [insira o nome da franquia de jogos], certo?

Tenho muita sorte de ter trabalhado como jornalista freelancer para vários meios de comunicação no Brasil, mas desde que me mudei para a Holanda, não posso mais ir a esses eventos, pois não tenho contatos na mídia aqui e também não falo holandês. Uma das coisas que perdi este ano foi o evento de lançamento de The Last of Us em Amsterdam e recentemente (semana passada) o evento de Marvel Spider-Man 2 em Hilversum.

Ok, e agora? Bem, decidi me tornar um influencer e comecei a postar no Instagram, mas realmente não gosto de postar coisas no Instagram. Prefiro passar o meu tempo programando e, claro, se tornar uma celebridade do Instagram hoje em dia não é uma tarefa fácil. Então decidi automatizar algumas partes disso, afinal, a Meta oferece uma API que nos permite fazer muitas coisas, incluindo postar Stories, Reels ou fotos. O que poderia dar errado?

Automatização
Automatização

A API do Instagram

Show, então simplesmente npm install axios e começamos a postar no Instagram, certo? Bem… por algum motivo, você não pode enviar vídeos para o Instagram diretamente via API, você precisa fornecer uma URL de onde eles baixarão o seu vídeo… tipo… sério? Quer dizer, enviamos pessoas para Marte, mas não podemos enviar um vídeo para o Instagram sem um link?

Mas não tema, estou aqui para ajudá-lo a resolver esse problema, caro desenvolvedor. Criei um script Node.js que permitirá que você publique vídeos no Instagram, e vou explicar como funciona.

O dilema de postar vídeo no Instagram

Antes de mergulharmos de cabeça, vamos preparar as nossas ferramentas. Instale as bibliotecas necessárias:

npm install axios @ngrok/ngrok express fluent-ffmpeg ffmpeg-static

Agora, vamos destrinchar o código e entender a mágica por trás dele.

Primeiro, precisamos configurar o nosso ambiente. Estamos usando axios para solicitações HTTP, ngrok para expor o nosso servidor local ao mundo (porque, você sabe, o Instagram precisa de um link) e express para servir o nosso vídeo.

const axios = require('axios');
const ngrok = require('@ngrok/ngrok');
const express = require('express');

const GRAPH_API_VERSION = 'v18.0';
const PORT = 3000;
const expressApp = express();

Este código simplesmente faz uma requisição POST para a API do Instagram para criar um container e “fazer o upload” do vídeo para ele.

O termo “fazer o upload” está entre aspas porque nós não estamos realmente fazendo o upload do vídeo, nós estamos apenas dizendo ao Instagram onde encontrá-lo.

Agora, vamos para a parte divertida. Precisamos enviar o nosso vídeo para um contêiner no Instagram. Mas lembre-se, não estamos realmente enviando o vídeo. Estamos apenas dizendo ao Instagram onde encontrá-lo. Então, precisamos criar um contêiner e depois enviar o vídeo para ele.

const uploadReelsToContainer = async (
  accessToken,
  instagramAccountId,
  caption,
  videoUrl,
  coverUrl
) => {
  const response = await axios.post(
    `https://graph.facebook.com/${GRAPH_API_VERSION}/${instagramAccountId}/media`,
    {
      access_token: accessToken,
      caption,
      media_type: 'REELS',
      video_url: videoUrl,
      cover_url: coverUrl,
    }
  );

  return response.data;
};

Legal, mas você deve estar pensando, “de onde eu consigo o accessToken e instagramAccountId?” Bem, você precisa criar um aplicativo no Facebook e depois criar uma conta no Instagram e vincular a sua conta do Instagram ao seu aplicativo do Facebook. Você pode encontrar mais informações sobre isso aqui. Para ser honesto, esta é a parte mais difícil do processo, mas uma vez que você consiga fazer funcionar, está tudo certo.

Ah, espere, você também quer saber como conseguir o videoUrl e coverUrl, certo? Paciência, meu doce padawan, chegaremos lá.

Depois que o contêiner é criado, precisamos verificar o seu status. Precisamos esperar até que o vídeo seja totalmente baixado pelo Instagram.

const getStatusOfUpload = async (accessToken, igContainerId) => {
  const response = await axios.get(
    `https://graph.facebook.com/${GRAPH_API_VERSION}/${igContainerId}`,
    { params: { access_token: accessToken, fields: 'status_code' } }
  );

  return response.data.status_code;
};

Se o status for FINISHED, então podemos prosseguir para a próxima etapa, que é finalmente publicar o vídeo, ou como a Meta chama: publicação de mídia.

const publishMediaContainer = async (accessToken, instagramAccountId, creationId) => {
  const response = await axios.post(
    `https://graph.facebook.com/${GRAPH_API_VERSION}/${instagramAccountId}/media_publish`,
    { access_token: accessToken, creation_id: creationId }
  );

  return response.data;
};

E qual é o propósito de postar isso e obter todos esses IDs estranhos? O que realmente queremos é a URL da postagem do Instagram, certo? Para isso, precisamos obter o permalink_url da resposta.

const fetchPermalink = async (accessToken, mediaId) => {
  const response = await axios.get(
    `https://graph.facebook.com/${GRAPH_API_VERSION}/${mediaId}`,
    { params: { access_token: accessToken, fields: 'permalink' } }
  );

  return response.data;
};

Vamos “ajuntar” tudo

Eu tenho adiado essa parte por um tempo, mas agora é hora de explicar como obter o videoUrl e coverUrl, e é aqui que o ngrok entra em jogo. Precisamos criar um servidor local express que fornecerá o nosso vídeo e capa, e então expô-lo ao mundo usando ngrok.

expressApp.listen(port);

expressApp.get('/video', (req, res) => res.sendFile(videoFilePath));
expressApp.get('/cover', (req, res) => res.sendFile(thumbnailFilePath));

Com este código, serviremos o nosso vídeo e capa em http://localhost:3000/video e http://localhost:3000/cover, respectivamente. As variáveis videoFilePath e thumbnailFilePath devem conter um caminho local para os arquivos de vídeo e capa.

Agora vamos expor isso ao mundo usando ngrok. Isso nos dará uma URL que podemos usar para fazer upload do nosso vídeo no Instagram.

const listener = await ngrok.connect(port);
const url = listener.url();

const videoUrl = `${url}/video`;
const coverUrl = `${url}/cover`;

E agora juntando tudo:

const postInstagramReel = async (
  accessToken,
  pageId,
  description,
  thumbnailFilePath,
  videoFilePath
) => {
  const expressApp = express();
  expressApp.listen(PORT);

  expressApp.get('/video', (req, res) => res.sendFile(videoFilePath));
  expressApp.get('/cover', (req, res) => res.sendFile(thumbnailFilePath));

  const listener = await ngrok.connect(PORT);
  const url = listener.url();

  const { id: containerId } = await uploadReelsToContainer(
    accessToken,
    pageId,
    description,
    `${url}/video`,
    `${url}/cover`
  );

  let status = null;
  const TWO_MINUTES = 2 * 60 * 1000;
  const startTime = Date.now();

  while (status !== 'FINISHED') {
    if (Date.now() - startTime > TWO_MINUTES) {
      await ngrok.disconnect();
      throw new Error('Upload took longer than 2 minutes.');
    }

    status = await getStatusOfUpload(accessToken, containerId);
    await new Promise((r) => setTimeout(r, 1000));
  }

  const { id: creationId } = await publishMediaContainer(accessToken, pageId, containerId);

  const { permalink } = await fetchPermalink(accessToken, creationId);

  await ngrok.disconnect();

  return { creationId, permalink };
};

Esta função iniciará o servidor do express e definirá a URL do ngrok. Em seguida, ele “fará o upload” do vídeo para o Instagram e aguardará até que o vídeo seja totalmente baixado. Depois disso, ele publicará o vídeo e retornará a URL da postagem do Instagram.

E é isso! Agora você pode postar vídeos no Instagram usando Node.js. Espero que tenha gostado.

Espere, o quê? Ah… você quer saber por que fiz você instalar o ffmpeg? Ok, vamos falar sobre isso.

Garantindo que o vídeo esteja pronto para o Instagram

Tudo está bom e o código está bonito e elegante, mas há mais uma coisa que precisamos fazer antes de postar nosso vídeo no Instagram. Precisamos garantir que o vídeo esteja no formato correto. O Instagram tem alguns requisitos para vídeos, e precisamos garantir que nosso vídeo atenda a esses requisitos. Para isso, usaremos o ffmpeg.

Existem dois pacotes do NPM ótimos que nos permitem usar o ffmpeg no Node.js: fluent-ffmpeg e ffmpeg-static. O primeiro é um wrapper em torno do ffmpeg, e o segundo é uma compilação estática do ffmpeg que podemos usar no nosso código.

const processVideo = (inputPath, outputPath) => {
  return new Promise((resolve, reject) => {
    ffmpeg(inputPath)
      .toFormat('mp4')
      .size('1080x1920')
      .aspect('9:16')
      .videoCodec('libx264')
      .audioCodec('aac')
      .audioChannels(2)
      .audioFrequency(48000)
      .audioBitrate('128k')
      .on('end', () => resolve(`Processing finished. Output saved to ${outputPath}`))
      .on('error', (err) => reject(new Error(`Error processing video: ${err.message}`)))
      .save(outputPath);
  });
};

Este código garantirá que o vídeo esteja no formato correto. Ele converterá o vídeo para mp4, redimensionará para 1080x1920 e garantirá que a proporção seja 9:16. Também garantirá que o codec de vídeo seja libx264 e que o codec de áudio seja aac. Além disso, garantirá que o áudio tenha 2 canais, uma frequência de 48000 e uma taxa de bits de 128k.

Conclusão

E é isso, com um pouco de código e astúcia, agora podemos postar vídeos no Instagram usando Node.js. Valeu a pena as horas que passei pesquisando e codificando isso? Provavelmente não, mas me diverti e aprendi muito, então acho que valeu a pena. Uhmn…

Ah, e não se esqueça de me seguir no Instagram em @opablopirata e me ajude a me tornar um influencer. Eu prometo que vou postar com frequência. Eu sou apenas um pouco preguiçoso, mas vou chegar lá.

Espero que tenha gostado e que isso tenha sido útil para você de alguma forma. Até a próxima! Saúde!

Tags:


Publicar um comentário

Comentários

Nenhum comentário.