Автоматически обновляйте свой баннер Twitter с подписчиками DEV и подписчиками YouTube.

В предыдущей части этой серии мы узнали, как автоматически твитить ваши популярные статьи.



Как и большинство разработчиков, я не остановился на достигнутом, лол. Я пошел еще дальше и создал сервис для автоматического обновления моего баннера в Твиттере с количеством моих подписчиков из DEV, Medium и YouTube.

Поверьте, это намного проще, чем мы думаем, или нет?

Давай выясним.

Авария

  1. Создайте дерзкое изображение баннера Twitter с заполнителями для заполнения
  2. Читайте подписчиков из DEV, Medium и YouTube
  3. Используйте Twitter API для обновления баннера
  4. Делайте это с регулярным интервалом

Создание шаблона изображения

Первым и самым важным шагом для начала является создание шаблона, который мы можем позже заполнить текущими данными.

Я всегда использую Canva для создания изображений для Twitter и YouTube. Итак, я пошел туда и использовал их шаблон Twitter Banner, чтобы создать его для себя.

Я добавил имена пользователей для всех трех учетных записей и оставил немного места для заполнения значения счетчика в реальном времени.

Я черпал вдохновение из некоторых аккаунтов в Твиттере и Тады 🎉!

Получение подписчиков DEV

Это было самым простым, все, что вам нужно сделать, это

  • получить API из вашей учетной записи DEV
  • используйте API своих подписчиков, чтобы получить всех подписчиков
  • они отправляют максимум 1000 подписчиков на страницу, поэтому нам нужно запустить цикл, пока подписчики возвращаются.

Фрагмент кода

// fetch all followers
export async function getFollowersFromDev(): Promise<any[]> {
  // start with page 1
  let page = 1,
    limit = 1000;
  const followers = [];
  // repeat until page number exists
  while (page) {
    const res = await fetch(
      `${process.env.DEV_API_URL}/followers/users?per_page=${limit}&page=${page}`,
      {
        headers: {
          "api-key": process.env.DEV_API_KEY as string,
        },
      }
    );
    const answer = await res.json();
    if (answer && Array.isArray(answer) && answer.length) {
      followers.push(...answer);
      // increment page number if this page is full, otherwise set to 0
      page = answer.length === limit ? page + 1 : 0;
    } else {
      // no more followers, so set page to 0
      page = 0;
    }
  }
  return followers;
}

Привлечение подписчиков YouTube

У нас есть REST API для этого,

  • создайте ключ API в своем проекте Google Cloud Platform и разрешите доступ к API YouTube.

  • посетите YouTube Studio, чтобы получить идентификатор своего канала, как показано на изображении ниже.

  • все, что вам нужно сделать дальше, это вызвать API и прочитать данные

Фрагмент кода

export async function getYoutubeSubscribers() {
  const res = await fetch(
    `https://youtube.googleapis.com/youtube/v3/channels?part=statistics&id=${YT_CHANNEL_ID}&key=${YT_API_KEY}`
  );
  const data = await res.json();
  return data?.items[0]?.statistics?.subscriberCount || 330;
}

Получение подписчиков Medium

Ну, это было самым сложным, Medium, похоже, не предоставляет API для подсчета подписчиков. Но погуглив это, я в конце концов нашел этот Суть от пользователя GitHub newhouse, большое им спасибо.

Оказывается, если вы добавите ?format=json в конец URL-адреса своего профиля на Medium, вы получите ответ JSON с кучей данных, включая «SocialStats».

Но «Подождите… Подождите… Подождите, не так быстро», — сказала команда Medium.

Они добавили некоторый текст перед фактическим JSON, чтобы ограничить использование в качестве API.

Кроме того, это не разрешилось, когда я сделал запрос на выборку, но работал при использовании Insomnia, поэтому я использовал Insomnia в качестве пользовательского агента при выполнении сетевых запросов.

Фрагмент кода

export async function getMediumFollowers() {
  const res = await fetch("https://medium.com/@anshuman-bhardwaj?format=json", {
    headers: {
      "user-agent": "insomnia/2021.7.2", // didn't work without this for me
    },
  });
  // Medium adds this to the JSON text
  const hijackString = "";
  const jsonText = await res.text();
  // remove the hijackString from JSON before parsing
  const data = JSON.parse(jsonText.replace(hijackString, ""));
  return (
    data?.payload?.references?.SocialStats?.[MEDIUM_USER_ID]
      ?.usersFollowedByCount || 20
  );
}

Обновление баннера моего профиля в Твиттере

Теперь, когда у нас есть вся необходимая информация, нам просто нужно создать функцию-обработчик API, которая будет

  1. извлекать данные из всех трех методов, сделанных выше
  2. обновите изображение-заполнитель, которое мы создали, со значениями, полученными из вышеуказанных методов.
  3. загрузить обновленное изображение в мою учетную запись Twitter, используя конечную точку API v1 update_profile_banner.

Обновление изображения

Мы будем использовать jimp пакет npm, чтобы добавить текст поверх нашего изображения. Для этого нам нужно найти точные координаты заполнителей. (хит и пробная версия отлично сработали для меня)

Мы используем метод print из jimp, чтобы поместить текст поверх изображения.

Как получить учетные данные Twitter API, я объяснил в предыдущей статье. Поэтому, пожалуйста, обратитесь к этой статье, и я пока ее пропущу.

Ограничения

  • API Twitter принимает кодировку base64 изображения, но я достигал максимального размера полезной нагрузки при использовании вызова fetch, но использование пакета npm Twitter API Client решило проблему для меня.
  • Моя функция обработчика API Next.js не смогла разрешить шрифты из модуля jimp во время выполнения, поэтому я скопировал их в общую папку, чтобы решить проблему.
  • Так как я использовал функции Next.js, я не мог записать образ на диск.
  • Да, я знаю, что getBase64Async существует в jimp, но он давал огромное возвращаемое значение ~ в 6 раз больше исходного размера. Итак, я связал утилиту getBufferAsync с вызовом toString, и у меня это сработало.

Фрагмент кода

import { NextApiRequest, NextApiResponse } from "next";
import {
  formatLog,
  getFollowersFromDev,
  getMediumFollowers,
  getYoutubeSubscribers,
  twitterClient,
} from "../../../utils";
import path from "path";
import jimp from "jimp";
export default async function views(
  request: NextApiRequest,
  response: NextApiResponse
) {
  console.info(formatLog("Running Update Twitter Header Function"));
  try {
    const devFollowers = await getFollowersFromDev();
    const ytSubs = await getYoutubeSubscribers();
    const mediumFollowers = await getMediumFollowers();
const filePath = path.resolve("./public/yellow_twitter_header.png");
    const jimpFont = path.resolve(
      "./public/open-sans-32-black/open-sans-32-black.fnt"
    );
    path.resolve("./public/open-sans-32-black/open-sans-32-black.png");
const image = await jimp.read(filePath);
    const font = await jimp.loadFont(jimpFont);
    image.print(font, 150, 98, ytSubs);
    image.print(font, 620, 98, devFollowers.length);
    image.print(font, 1130, 98, mediumFollowers);
    const fromImage = await image.getBufferAsync(image.getMIME());
    const updatedHeader =
      await twitterClient.accountsAndUsers.accountUpdateProfileBanner({
        banner: fromImage.toString("base64"),
        width: 1500,
        height: 500,
      });
    response.status(200).send({
      type: "success",
      updatedHeader,
      devFollowers: devFollowers.length,
      ytSubs,
      mediumFollowers,
    });
  } catch (e: any) {
    console.log(e);
    response.status(500).send({
      type: "error",
      message: e.message,
    });
  }
}

Планирование обновлений

Теперь, когда мы сделали всю тяжелую работу, нам просто нужно вызвать обработчик API, созданный выше.

Для планирования я создал задание Cron, используя действия GitHub, которые будут запускаться каждые 5 минут для обновления изображения моего профиля. Задание Cron вызывает обработчик API, созданный выше, и все.

И на данный момент это работает довольно хорошо.

Примечание. API обновления баннеров Twitter ограничен по частоте, не удалось найти точное число, но это где-то около 30 вызовов за 15 минут или около того. Если знаете, напишите в комментариях.

Ресурсы

Ну вот и все, друзья мои. Вы можете ознакомиться с полным руководством и использовать его, разветвив этот репозиторий GitHub.

Я надеюсь, что вы найдете эту статью полезной! Если у вас есть какие-либо отзывы или вопросы, пожалуйста, не стесняйтесь оставлять их в комментариях ниже, я хотел бы услышать и поработать над ними.

Для большего количества такого контента, пожалуйста, следуйте за мной

До следующего раза

Первоначально опубликовано на https://theanshuman.dev 31 января 2022 г.

Больше контента на plainenglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Получите эксклюзивный доступ к возможностям написания и советам в нашем сообществе Discord.