# Мироры. Что откуда брать и какой алгоритм работы.

By [soldi](https://paragraph.com/@soldi) · 2022-09-12

---

Канал с кодингом в нфт и около нфт сфере: [https://t.me/soldidlos](https://t.me/soldidlos)

**Разберем миррор для дискорда. Язык: Python 3.10**

Миррор - программа, которая пересылает ваши сообщения из определенного канала на ваш сервер с помощью Webhook.

Webhook - это механизм отправки уведомлений. В дискорде хуки очень удобная штука

### Импорты

    import math
    import os
    import re
    import sqlite3
    import time
    import requests
    import telebot
    from discord_webhook import DiscordWebhook, DiscordEmbed
    

**math** - использую для удобных математических расчетов **os** - взаимодействие с системой (нужно для работы с файлами на компьютере) **re** - улучшенный replace - форматирование строки **sqlite3** - локальная база данных **time** - использую для небольших пауз во время работы программы **requests** - запрос для получения инфы **telebot** - использую для сообщений в тг об ошибках, если они появляются, можно не ставить, но мне так удобнее **discord\_webhook** - для работы с вебхуками дискорда

### Принцип работы

1.  Получаем инфу через запрос
    
2.  Парсим ее
    
3.  Добавляем новые значения в бд
    
4.  Если новое значение появилось, то отправляем хук
    
5.  Если нового значения нет, то идем дальше
    
6.  И все это в бесконечном цикле
    

### Сам код

Создаем дб. [Неплохой гайд](https://pythonru.com/osnovy/sqlite-v-python), но лучше всегда читать [оф документацию](https://docs.python.org/3/library/sqlite3.html) Рекомендую добавить EXISTS в запрос, чтобы избежать ошибок при перезапуске программы

    CREATE TABLE IF NOT EXISTS table_name (columns)
    

Далее нам нужно получить инфу, которую мы будем пересылать

    headers = {
        'authorization': 'token'
    }
    r = requests.get(url=f'https://discord.com/api/v9/channels/{channel_id}/messages?limit=50', headers=headers).json()
    

headers для того, чтобы дискорд вас пропустил, вставляете токен аккаунта В реквесте использую [f string](https://habr.com/ru/post/462179/), потому что у меня функция гоняется в цикле и одна программа парсит сразу несколько каналов по очереди. limit - кол-во сообщений, которое будет содержать один запрос, максимум 50 Использую метод json(), чтобы сразу получить на выходе джсон файл, с которым дальше работаю

Смотрим, что мы получаем из запросе и на основе этого парсим инфу, как вам удобно, небольшой пример:

        for value in r:
            try:
                uniq_id = value['id']
                username = f"{value['author']['username']}#{value['author']['discriminator']}"
                description = value['embeds'][0]['description']
                title = value['embeds'][0]['title']
                    try:
                        вставляем значения в таблицу
                        отправляем хук
                    except:
                        pass
            except Exception as ex:
                print(ex)
                pass
    

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

По поводу отправки хука. Тут формируйте как вам удобно, почитайте док библы и выставляйте аватарку и юзернейм, чтобы красиво было и было понятно кто отправляет сообщение.

Вот вам лайфхак как аватарка формируется

    avatar_id = f"{value['author']['id']}/{value['author']['avatar']}"
    avatar = f"https://cdn.discordapp.com/avatars/{avatar_id}.webp?size=80"
    

Ну и в итоге загоняете это все в цикл, не забывайте разбивать все на функции, чтобы каши не было. Модифицировать можно как угодно, у меня например два словаря, один с каналами, второй с вебхуками. Ключи и там и там одинаковые, например:

    channel_ids = {
        'degendao_calls': '925530174701830206',
    }
    webhooks = {
        'degendao_calls': 'webhook'
    }
    

И программа работает так, что при получении нового сообщения из канала, он отправляет именно в этот вебхук. То бишь одна функция на отправку, одна на парсинг и все в цикле. Если не автоматизировать как-то так, то придется делать разные функции на разные каналы, ибо айди канала и вебхук меняется.

Вот так примерно олл ин олл будет выглядеть

    def get_data(channel_id, channel_name):
        try:
            r = requests.get(url=f'https://discord.com/api/v9/channels/{channel_id}/messages?limit=1', headers=headers).json()
        for value in r:
            try:
                uniq_id = value['id']
                username = f"{value['author']['username']}#{value['author']['discriminator']}"
                description = value['embeds'][0]['description']
                title = value['embeds'][0]['title']
                    try:
                        вставляем значения в таблицу
                        отправляем хук
                    except:
                        pass
            except Exception as ex:
                print(ex)
                pass
        except Exception as ex:
            print(f"req error: {ex} in {channel_name}")
            pass
    
    def send_hook(вся инфа, которая используете):
        отправка хука, кстати небольшой совет, обработайте исключения по типу длинны сообщений, наличие или отсутствие ембеда, вложения итд
    В общем поиграйтесь разными сообщениями и пробуйте их спарсить, чтобы потом программа не пропускала ничего и не выбивала ошибки
    
    def main():
    db = sqlite3.connect('discord_parser.db')
    sql = db.cursor()
    sql.execute(f"CREATE TABLE IF NOT EXISTS table_name {keys[i]} (columns)")
    db.commit()
        while True:
            get_data()
            time.sleep(1)
    
    if __name__ == '__main__':
    main()
    

Думаю, что этой инфы будет достаточно, чтобы разобраться в том, как это работает и попробовать написать самому. Всем спасибо за внимание, можете смело заходить в чатик и писать любые вопросы, всем постараюсь ответить. Канал: [https://t.me/soldidlos](https://t.me/soldidlos) Чатик: [https://t.me/soldi\_chat](https://t.me/soldi_chat)

---

*Originally published on [soldi](https://paragraph.com/@soldi/6aBJe3PjLGfGgAtegSlU)*
