Начало
Библиотеки
Отдельных библиотек для 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, и наш адрес они отклонят.
Номер и ключ проще всего взять из адреса вебхука. Храните адрес в переменной окружения, а не в коде.
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
Установка.
pip install discord.pyАдреса задаются один раз в начале программы. Они действуют и на асинхронный вебхук (discord.Webhook), и на обычный (discord.SyncWebhook).
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, например это бот или веб-сервер.
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 не нужен.
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="Бэкап")Файлы и картинки
# один файл
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 библиотека обрабатывает сама. Она ждёт нужное время и повторяет запрос.
try:
webhook.send("Привет")
except discord.NotFound:
print("Вебхук удалён, нужен новый адрес")
except discord.HTTPException as error:
print(error.status, error.code, error.text)discord.js
Установка. Нужен Node.js 18 или новее.
npm install discord.jsАдреса передаются при создании вебхука в настройке rest. В api — адрес API без версии, /v10 библиотека допишет сама. В cdn — адрес картинок.
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);
});Файлы и картинки
// один файл
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
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
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 -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 они бесполезны.