Glitch
Документация API · Библиотеки

Начало

Библиотеки

Отдельных библиотек для Glitch не нужно. API повторяет API Discord, поэтому подходят обычные discord.py и discord.js. Им нужно только указать адреса Glitch вместо адресов Discord. Адресов два. Первый — адрес API, через него идут все запросы. Второй — адрес картинок, по нему библиотека загружает аватарки, значки и стикеры. Примеры на этой странице проверены на discord.py 2.4 и discord.js 14.

Как задать вебхук в библиотеке

Библиотеки умеют создавать вебхук двумя способами. Первый — по ссылке целиком (Webhook.from_url в discord.py, new WebhookClient({ url }) в discord.js). Второй — по номеру и ключу (Webhook.partial и new WebhookClient({ id, token })).

С Glitch работает только второй способ. Первый библиотеки разрешают только для адресов discord.com, и наш адрес они отклонят.

Номер и ключ проще всего взять из адреса вебхука. Храните адрес в переменной окружения, а не в коде.

Python
import os

# GLITCH_WEBHOOK_URL = https://api.glitchapp.online/v10/webhooks/<номер>/<ключ>
WEBHOOK_ID, WEBHOOK_TOKEN = os.environ["GLITCH_WEBHOOK_URL"].rstrip("/").split("/")[-2:]

discord.py

Установка.

curl
pip install discord.py

Адреса задаются один раз в начале программы. Они действуют и на асинхронный вебхук (discord.Webhook), и на обычный (discord.SyncWebhook).

Python
import discord
from discord.webhook import async_ as webhook_api

webhook_api.Route.BASE = "https://api.glitchapp.online/v10"      # адрес API
discord.Asset.BASE = "https://api.glitchapp.online/cdn"          # адрес картинок

Без второй строки всё будет работать, но вместо аватарок библиотека будет показывать стандартные картинки Discord.

Асинхронный вебхук

Подходит, если программа уже работает на asyncio, например это бот или веб-сервер.

Python
import asyncio
import os

import aiohttp
import discord
from discord.webhook import async_ as webhook_api

webhook_api.Route.BASE = "https://api.glitchapp.online/v10"
discord.Asset.BASE = "https://api.glitchapp.online/cdn"
WEBHOOK_ID, WEBHOOK_TOKEN = os.environ["GLITCH_WEBHOOK_URL"].rstrip("/").split("/")[-2:]


async def main():
    async with aiohttp.ClientSession() as session:
        webhook = discord.Webhook.partial(int(WEBHOOK_ID), WEBHOOK_TOKEN, session=session)

        embed = discord.Embed(title="Сборка 1.4.2 прошла", description="Все проверки зелёные", color=0x2FAE9A)
        embed.add_field(name="Ветка", value="master", inline=True)
        embed.add_field(name="Длительность", value="2 мин 14 с", inline=True)

        # wait=True — получить созданное сообщение, чтобы потом его изменить
        message = await webhook.send("Готово!", embed=embed, username="CI", wait=True)

        await webhook.edit_message(message.id, content="Готово, версия выложена")


asyncio.run(main())

Обычный вебхук

Подходит для скриптов, задач по расписанию и всего, где asyncio не нужен.

Python
import os

import discord
from discord.webhook import async_ as webhook_api

webhook_api.Route.BASE = "https://api.glitchapp.online/v10"
discord.Asset.BASE = "https://api.glitchapp.online/cdn"
WEBHOOK_ID, WEBHOOK_TOKEN = os.environ["GLITCH_WEBHOOK_URL"].rstrip("/").split("/")[-2:]

webhook = discord.SyncWebhook.partial(int(WEBHOOK_ID), WEBHOOK_TOKEN)
webhook.send("Резервная копия базы готова", username="Бэкап")

Файлы и картинки

Python
# один файл
webhook.send("Отчёт за неделю", file=discord.File("report.pdf"))

# несколько картинок одним сообщением (альбом)
webhook.send(files=[discord.File("before.png"), discord.File("after.png")])

# картинка внутри карточки
embed = discord.Embed(title="Скриншот ошибки")
embed.set_image(url="attachment://error.png")
webhook.send(embed=embed, file=discord.File("error.png"))

Ошибки

Отказ сервера библиотека превращает в исключение. Код ошибки Glitch лежит в поле code, HTTP-статус в status. Ответ 429 библиотека обрабатывает сама. Она ждёт нужное время и повторяет запрос.

Python
try:
    webhook.send("Привет")
except discord.NotFound:
    print("Вебхук удалён, нужен новый адрес")
except discord.HTTPException as error:
    print(error.status, error.code, error.text)

discord.js

Установка. Нужен Node.js 18 или новее.

curl
npm install discord.js

Адреса передаются при создании вебхука в настройке rest. В api — адрес API без версии, /v10 библиотека допишет сама. В cdn — адрес картинок.

JavaScript
const { WebhookClient, EmbedBuilder } = require('discord.js');

const [id, token] = process.env.GLITCH_WEBHOOK_URL.replace(/\/$/, '').split('/').slice(-2);

const webhook = new WebhookClient({ id, token }, {
  rest: { api: 'https://api.glitchapp.online', cdn: 'https://api.glitchapp.online/cdn' },
});

async function main() {
  const embed = new EmbedBuilder()
    .setTitle('Сборка 1.4.2 прошла')
    .setDescription('Все проверки зелёные')
    .setColor(0x2fae9a)
    .addFields(
      { name: 'Ветка', value: 'master', inline: true },
      { name: 'Длительность', value: '2 мин 14 с', inline: true },
    );

  // WebhookClient всегда получает созданное сообщение в ответ
  const message = await webhook.send({ content: 'Готово!', username: 'CI', embeds: [embed] });

  await webhook.editMessage(message.id, { content: 'Готово, версия выложена' });
}

main().catch((error) => {
  // error.code — код ошибки Glitch, error.status — HTTP-статус
  console.error(error.status, error.code, error.message);
});

Файлы и картинки

JavaScript
// один файл
await webhook.send({ content: 'Отчёт за неделю', files: ['./report.pdf'] });

// картинка внутри карточки
const embed = new EmbedBuilder().setTitle('Скриншот ошибки').setImage('attachment://error.png');
await webhook.send({ embeds: [embed], files: [{ attachment: './error.png', name: 'error.png' }] });

Без библиотеки

Для простых задач библиотека не нужна, отправка сообщения — это один HTTP-запрос.

Python и requests

Python
import json
import os

import requests

URL = os.environ["GLITCH_WEBHOOK_URL"]

# текст
requests.post(URL, json={"content": "Привет из Python"}).raise_for_status()

# получить созданное сообщение
message = requests.post(URL, params={"wait": "true"}, json={"content": "С ответом"}).json()
print(message["id"])

# файл: сам файл полем files[0], остальное JSON-строкой в payload_json
with open("report.pdf", "rb") as f:
    response = requests.post(
        URL,
        data={"payload_json": json.dumps({"content": "Отчёт за неделю"})},
        files={"files[0]": ("report.pdf", f)},
    )
response.raise_for_status()

JavaScript и fetch

JavaScript
const response = await fetch(process.env.GLITCH_WEBHOOK_URL + '?wait=true', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ content: 'Привет из JavaScript' }),
});

if (!response.ok) {
  const error = await response.json();
  throw new Error(`${response.status} ${error.code}: ${error.message}`);
}
const message = await response.json();

curl

curl
# текст
curl -X POST "$GLITCH_WEBHOOK_URL" -H "Content-Type: application/json" -d '{"content": "Привет"}'

# файл
curl -X POST "$GLITCH_WEBHOOK_URL" \
  -F 'payload_json={"content": "Отчёт за неделю"}' \
  -F "files[0]=@report.pdf"

Если пишете без библиотеки, обрабатывайте ответ 429 сами. Как это делать, описано на странице Пределы частоты.

Что в библиотеках работает иначе

Дата из номера. Библиотеки Discord считают время создания объекта по его номеру. Это created_at в discord.py и createdAt в discord.js. Номера Glitch устроены иначе, поэтому такая дата будет неверной. Точное время отправки сообщения берите из поля timestamp ответа сервера.

Картинки. Библиотеки собирают ссылку на аватарку сами, из адреса картинок и короткого отпечатка из поля avatar. Поэтому важно указать адрес картинок Glitch, как показано выше. Тогда display_avatar.url в discord.py и displayAvatarURL() в discord.js дадут рабочую ссылку, а read() и save() скачают картинку. Если у человека нет своей аватарки, библиотека предложит стандартную картинку Discord, а её у Glitch нет, и по такой ссылке будет ошибка 404.

Ссылки на сообщения. Свойства вроде jump_url ведут на discord.com. Для Glitch они бесполезны.

На этой странице
  1. Как задать вебхук в библиотеке
  2. discord.py
  3. discord.js
  4. Без библиотеки
  5. Что в библиотеках работает иначе