Introduction
Today we will build a Discord.py
and use Flask
to allow to integrate the Ethereum wallet addresses with the wallet, you use the Flask
frontend to connect the wallet while it's logged in the Flask
system and when you want to check if synced, the Discord.py
bot sends a JSON POST
request to read.
SO LET'S GOOOOO 🔥🔥🔥
Setup the Flask Page
Start by creating a new directory, and in that directory, create a folder for the Flask page:
mkdir metamask-flask-discord
cd metamask-flask-discord
mkdir flask
cd flask
Now, create an app.py
file and a log.txt
and paste this into the app.py
:
from flask import Flask, render_template, Response, request
app = Flask(__name__)
@app.route('/<discord_id>')
def index(discord_id):
return render_template('index.html', discordId = discord_id)
@app.route('/sync', methods=['POST'])
def sync():
discord_id = request.json['discordId']
wallet_address = request.json['walletAddress']
with open('log.txt', 'r+') as f:
file = f.read()
if discord_id in file:
if wallet_address in file:
Pass
else:
f.write(' ' + wallet_address)
else:
f.write('\n' + discord_id + ' ' + wallet_address)
f.close()
@app.route('/read', methods=['POST'])
def read():
discord_id = request.json['discordId']
with open('log.txt', 'r') as f:
file = f.read()
if discord_id in file:
wallet_addresses = file.split(discord_id)[1].split(' ')
wallet_addresses.pop(0)
return Response(str(wallet_addresses), mimetype='application/json')
else:
return Response('No wallet address found', mimetype='application/json')
This is our main flask
file, what we are doing here, we are setting 3
routes:
-
/
(main) -
sync
(to sync with the logs which also syncs with the bot) -
read
(provides wallet addresses for a specific user)
And for sync
and read
we will receive a JSON POST
request, POST
is more safer, that's why I personally prefer it.
Also, in both sync
and read
we open up the log.txt
either to read wallet addresses for a specific user, or write new wallet addresses for a new user.
Now, let's create the landing page where you can connect your MetaMask
wallet:
mkdir templates
touch index.html
Now in your index.html
, paste this:
<!DOCTYPE html>
<html>
<head>
<title>MetaMask Connection</title>
</head>
<body>
<center>
<h1>Connect Your MetaMask Wallet Here To Connect With Discord!</h1>
<button id="connectWallet" onclick="">Connect Wallet</button>
<button id="syncDiscord" onclick="">Sync Discord</button>
<p id="walletAddress"></p>
<script type="text/javascript">
var discordId = "{{ discordId }}";
window.walletAddress = null
const syncDiscord = document.getElementById('syncDiscord');
const connectWallet = document.getElementById('connectWallet')
const walletAddress = document.getElementById('walletAddress')
function checkInstalled() {
if (typeof window.ethereum == 'undefined') {
walletAddress.innerText = 'Please install MetaMask to continue.'
return false
}
connectWallet.addEventListener('click', connectWalletwithMetaMask)
}
async function connectWalletwithMetaMask() {
const accounts = await window.ethereum.request({ method: 'eth_requestAccounts' })
.catch((e) => {
console.error(e.message)
return
})
if (!accounts) { return }
window.walletAddress = accounts[0]
walletAddress.innerText = window.walletAddress
connectWallet.innerText = 'Sign Out'
connectWallet.removeEventListener('click', connectWalletwithMetaMask)
setTimeout(() => {
connectWallet.addEventListener('click', signOutOfMetaMask)
syncDiscord.addEventListener('click', syncDiscordWithWallet)
}, 200 )
}
function signOutOfMetaMask() {
window.walletAddress = null
walletAddress.innerText = ''
connectWallet.innerText = 'Connect Wallet'
connectWallet.removeEventListener('click', signOutOfMetaMask)
syncDiscord.removeEventListener('click', syncDiscordWithWallet)
setTimeout(() => {
connectWallet.addEventListener('click', connectWalletwithMetaMask)
}, 200 )
}
window.addEventListener('DOMContentLoaded', () => {
checkInstalled()
})
async function syncDiscordWithWallet() {
alert("If the wallet is already in the system, nothing would happen, if not, it would add it to the bot system.")
const response = await fetch('/sync', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
walletAddress: window.walletAddress,
discordId: discordId
})
})
}
</script>
</center>
</body>
</html>
So here we make few buttons, and make a few event listeners which run certain functions, and for example, when the wallet is connected, we replace the event listener to listen to the sign out function, why would the user sign in again if he is already signed in, hahah!
And for syncing here, we send a JSON POST
request with walletAddress
and discordId
to /sync
to save it!
Working on our Discord.py bot
Start by creating a directory and creating a .env
& bot.py
:
mkdir discordbot
cd discordbot
touch .env
touch bot.py
Now, open up your .env
file where you save your token just like this:
TOKEN=<your-discord-bot-token-here>
Let's work on the actual bot now:
import discord
from discord.ext import commands
import requests
import os
from dotenv import load_dotenv
load_dotenv()
token = os.getenv('TOKEN')
intents = discord.Intents.all()
bot = commands.Bot(command_prefix='$', intents=intents)
@bot.event
async def on_ready():
print("Bot is ready")
print("Username: {}".format(bot.user.name))
print("ID: {}".format(bot.user.id))
print("Discord.py Version: {}".format(discord.__version__))
print("------")
@bot.command()
async def linkwallet(ctx):
await ctx.author.send("Click on this link to connect your MetaMask Wallet")
await ctx.author.send("Link your wallet here: http://127.0.0.1:5000/{}".format(ctx.author.id))
@bot.command()
async def readuser(ctx, userid: str):
r = requests.post('http://127.0.0.1:5000/read', json={'discordId': userid})
await ctx.send(r.text)
bot.run(token)
So what we are doing is simple, first linkwallet
command which actually sending a DM with a link like this to connect: http://127.0.0.1:5000/<discord-id>
And readuser
gets a userid
and send a JSON request to read and returns the JSON
response back to the user!
Try it out!
Let's run the flask
app:
cd flask
flask run
And let's run the bot:
cd discordbot
python bot.py
Video Demo:
Important Links 🔗
Thanks for reading!!!
Thanks for reading this article 🚀
Hope you learned something useful !!!