Настоящая инструкция, как делать динамические стикеры в Telegram

Шо, посоны, анимэ? Что это за тренд пошел писать статьи про то, как создать в Тележеньке динамические стикеры — при том, либо максимально поверхностные, либо максимально тугие (вот вам curl, и любуйтесь им сколько вам угодно).

Решил, чего это я, потрачу полчасика, напишу статью, как реально создать динамические стикеры в тележеньке на Node.js, TypeScript, Telegraf.js и с использованием еще горсти сторонних зависимостей. Ну и с исходным кодом, который любой ламер сможет адаптировать под свои нужды. Поехали!

Структуру проекта я особо не буду объяснять — стандартный бойлерплейт TypeScript, коих в интернетах-этих-ваших мульоны. Даже я стартер для себя написал недавно, чтобы упростить запуск MVP. Перейду сразу к соку.

Мы создадим простого бота под документации Telegraf.js. По команде /start он будет создавать стикерпак (желательно сделать это один раз) с одним стикером, а после будет по куллдауну обновлять этот один стикер.

Для генерации картинки стикера, воспользуемся пакетом text-to-picture (он немного приуныл, поэтому я сделал свой форк с блекджеком и нормальными зависимостями, который и буду использовать).

Алсо, я не буду углубляться в работу с @BotFather — по нему и по инструкции использования прокатились в других статьях. На текущий момент у вас должны быть:

  • Токен бота от @BotFather
  • Установленные на компуктере node и yarn

Если вы ну уж полный ламер далекий от кодирования, переходите в конец статьи — там я просто опишу шаги по созданию вашего собственного бота на основе кода стартера. Следующие пара-тройка секций для простых программистов.

Создаем бота

Ну это очень просто. За пазухой у скрипта, естественно, dotenv, в котором лежат TOKEN (токен бота) и ADMIN (ваш user id). Начинаем кодирование, быстренько накатаем скриптик, который отвечает на /start.

import Telegraf from 'telegraf' const bot = new Telegraf(process.env.TOKEN) bot.start(ctx => ctx.reply('WoW Classic — это симулятор очередей')) bot.launch().then(() => console.log("It's alive!"))

Нойс. Теперь можем запустить скриптик при помощи того же yarn develop — команду, которую я любезно включил в `package.json` нашего стартера; отправить боту /start и даже получить ответ.

Генерим картинку

async function getStickerId() { const secondsAfterPHP = Math.floor( new Date().getTime() / 1000 - new Date('1995').getTime() / 1000 ) const result = await textToPicture.convert({ text: `${secondsAfterPHP}`, source: { width: 512, height: 512, background: '0xFF0000FF', }, color: 'white', }) const file = await bot.telegram.uploadStickerFile(ownerId, { source: await result.getBuffer(), }) return file.file_id }

Скриптец выше делает следующие вещи:

  • Считает количество секунд после создания PHP в 1995 году
  • Создает картинку при помощи text-to-picture пакета
  • Загружает буфер картинки от text-to-picture в Телеграм
  • Возвращает результат функции — file_id нашего стикера

Эту функцию мы сможем использовать дальше.

Создаем стикерпак

Тут все изи. Мы берем результат getStickerId функции и пихаем ее в функцию создания стикерпака. Ну а потом грех не ответить на это сообщение созданным стикером, чтобы вы могли себе сохранить стикерпак.

const stickerSetName = 'phpSuckedSeconds' bot.start(async ctx => { try { const botUsername = ctx.me const stickerId = await getStickerId() await ctx.telegram.createNewStickerSet( ownerId, `${stickerSetName}_by_${botUsername}`, 'PHP sucked for this many seconds', { png_sticker: stickerId, emojis: '💩', mask_position: undefined, } ) const stickerSet = await bot.telegram.getStickerSet(`${stickerSetName}_by_${botUsername}`) const sticker = stickerSet.stickers[0] return ctx.replyWithSticker(sticker.file_id) } catch (err) { return ctx.reply(err.message) } })

Опять пройдемся построчно, что тут мы имеем:

  • Во-первых, тут все может плюнуть в нас ошибкой — поэтому мы ловим ошибку в одном месте и отвечаем ей пользователю, если нужно
  • Дальше мы получаем username нашего бота, чтоб создать в итоге название стикерпака, оканчивающееся на _by_mybot — неочевидная обязабма в API
  • Используем вышеописанную функцию и получаем идентификатор стикера
  • Создаем сам стикер пак простой командой
  • Так как эта команда возвращает лишь результат выполнения (получилось или нет), мы еще раз вытягиваем информацию о паке стикеров
  • Берем первый (и единственный) стикер
  • Отвечаем этим стикером нам любимым
Как-то так в итоге получается
Как-то так в итоге получается

Делаем стикерпак 🌈 *динамичным* 🦄

Здесь все просто — каждые 30 секунд мы будем удалять единственный стикер и добавлять туда новый. Вот код функции, собственно говоря.

setInterval(updateSticker, 30 * 1000) async function updateSticker() { console.log('Updating stickers') const botUsername = bot.options.username const stickerSet = await bot.telegram.getStickerSet( `${stickerSetName}_by_${botUsername}` ) const sticker = stickerSet.stickers[0] await bot.telegram.deleteStickerFromSet(sticker.file_id) await bot.telegram.addStickerToSet( ownerId, stickerSetName, { png_sticker: await getStickerId(), emojis: '💩', mask_position: undefined, }, false ) console.log('Updated stickers') }

Никакой магии, мы просто:

  • Заставляем безмозглую машину выполнять одно и то же действие каждые 30 секунд
  • Логируем нам любимым, что обновление инициированно
  • Получаем стикерпак и единственный стикер оттуда
  • Удаляем этот стикер
  • Добавляем новый стикер с новым временем, воспользовавшись функцией создания и загрузки картинки
  • Логируем окончание процесса
  • А, это все

Вот так просто — буквально за полчаса — мы собрали рабочее (хоть и не самое красивое) решение для создания динамических стикеров в Телеграме. И это почти пошаговое руководство, а не просто статья со словами "создавайте стикеров через ботов" или "просто курлите напрямую в тележеньку, каждый раз, когда нужно обновить стикеры — но где брать картинки я не скажу".

Держите этот скрипт запущенным на своем пека, мокинтоше или линухе на сервачке — и будет вам счастье. А теперь к секции, которой все ждут: как же нам генерить динамические стикеры без знаний программирования?

Вот так

1. Качаете файлики из стартера

2. Ставите себе нужные зависимости через yarn install

3. Создаете файл .env

4. Заполняете в нем TOKEN и ADMIN поля, как в .env.sample

3. Открываете src/app.ts

4. Меняете stickerSetName и stickerSetDescription

5. Меняете переменную text (это то, что будет на картинке)

6. Запускаете все через yarn develop

Зетс ол фолкс!

Заключение и наглый пиар себя

Надеюсь, этот материал кому-нибудь да будет полезным. Никакого зла я не держу в сторону авторов предыдущих статей — они замечательные люди (просто недоговаривают). Если вам понравилась моя статья — не стесняйтесь апвоутить, подписываться и оставлять эмодзи хлопков в комментариях.

К слову, на любые вопросы с удовольствием отвечу в тех же самых комментариях. Ну и, как принято на VC.ru, пара слов о моем новом проекте, чтобы вы обязательно зашли и покрутили его.

Todorant — это сервис, который позволяет мне лично держать голову легкой (без веса постоянно накапливающихся задач в моих тудулистах) благодаря идеям из книг Eat That Frog, Willpower и Getting Things Done, что я недавно прочитал.

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

Спасибо!

3737
27 комментариев

Спасибо за материал, я ламер и мне интересно.
Но разрешите пару замечаний. Коль вы пишите доя ламеров (остальным наверное и не надо) :
1 множество терминов да ещё английских на русском. Это не для ламеров
2 стиль изложения 'пацановский', смотрите как все просто. Это не для ламеров
По факту нужна грамотная инструкция которая научит и поможет.

7
Ответить

К сожалению, вырос на улице — язык белых людей так и не освоил. В этой статье я постарался как-то более прилично написать, похоже, не вышло. Ну, всяко лучше, чем мой Пацанский разбор кода ТОН

4
Ответить

После слов node, yarn, dotenv, я приуныл и понял, что это совсем не для ламеров.

1
Ответить

Я первый 👏

3
Ответить

Комментарий недоступен

1
Ответить

Делаем ставки сколько еще будет инструкций

Ответить

Сначала будет вебсервис-конструтор таких стикеров, а потом аггрегатор таких сервисов и статей по ним.

8
Ответить