Python Discord OAuth2 - Guild.Join (Joining a Guild) - python

Hi I'm trying to do a 'Authorize with Discord' that automatically joins the user to my guild.
I'm running a Flask application that handles all of these.
So far, here's my code:
def add_to_guild(access_token, userID, guildID):
url = f"{Oauth.discord_api_url}/guilds/{guildID}/members/{userID}"
headers = {
"Authorization" : f"Bearer {access_token}"
}
response = requests.post(url=url, headers=headers)
print(response.text)
However this doesn't work. I get a error message saying:
{"message": "405: Method Not Allowed", "code": 0}
On the OAuth2 docs, it says that i'm suppose to get a response of 201 if the user successfully joins, or 204 if user is already in the guild.
UPDATE 1:
I changed the method to requests.get and now I receive this error:
{"message": "401: Unauthorized", "code": 0}
UPDATE 2:
I created a Bot, invited it to my discord guild and successfully was able to get some information about my user in the guild. however once i left and try to run the link again, i got this error
{"message": "Unknown Member", "code": 10007}
UPDATE 3:
I changed the method to PUT and now I'm getting a Bad Request
def add_to_guild(access_token, userID):
url = f"{Oauth.discord_api_url}/guilds/{guildid i cant show}/members/{userID}"
botToken = "cant show also"
headers = {
"Authorization" : f"Bot {botToken}",
'Content-Type': 'application/json'
}
response = requests.put(url=url, headers=headers)
print(response.text)

To add a member, you should use requests.put(), and the Guilds Auth header needs to be a Bot token, so change to:
headers = {
"Authorization" : f"Bot {access_token}"
}
And make sure you are passing a Bot token. More at: https://discord.com/developers/docs/reference
The Authorization header must be a Bot token (belonging to the same
application used for authorization), and the bot must be a member of
the guild with CREATE_INSTANT_INVITE permission.
To get the member, you would use requests.get() without the bot header.

Update 3 put() is the way to go
However, you're still missing the JSON payload which must include the user access token received from the token exchange from a code grant.
data = {
"access_token" : access_token
}
Then fire your request with passing data to json, so
response = requests.put(url=url, json=data, headers=headers)
print(response.json)

Related

Moodle Create User API Invalid Parameter Exception

I am trying to register a user via API using Python Request.
Here is my code
import requests
url = "www.website.com/webservice/rest/server.php?createpassword=1&username=thisissifumwike&auth=manual&password=Tester#2023.&firstname=Domain&lastname=Tester&email=hello#gmail.com&maildisplay=sifugmail&city=Daressalaam&country=Tanzania&timezone=99&description=I am a good tester&firstnamephonetic=Sifu&lastnamephonetic=Domain&middlename=Tester&alternatename=Tunety&interests=books, codes, forex&idnumber=FMM001&institution=FMM&department=Traders&phone1=0611222333&phone2=0611333222&address=Daressalaam&lang=en&calendartype=gregorian&theme=default&mailformat=1&customfields=&wstoken=token&wsfunction=core_user_create_users&moodlewsrestformat=json"
payload={}
headers = {}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
However upon sending that request I get this response
{
"exception": "invalid_parameter_exception",
"errorcode": "invalidparameter",
"message": "Invalid parameter value detected"
}

When I try to change volume with Spotify API, I get error code 403

When I try to change the volume, I get:
requests.exceptions.HTTPError: 403 Client Error: Forbidden for url: https://api.spotify.com/v1/me/player/volume
I checked if my client_id and client_secret, everything seems fine. Also I have premium account.
import requests
from client_secrets import client_id, client_secret
AUTH_URL = 'https://accounts.spotify.com/api/token'
# POST
auth_response = requests.post(AUTH_URL, {
'grant_type': 'client_credentials',
"scope": "user-modify-playback-state",
'client_id': client_id,
'client_secret': client_secret,
})
# convert the response to JSON
auth_response_data = auth_response.json()
# save the access token
access_token = auth_response_data['access_token']
headers = {
'Authorization': 'Bearer {token}'.format(token=access_token)
}
data = {"volume_percent": 10}
response = requests.put("https://api.spotify.com/v1/me/player/volume",data=data, headers=headers)
response.raise_for_status()
Several authorization flows are detailed in their documentation but your request doesn't match any of them. If I understand correctly your app is just a server-side code without any frontend which means that the Client Credentials Flow is the one that best matches your need. In this flow you don't need to send the client ID and secret in the request body instead, you need to send them in the Authorization header in the following format: Basic <base64 encoded client_id:client_secret>.
Also, make sure to set the Content-Type header to application/x-www-form-urlencoded as stated in the documentation.
Otherwise, the rest seems fine.

"Handle could not be extracted" error in POST request (Exactonline)

I am trying to send POST request in order to recieve access and refresh tokens for OAuth2 authorization in Exact Online services.
I was able to retrieve authorization code, which is used to obtain these tokens. When I try to send POST request with the following parameters, I recieve an error "invalid_request" with description "Handle could not be extracted".
Screenshot of an error message
My code is pretty simple but I cant see the problem.
import requests
id_client = '***'
secret_key_client = '***'
redirect_uri = 'https://www.redirect.uri/'
response_type = 'code'
force_login = '0'
code = "***"
response = requests.post('https://start.exactonline.be/api/oauth2/token',
data={
'code': code,
'redirect_uri': redirect_uri,
'response_type': 'code',
'client_id': id_client,
'client_secret': secret_key_client
})
print(response.text)
I have also tried to change parameter name "response_type" to "grant_type" and its value to "autorization_code" and it didnt work for me.

Spotify API get user saved tracks error 401 missing token

I'm building a discord bot with discord.py and I'm trying to get the spotify user saved tracks.
This is my auth def:
#classmethod
def get_token(self):
CLIENT_ID = 'myclientid'
CLIENT_SECRET = "myclientsecret"
SPOTIFY_TOKEN_URL = "https://accounts.spotify.com/api/token"
client_token = base64.b64encode("{}:{}".format(CLIENT_ID, CLIENT_SECRET).encode('UTF-8')).decode('ascii')
headers = {"Authorization": "Basic {}".format(client_token)}
payload = {"grant_type": "client_credentials"}
token_request = requests.post(SPOTIFY_TOKEN_URL, data=payload, headers=headers)
access_token = json.loads(token_request.text)["access_token"]
return access_token
This is my def where I try to get the user saved tracks:
#commands.command(name='splayfav', aliases=['splayfavorites', 'splaysavedtracks'], description="Command to see the info from spotify \n __Example:__ \u200b \u200b *!infos*")
async def play_saved_tracks_from_spotify(self, ctx):
token = self.get_token(ctx)
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': f'Bearer {token}',
}
response = requests.get('https://api.spotify.com/v1/me/tracks', headers=headers)
print(response.text)
I get this error:
{
"error" : {
"status" : 401,
"message" : "Missing token"
}
}
But If I go in the Spotify API console and get manually a token and put it manually after bearer, then it works, obviously I'm trying to automate the process so I can't take it by hand every time. If I print the token it's actually a token(I mean it's not None or similar), but it's like if It is the wrong one.
How can I fix this problem?
This error message is stupid. What it should tell you is that your authorization token does not have the grant to access the user.
There's 2 different ways to authorize:
client credentials (as you do, can't access any user related stuff)
Authorization Code Flow, see: https://developer.spotify.com/documentation/general/guides/authorization/code-flow/
The second way requires a bit more setup in your app. Basically get redirected to spotify webpage, then the user selects allow for the required permissions, then you get back a code and with that you can get a token and the refresh token (this one is the interesting part).
Now this is quite a hustle to get through, but once you have the refresh token you can basically do almost the same call you do just to get a refreshed access token. (See "Request a refreshed Access Token" at the bottom of the page I linked above)
So with refresh token you can do:
POST https://accounts.spotify.com/api/token
HEADER:
Authorization: Basic $base64(clientId:clientSecret)
BODY Parameters (form url encoded)
grant_type: refresh_token
refresh_token: <your value here>
Use this improved access token and it will work.

Starting a conversation with a chat bot hosted on Microsoft Azure through HTTP request in Python

A Microsoft tutorial shows that in order to set up a conversation with a bot I should issue the following HTTP request:
POST https://directline.botframework.com/api/conversations
Authorization: Bearer SECRET_OR_TOKEN
My question is if I can achieve this with the following Python code:
import requests
r = requests.post('https://directline.botframework.com/api/conversations',
params = {'Authorization':'Bearer ftmhNAqZ2tw.cwA.qIA.Xz2ZWfYJzxd8vJjcK9VmINWNLxlvKiM5jC8F_cbaf0s'})
If I print the response with print(r.content) it says:
{ "error": {
"code": "BadArgument",
"message": "Missing token or secret" } }
HTTP requests have three areas where content can be sent:
URL parameters
Body
Headers
To set these in python's requests package the following can be used (POST method assumed, but all are the same):
URL Parameters:
requests.post('https://myurl.com', params = {'MyParam':'MyValue'})
# equivilient to http://myurl.com?MyParam=MyValue
Body:
requests.post('https://myurl.com', data={"key":"value"})
# or if sending json data
requests.post('https://myurl.com', data=json.dumps(myData))
Headers:
requests.post('https://myurl.com', headers={"headername":"value"})
In your specific case, while the API is not well documented - we can assume they expect the "Authorization" data to be sent in a header, as this is standard. In this case, you need to assign headers as follows:
requests.post('https://directline.botframework.com/api/conversations', headers={'Authorization':'Bearer ftmhNAqZ2tw.cwA.qIA.Xz2ZWfYJzxd8vJjcK9VmINWNLxlvKiM5jC8F_cbaf0s'})
The bearer token needs to be sent as a header, not as a payload or query parameter.
You need to use the headers argument:
auth = {'Authorization': 'Bearer xxxYourBearerTokenHerexxx'}
r = requests.post('https://directline.botframework.com/api/conversations', headers=auth)
print(r) # <Response [200]>

Categories

Resources