Розробка Discord-бота роздачі ролей за NFT

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка Discord-бота роздачі ролей за NFT
Середній
~3-5 днів
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1306
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1218
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    920
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1147
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    610
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    885

Discord бот для розподілу ролей за NFT

Token gating — стандартна практика для спільнот NFT. Маєш NFT з колекції — отримаєш доступ до приватних каналів, ранній доступ, виключні дропи. Технічно це верифікація: гаманець з потрібним NFT → Discord акаунт → роль. Завдання виглядає простим, але між «верифікацією» та «справжнім постійним доступом» лежить цілий шар інфраструктури, який передбачено ламається.

Архітектура системи

Зв'язок wallet ↔ Discord

Користувач натискає «Verify» → редирект на сторінку верифікації → підключає гаманець через WalletConnect v2 → підписує повідомлення (без газу) → сервер перевіряє підпис → зберігає {discordId: walletAddress}.

Підпис повідомлення — не транзакція, користувач нічого не платить. Стандартне повідомлення для верифікації:

Verify Discord: username#1234
Nonce: a3f8b2c1
Timestamp: 1711234567

Nonce — випадкова рядок, унікальна для кожної сесії, з TTL 5 хвилин. Без nonce можливі replay-атаки: скопійований підпис можна переозначити.

Верифікація підпису на бекенді:

import { verifyMessage } from 'viem';

const isValid = await verifyMessage({
    address: claimedAddress,
    message: expectedMessage,
    signature: userSignature
});

Перевірка володіння NFT: три підходи

Прямий RPC виклик. balanceOf(wallet, tokenId) через ethers.js або viem. Простий, працює для малих колекцій. Проблема: при 10 000 користувачів — 10 000 RPC викликів при кожній перевірці.

Alchemy/Moralis NFT API. getNFTsForOwner(wallet, contractAddress) — один запит повертає всі токени. Швидко, але залежність від зовнішнього сервісу. При даунтаймі Alchemy — бот не працює.

The Graph subgraph. Індексуємо Transfer події колекції, будуємо {owner: [tokenIds]} маппінг. Швидкий GraphQL запит. Затримка індексації ~1-5 хвилин — при швидкій продажі токена користувач ще 5 хвилин зберігає роль.

Для продакшн ботів використовуємо Alchemy NFT API як основний з The Graph як резервна та прямим RPC як останній fallback.

Discord bot: slash команди та обробка подій

Бот реалізований на discord.js v14. Ключові slash команди:

  • /verify — початок верифікації, бот відправляє ephemeral повідомлення зі ссилкою
  • /check — примусова перевірка володіння (для користувачів, які продали токен)
  • /roles — показати всі ролі та вимоги до них

Ролі призначаються через guild.members.cache.get(userId)?.roles.add(roleId). Вимагає дозволу MANAGE_ROLES та роль бота має бути вище за призначувані ролі в ієрархії — часта помилка при налаштуванні.

async function syncUserRoles(userId: string, wallet: string): Promise<void> {
    const member = await guild.members.fetch(userId);
    const ownedTokens = await getNFTsForOwner(wallet, CONTRACT_ADDRESS);
    
    for (const [roleId, requirement] of ROLE_REQUIREMENTS) {
        const qualifies = checkQualification(ownedTokens, requirement);
        if (qualifies && !member.roles.cache.has(roleId)) {
            await member.roles.add(roleId);
        } else if (!qualifies && member.roles.cache.has(roleId)) {
            await member.roles.remove(roleId);
        }
    }
}

Періодична ресинхронізація

Критичний момент: користувач продав NFT, має втратити роль. Бот не отримує подію від Discord — він повинен періодично перевіряти сам.

Cron job кожні 10-30 хвилин: для кожного верифікованого користувача перевіряємо поточний баланс, оновлюємо ролі. При 1000 користувачів та 30-хвилинному інтервалі — ~33 API запиту на хвилину. Укладається в ліміти Alchemy.

Оптимізація: слухаємо Transfer події контракту через WebSocket (Alchemy WebSocket API). При будь-якому Transfer перевіряємо, задіяний ли верифікований гаманець, та негайно оновлюємо роль. Це знижує затримку до секунд.

const provider = new WebSocketProvider(ALCHEMY_WS_URL);
const contract = new Contract(NFT_ADDRESS, erc721Abi, provider);

contract.on('Transfer', async (from, to, tokenId) => {
    const affectedWallets = [from, to].filter(w => w !== ethers.ZeroAddress);
    for (const wallet of affectedWallets) {
        await syncRolesForWallet(wallet);
    }
});

Підтримка декількох колекцій та ролей на основі ознак

Справжні проекти вимагають складних умов:

  • Маєш ≥3 токени з колекції A → VIP роль
  • Маєш токен з ознакою «Legendary» → роль Legendary
  • Маєш токен з колекції A та колекції B → роль Collab

Для ролей на основі ознак потрібен доступ до метаданих. Alchemy getNFTsForOwner повертає tokenMetadata включаючи attributes. Конфігурація ролей у JSON:

{
  "LEGENDARY_ROLE_ID": {
    "contract": "0x...",
    "minBalance": 1,
    "requiredTrait": {"trait_type": "Rarity", "value": "Legendary"}
  }
}

Stack

Компонент Технологія
Бот discord.js v14, TypeScript
Wallet connect WalletConnect v2 (веб-додаток для верифікації)
NFT дані Alchemy NFT API + WebSocket
База даних PostgreSQL (userId ↔ wallet маппінг)
Хостинг Railway або Render (постійний процес)
Верифікація підписів viem verifyMessage

Орієнтири за часом

Базовий бот з однією колекцією та однією роллю — 3-4 дні. Розширений з декількома колекціями, ролями на основі ознак та реал-тайм синхром через WebSocket — 4-5 днів.