I am trying to make a small app to send messages to the ChatWork app. I manage to get the code from the authorization when I sign in, but when I try to use this code to generate the token, I am getting 401. So, really do not know what I am doing wrong. I appreciate your help. This is the code:
import requests
from urllib.parse import urlencode, urlparse, parse_qs
import hashlib
import base64
import secrets
# Your ChatWork OAuth 2.0 client ID and redirect URI
client_id = "my_client_ID"
client_secret = "my_client_secret"
redirect_uri = "https://example.com/"
state = "343ab3341331218786ef" # This is for CSRF staff
# URL for the OAuth 2.0 authorization and token endpoints
auth_endpoint = "https://www.chatwork.com/packages/oauth2/login.php"
token_endpoint = "https://oauth.chatwork.com/token"
# Generate a code verifier
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b'=').decode('utf-8')
# Calculate the code challenge
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').replace('=', '')
# Parameters for the authorization request
params = {
"response_type": "code",
"client_id": client_id,
"redirect_uri": redirect_uri,
"scope": "rooms.all:read_write",
"state": state,
"code_challenge": code_challenge,
"code_challenge_method": "S256"
}
# Construct the authorization URL
auth_url = auth_endpoint + "?" + urlencode(params)
# Print the authorization URL
print("Open this URL in your browser and authorize the application:")
print(auth_url)
# After the user authorizes the application, they will be redirected to your redirect URI
# Parse the authorization code from the redirect URI
authorization_code = input("Enter the authorization code from the redirect URI (or leave empty if denied): ")
parsed_url = urlparse(authorization_code)
query_params = parse_qs(parsed_url.query)
code = query_params["code"][0]
print(code)
if not code:
print("Authorization denied by user.")
# Handle the denial, such as displaying a message to the user or redirecting them to a different page
else:
# Parameters for the token request
token_params = {
"grant_type": "authorization_code",
"code": code,
"client_id": client_id,
"redirect_uri": redirect_uri,
"code_verifier": code_verifier
}
# Make a POST request to the token endpoint to exchange the authorization code for an access token
response = requests.post(token_endpoint, data=token_params, headers={"Authorization": "Basic " + base64.b64encode(f"{client_id}:{client_secret}".encode('utf-8')).decode('utf-8')})
print(response)
# Parse the access token from the response
access_token = response.json().get('access_token')
print(access_token)
This is the documentation: http://download.chatwork.com/ChatWork_API_Documentation.pdf
The type of client has to be set up as confidential, otherwise you won't get client_secret
.
I solved the issue. First, setting up the account as public, then change the response without encoding (The documentation was a bit misleading here). This is the full code working:
import requests
from urllib.parse import urlencode, urlparse, parse_qs
import hashlib
import base64
import secrets
# Your ChatWork OAuth 2.0 client ID and redirect URI
client_id = "your_client_id"
redirect_uri = "https://example.com/"
state = "343ab3341331218786ef"
# URL for the OAuth 2.0 authorization and token endpoints
auth_endpoint = "https://www.chatwork.com/packages/oauth2/login.php"
token_endpoint = "https://oauth.chatwork.com/token"
# Generate a code verifier
code_verifier = base64.urlsafe_b64encode(secrets.token_bytes(32)).rstrip(b'=').decode('utf-8')
# Calculate the code challenge
code_challenge = base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode('utf-8')).digest()).decode('utf-8').replace('=', '')
# Parameters for the authorization request
params = {
"response_type": "code",
"client_id": client_id,
"redirect_uri": redirect_uri,
"scope": "rooms.all:read_write",
"state": state, # Generate a random string for CSRF protection
"code_challenge": code_challenge,
"code_challenge_method": "S256"
}
# Construct the authorization URL
auth_url = auth_endpoint + "?" + urlencode(params)
# Print the authorization URL
print("Open this URL in your browser and authorize the application:")
print(auth_url)
# After the user authorizes the application, they will be redirected to your redirect URI
# Parse the authorization code from the redirect URI
authorization_code = input("Enter the authorization code from the redirect URI (or leave empty if denied): ")
parsed_url = urlparse(authorization_code)
query_params = parse_qs(parsed_url.query)
code = query_params["code"][0]
print(code)
if not code:
print("Authorization denied by user.")
# Handle the denial, such as displaying a message to the user or redirecting them to a different page
else:
# Parameters for the token request
token_params = {
"grant_type": "authorization_code",
"client_id": client_id,
"code": code,
"redirect_uri": redirect_uri,
"code_verifier": code_verifier
}
response = requests.post(token_endpoint, data=token_params)
print(response.json())
# Parse the access token from the response
access_token = response.json().get('access_token')
print(access_token)
```