我的代码:
import os
import json
import dotenv
import requests
import requests_oauthlib
class Calendar():
def __init__(self):
dotenv.load_dotenv()
self.api_key = os.getenv("API_KEY")
self.calendar_id = os.getenv("CALENDAR_ID")
self.access_token = os.getenv("GOOGLE_CALENDAR_API_ACCESS_TOKEN")
def auth(self, scopes):
with open("./assets/credentials.json", "r") as json_file:
credentials = json.load(json_file)
client_id = credentials["web"]["client_id"]
client_secret = credentials["web"]["client_secret"]
redirect_uri = credentials["web"]["redirect_uris"][0]
authorization_url = credentials["web"]["auth_uri"]
token_url = credentials["web"]["token_uri"]
scopes = scopes
with requests_oauthlib.OAuth2Session(client_id=client_id, scope=scopes, redirect_uri=redirect_uri) as session:
authorization_url, state = session.authorization_url(authorization_url, access_type="offline", prompt="select_account")
print("click the link to auth", authorization_url)
redirect_response = input("Paste the redirect URL here:")
credentials = session.fetch_token(token_url=token_url, client_secret=client_secret, authorization_response=redirect_response)
dotenv.set_key(".env", key_to_set="GOOGLE_CALENDAR_API_ACCESS_TOKEN", value_to_set=credentials["access_token"], quote_mode="never")
self.access_token = credentials["access_token"]
def add_event(self, summary, start_date, end_date, description="", recurrence=False):
url = f"https://www.googleapis.com/calendar/v3/calendars/{self.calendar_id}/events"
headers = {
"Authorization": f"Bearer {self.access_token}",
"Accept": "application/json",
"Content-Type": "application/json"
}
payload = {
"end": {
"dateTime": end_date,
"timeZone": "Asia/Taipei"
},
"start": {
"dateTime": start_date,
"timeZone": "Asia/Taipei"
}
}
if recurrence:
payload["recurrence"] = ["RRULE:FREQ=WEEKLY"]
response = requests.post(url=url, data=payload, headers=headers)
return response.text
if __name__ == "__main__":
c = Calendar()
c.auth(["https://www.googleapis.com/auth/calendar", "https://www.googleapis.com/auth/calendar.events"])
print(c.add_event(summary="test", start_date="2024-09-05T01:00:00.000", end_date="2024-09-17T13:00:00.000"))
输出:
{
"error": {
"errors": [
{
"domain": "global",
"reason": "badRequest",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}
我已经在 Google 的 API Explorer 上尝试了该 API,它成功地将事件添加到日历中。然而,当我在 python 中做同样的事情时,它出错了。
一开始,我以为是因为“datetime”格式,但我尝试了很多不同的格式,它们都返回相同的“400 bad request”。
我认为在Calendar API的“Events: insert”的情况下,请求正文需要是从JSON转换而来的字符串。那么,下面的修改怎么样?
response = requests.post(url=url, data=payload, headers=headers)
response = requests.post(url=url, json=payload, headers=headers)
或
response = requests.post(url=url, data=json.dumps(payload), headers=headers)
Bad Request
的错误。