With the lack of tutorials regarding Discord OAuth2 and how it works, I decided to write my own guide as well as record a video along with it. This article will show how Discord's OAuth2 can be used in order to add a Discord user to a guild. We will be using Python and the requests library for this guide.
Importing reqests
Since requests is the only library we will be using, we have to import it at the top of our code.
import requests
Setting up our variables
We are going to setup 4 variables that will be used later in our code.
API_ENDPOINT = 'https://discord.com/api/v8'
CLIENT_ID = ''
CLIENT_SECRET = ''
REDIRECT_URI = "https://google.com"
```
For the {% raw %}`CLIENT_ID` and `CLIENT_SECRET`, we have to get these from [Discord's Developer Portal]
(https://discord.com/developers/applications).
## Creating our Discord application
We need to create a new application, and give it a name. ![Screenshot 2021-08-05 at 11.40.06](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/070lcvkhavbet5hrj6b2.png)
After creating our application, we can click on the OAUTH2 tab to find our `CLIENT_ID` and `CLIENT_SECRET`. Copy these two values and paste them at the variable definitions above.
![Screenshot 2021-08-05 at 11.42.12](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w42r81w39sz2sb2c2e6o.png)
### Setting up our redirect URI
As you probably noticed, we have a `REDIRECT_URI` too. This is the URI that we will be using to get the code from our user, that we then can use to exchange it for an actual access_token. But we have to add this URI in our Developer Portal. The URI does not matter, it can be anything. But we have to allow it.
![Screenshot 2021-08-05 at 11.48.03](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0n3c8xyxzligxhjoj9qu.png)
## Writing our `exchange_code`function.
This function will allow us to convert the code we get from the user into an access_token, which we then can use to add the user to a guild.
```py
def exchange_code(code):
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
```
Here, we send along our application info, and return the json object that we get back from Discord.
## Writing our `add_to_guild`
This function is just an example of what we can do with the newly acquired access_token. For a full list of what you can do, check out the [Discord OAUTH2 Documentation] (https://discord.com/developers/docs/topics/oauth2)
```py
def add_to_guild(access_token, userID, guildID):
url = f"{API_ENDPOINT}/guilds/{guildID}/members/{userID}"
botToken = "ODcyMjMyMjQ5ODYzNTkzOTk0.YQm3lQ.yB3pFepBcy7K1gQVrBxNfYf_Bdk"
data = {
"access_token" : access_token,
}
headers = {
"Authorization" : f"Bot {botToken}",
'Content-Type': 'application/json'
}
response = requests.put(url=url, headers=headers, json=data)
print(response.text)
```
This function takes in the access_token, the guildID and the userID of the user we want to add to the guild. It also requires a bot token, which you can get from the developer portal.
![Screenshot 2021-08-05 at 11.55.09](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cg2pj8fkik6nwnpto9yg.png)
We send along this bot token in our headers, and then print out the response we get from Discord. If everything went well, this should be an object with info about the user.
## Finishing up our code
Now, all there is left to do is to run our functions, in the correct order.
```py
code = exchange_code('')['access_token']
add_to_guild(code, 'USER_ID', 'GUILD_ID')
```
So what do we pass in to the `exchange_code` function? Well this is the part where the user has to go to the authorize link and authorize our application.
`https://discord.com/oauth2/authorize?response_type=code&client_id=157730590492196864&scope=identify+guilds.join&state=15773059ghq9183habn&redirect_uri=https%3A%2F%2Fgoogle.com&prompt=consent`
You have to plug in your own client_id and the redirect URI you decided to use.
![Screenshot 2021-08-05 at 12.01.32](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dcftw0bjg3vixuclckdg.png)
After authorizing, the user will be sent to our redirect URI. If you look at the uri, you'll find the code that we are after.
![Screenshot 2021-08-05 at 12.02.40](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0mfn4itimodb4hocek62.png)
Copy this code and paste it inside the `exchange_code` function.
## Running our code
Before our code can actually work. We have to invite our Discord bot to the server we wish to add the user to.
`https://discord.com/oauth2/authorize?client_id=123456789012345678&scope=bot+applications.commands`
Again, you have to plug in your own client_id to invite your own bot.
Once it is in the server, everything is ready to work. If you want to try it out, leave the server (transfer ownership to someone else if it is your own), and then run the code with your own code and user id. If you have done everything correctly, the bot will add you back to the guild.
## Done
That is all there is to it. This is my first ever article on dev.to, it was fun writing it and I look forward to writing more in the future!
Top comments (5)
Hi, how we get code from user if the user are not yet on our guild ?
(the code we pass to exchange_code)
Thanks a lot
EDIT : its explain at the end but how we get the user id ? I juste have something like PSEUDO#1234
EDIT2 : this is my function to get user_id :
def get_user_id(self, access_token):
headers = {
'Authorization': f'Bearer {access_token}'
}
response = requests.get('https://discord.com/api/v10/users/@me', headers=headers)
response.raise_for_status()
user = response.json()
return user['id']
Now i have error for assign_role:
def assign_role(self, access_token, user_id, role_id):
url = f"{DISCORD_API_ENDPOINT}/guilds/{self.server_id}/members/{user_id}/roles/{role_id}"
headers = {
"Authorization": f"Bearer {access_token}",
'Content-Type': 'application/json'
}
response = requests.put(url=url, headers=headers)
response.raise_for_status()
Great guide, and as you say, there is barely anything/if anything at all about this on the net. Thanks for doing this.
No worries. Thanks for the comment!
How would i do this with every user who is verified by running a command with the guild id?
Is this able to let everyone with the oAuth in their account to join one server?