Эта статья продолжение первой части. Мы подробно рассмотрим систему модерации Midjourney, коснемся лимитов скорости (rate limits) Discord, двух самых сложных тем. В конце статьи приведен рабочий код. Прежде чем мы начнем, убедитесь, что у вас есть учетная запись Discord с активной подпиской Midjourney. Базового плана за $10 будет достаточно. Следуйте этим простым шагам, чтобы получить: Идентификатор сервера Discord, который будет упомянут в этой статье как server_id Идентификатор канала Discord, который будет упомянут в этой статье как channel_id Токен Discord, который будет упомянут в этой статье как discord_token Оригинальная документация Discord предлагает использовать HTTP заголовки для определения случаев, когда лимит скорости превышен, и соответствующе корректировать действия. Этот подход необходим для сложных или коммерческих приложений, в этой статье мы будем использовать более простой, но не менее эффективный метод.  Мы добавим паузу в 350 миллисекунд перед каждым вызовом API Discord. Поскольку наш код работает с одним потоком, это будет достаточно для того, чтобы оставаться в пределах лимита. Общая производительность нашей небольшой программы не пострадает, поскольку время ответа Midjourney гарантированно превосходит предложенные 350 миллисекунд. Midjourney выполняет как пре-модерацию так и пост-модерацию команд /imagine, вам потребуется надежный способ обнаружения обоих случаев. При выполнении POST-запроса с командой /imagine в канале Discord (как описано в первой части), вы столкнетесь с семью возможными случаями:  Успешное выполнение Через несколько секунд размещенное сообщение появится в канале с исходным идентификатором сообщения id, статусом (Waiting to start) в поле content и с полем type  установленным в 0.   GET https://discord.com/api/v10/channels/channel_id/messages   Как только Midjourney завершит генерацию, исходное сообщение будет удалено, Midjourney разместит окончательное сообщение с новым идентификатором id содержащим результаты генерации.  GET https://discord.com/api/v10/channels/channel_id/messages   Пре-модерация Это самый простой случай: размещенное сообщение никогда не появится в канале. Вы увидите что-то подобное этому.   Сообщения, помеченные как  “Only you can see this” (Только вы можете видеть это), могут быть получены с помощью Discord Gateway API.   Пост-модерация Пост будет появляться в канале так же, как в случае "Успешного выполнения".   GET https://discord.com/api/v10/channels/channel_id/messages   Генерация может даже начаться, и вы увидите прогресс, но внезапно остановится с сообщением, похожим на следующее.   GET https://discord.com/api/v10/channels/channel_id/messages   Эфемерная модерацияНекоторые слова в вашем запросе могут вызвать "мягкую модерацию". Генерация начинается и успешно завершается, но после завершения сообщение будет отображаться как "Original message was deleted" (Исходное сообщение было удалено). Сообщение больше не возвращается запрос GET https://discord.com/api/v10/channels/channel_id/messages, даже если изначально оно было. Пример ниже. GET https://discord.com/api/v10/channels/channel_id/messages   Сгенерированное сообщение было удалено (Original message was deleted).   Сообщения, помеченные как  “Only you can see this” (Только вы можете видеть это), могут быть получены с помощью Discord Gateway API.   Неверный запросЭто происходит когда вы указываете неправильный параметр. Как и в случае пре-модерации размещенное сообщение не появится в канале. Рекомендуется добавить код для проверки синтаксиса запроса перед его размещением. Мы планируем рассмотреть тему проверки синтаксиса запроса в одной из наших последующих статей. Сообщения, помеченные как  “Only you can see this” (Только вы можете видеть это), могут быть получены с помощью Discord Gateway API.   Сообщение в очередиВ зависимости от вашего плана подписки на Midjourney у вас может быть от 3 (Basic & Standard) до 15 (Pro & Mega) одновременных выполнений заданий. Как только этот лимит достигнут, запросы на выполнение заданий будут поставлены в очередь и сообщения, связанные с этими заданиями, не будут немедленно появляться в GET https://discord.com/api/v10/channels/channel_id/messages до тех пока Midjourney не завершит выполнение одного из активных заданий. Фактически это означает, что задание было помещено во внутреннюю очередь Midjourney. Сообщения, помеченные как  “Only you can see this” (Только вы можете видеть это), могут быть получены с помощью Discord Gateway API.   Желательно минимизировать или полностью исключить случаи "Сообщение в очереди", поскольку существует значительная вероятность того, что Midjourney может ограничивать ваши запросы на генерацию в таких случаях и использовать это как индикатор нарушения условий использования Midjourney (…may not use automated tools to access, interact with, or generate Assets through the Services… | …нельзя использовать автоматические средства для доступа, взаимодействия или генерации ресурсов через услуги…). Очередь переполнена Внутренняя очередь задач Midjourney может вмещать до 10 задач, после чего вы получите сообщение "Очередь переполнена". Вам придется подождать и попробовать снова.   Сообщения, помеченные как  “Only you can see this” (Только вы можете видеть это), могут быть получены с помощью Discord Gateway AP Желательно минимизировать или полностью исключить случаи "Очередь переполнена", поскольку существует значительная вероятность того, что Midjourney может ограничивать ваши запросы на генерацию в таких случаях и использовать это как индикатор нарушения условий использования Midjourney (…may not use automated tools to access, interact with, or generate Assets through the Services… | …нельзя использовать автоматические средства для доступа, взаимодействия или генерации ресурсов через услуги…). Как вы заметили в предыдущем абзаце, некоторые сообщения можно извлечь с использованием Discord Gateway API. В отличие от Discord REST API, который мы используем в этой статье, Discord Gateway API требует использования WebSocket API для обмена данными в реальном времени между вашим клиентским приложением и сервером Discord. Это добавляет еще один уровень сложности и, что более важно, может увеличить вероятность бана. В подавляющем большинстве случаев вы можете создать алгоритм без использования Discord Gateway API. Мы планируем рассмотреть крайние случаи, когда использование Discord Gateway API является единственным решением, в последующих статьях. Учитывая информацию, полученную из предыдущих абзацев, вы можете реализовать следующую простую стратегию: Убедитесь, что у вас есть хотя бы один свободный слот (job). Для этого вы можете использовать либо отдельную учетную запись Midjourney для всех ваших автоматизированных задач, либо тщательно управлять количеством вручную запущенных задач, ограничив их до максимум двух. Этот подход поможет избежать как случаев "Сообщение в очереди", так и случаев "Очередь переполнена". Перед размещением /imagine запроса выполните GET https://discord.com/api/v10/channels/channel_id/messages, чтобы получить идентификатор id первой записи. По умолчанию этот API возвращает 50 последних сообщений из канала, упорядоченных в порядке убывания, с самым свежим сообщением в начале списка. После размещения /imagine запроса с использованием POST https://discord.com/api/v10/interactions, продолжайте проверять канал каждые 3-5 секунд, выполняя GET https://discord.com/api/v10/channels/channel_id/messages. Сравнивайте идентификатор id первой записи с значением, полученным на предыдущем этапе. Если через 30 секунд вы не видите новой записи в канале, можно предположить, что у вас либо случай пре-модерации, либо "Неверного запроса", и ваш запрос, возможно, требует пересмотра. Как только вы определите, что новое сообщение действительно появилось в вашем канале, сохраните идентификатор id этого сообщения. Продолжайте выполнять GET https://discord.com/api/v10/channels/channel_id/messages каждые 20-30 секунд, чтобы проверить следующие оставшиеся случаи: Успешное выполнение: когда генерация завершена, сообщение с исходным идентификатором id больше не присутствует в канале. Вместо него присутствует новое сообщение с непустым массивом компонентов components. Сгенерированное изображение можно получить из поля attachments[0].url. Пост-модерация: когда сообщение с исходным идентификатором id все еще присутствует, и его поле content заканчивается на (Stopped). Эфемерная модерация: когда идентификатор id первой записи совпадает с значением, полученным до размещения изображения-запроса. Этот алгоритм позволит вам эффективно управлять процессом генерации с помощью Midjourney /imagine, учитывая различные все возможные сценарии.  Midjourney Discord API guru