Simple Discord bot that:
- collects one wallet address per Discord user through
/submit - lets configured admins trigger a manual draw through
/draw - lets configured admins set a real-time submission log channel through
/log - blocks duplicate users and duplicate wallet addresses
- stores submissions in SQLite
- sends 15 random winners to two Tangem admins every 24 hours
- starts the first draw 24 hours after the first valid submission
/submit wallet:<address>stores the user's wallet address once/drawforces an immediate admin DM draw and resets the next draw to 24 hours after that manual send/log channel:<channel>configures a text channel where every new accepted wallet submission is posted in real time- a user cannot submit a second address
- the same wallet address cannot be reused by another user
/submithas a short anti-spam cooldown per user- each draw contains unique users only
- if fewer than 15 wallets exist, the draw includes only the submitted wallets
- the draw timer is rolling:
- first draw is scheduled 24 hours after the first submission
- after a draw is sent, the next one is scheduled 24 hours after that send time
Admin DM targets default to:
helen_tangem(1415598615681831065)oliwer_defiants(943914248185217077)
- Python 3.11+
- a Discord application with a bot token
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .envFill in .env:
DISCORD_TOKEN=your_bot_token
DISCORD_GUILD_ID=your_tangem_server_id
DATABASE_PATH=data/tangem_lottery.sqlite3
ADMIN_USER_IDS=1415598615681831065,943914248185217077
WINNERS_PER_DRAW=15
DRAW_INTERVAL_HOURS=24
LOG_LEVEL=INFODISCORD_GUILD_ID is optional, but recommended for the Tangem server because guild command sync appears immediately. Without it, the command is registered globally and can take longer to show up.
source .venv/bin/activate
tangem-lottery-botBuild the image:
docker build -t tangem-lottery-bot .Run the container:
docker run -d \
--name tangem-lottery-bot \
--restart unless-stopped \
--env-file .env \
-v "$(pwd)/data:/app/data" \
tangem-lottery-botNotes:
- keep
DATABASE_PATH=data/tangem_lottery.sqlite3in.env - the
data/volume preserves wallet submissions and draw state across restarts - use
docker logs -f tangem-lottery-botto watch bot logs - to update the bot, rebuild the image and recreate the container
Redeploy example:
docker build -t tangem-lottery-bot .
docker rm -f tangem-lottery-bot
docker run -d \
--name tangem-lottery-bot \
--restart unless-stopped \
--env-file .env \
-v "$(pwd)/data:/app/data" \
tangem-lottery-botThe bot does not need any privileged intents or elevated permissions.
- scopes:
bot,applications.commands - bot permissions integer:
0
Admins must allow DMs from server members or the bot may not be able to deliver the daily draw.
If Discord returns 50278 Cannot send messages to this user, the recipient's DM privacy settings are blocking the bot.
The repo includes a sample systemd unit at deploy/tangem-lottery-bot.service.
Example deployment flow:
git clone <your-repo-url> /opt/tangem-lottery-bot
cd /opt/tangem-lottery-bot
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
cp .env.example .envThen:
- Edit
.env - Copy
deploy/tangem-lottery-bot.serviceto/etc/systemd/system/ - Update the paths and user in the service file
- Run
sudo systemctl daemon-reload - Run
sudo systemctl enable --now tangem-lottery-bot - Check logs with
journalctl -u tangem-lottery-bot -f
source .venv/bin/activate
pytest