简体   繁体   English

使用 Webhooks 将 Google 日历数据发送到 Python 服务器时出现问题

[英]Issue with sending Google Calendar data to Python server with Webhooks

I'm making an application that requires sending Google Calendar data to a Python server.我正在制作一个需要将 Google 日历数据发送到 Python 服务器的应用程序。 I would like to be notified if an event is added or modified.如果添加或修改事件,我希望收到通知。 I have created the webhook server as a flask app - below:我已将 webhook 服务器创建为 flask 应用程序 - 如下:

from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    if request.method == 'POST':
        print("Data received from Webhook is: ", request.json)
        return "Webhook received!"

app.run(host='0.0.0.0', port=8000)

I created an ngrok tunnel so I could get a HTTPS callback URL for the webhook.我创建了一个 ngrok 隧道,因此我可以获得 HTTPS 回调 URL 用于 webhook。 I have verified that the server seems to be fine as I can send data to it with Postman (with the HTTPS callback address)我已经验证服务器似乎没问题,因为我可以使用 Postman 向它发送数据(使用 HTTPS 回调地址)

However, I think I may be doing something wrong with the setup of the notification channel.但是,我认为我可能在设置通知渠道时做错了什么。 When I run the notification channel code, I get the following 400 bad request:当我运行通知通道代码时,我收到以下 400 错误请求:

127.0.0.1 - - [05/Jan/2023 20:52:11] "[31m[1mPOST /webhook HTTP/1.1[0m" 400

And it is making a connection, because every time I add or modify an event in the calendar, I get the same message in the server console:它正在建立连接,因为每次我在日历中添加或修改事件时,我都会在服务器控制台中收到相同的消息:

 * Serving Flask app 'WebHookServerV3' (lazy loading)
 * Environment: production
[31m   WARNING: This is a development server. Do not use it in a production deployment.[0m
[2m   Use a production WSGI server instead.[0m
 * Debug mode: off
 * Running on all addresses (0.0.0.0)
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://127.0.0.1:8000
 * Running on http://192.168.1.108:8000 (Press CTRL+C to quit)
Data received from Webhook is:  This is sample data sent from POSTMAN
127.0.0.1 - - [05/Jan/2023 20:45:05] "POST /webhook HTTP/1.1" 200 -
127.0.0.1 - - [05/Jan/2023 20:52:11] "[31m[1mPOST /webhook HTTP/1.1[0m" 400 -
127.0.0.1 - - [05/Jan/2023 20:52:33] "[31m[1mPOST /webhook HTTP/1.1[0m" 400 

So it has connected to my calendar, it responds in real time when events are added or modified, but it's not giving me the data in the format I want (like the event, new time etc).所以它已经连接到我的日历,当添加或修改事件时它会实时响应,但它不会以我想要的格式(如事件、新时间等)给我数据。 I am new to webhooks and setting up channels - so I am not sure if I am missing something obvious in how I am setting it up.我是 webhooks 和设置频道的新手 - 所以我不确定我在设置过程中是否遗漏了一些明显的东西。 It's been difficult to find examples of this online.很难在网上找到这方面的例子。 Here is a snippet of the code where I am setting up the notification channel:这是我设置通知渠道的代码片段:

webhook_id = "channel_6"
webhook_url = "https://99cb-210-185-111-210.au.ngrok.io/webhook"

# Set the start and end times for the events to be retrieved

now = datetime.utcnow()
start_time = now
end_time = start_time + timedelta(weeks=1)
timeMin = start_time.isoformat() + 'Z'  # 'Z' indicates UTC time
timeMax = end_time.isoformat() + 'Z'

# Set up a push notification channel
# Using a ngrok https address.
channel = {
    "id": webhook_id,
    "type": "web_hook",
    "address": webhook_url
}

# Watch for events on the calendar
result = service.events().watch(
    calendarId=calendar_id,
    body={
        "id": webhook_id,       
        "type": "web_hook",
        "address": webhook_url,
        "params": {
            "ttl": "60"
        }
    },
    timeMin=timeMin,
    timeMax=timeMax
).execute()

# Print the channel ID and resource ID
print(f'Channel ID: {result["id"]}')
print(f'Resource ID: {result["resourceId"]}')

This is what I get when I run the client side code:这是我运行客户端代码时得到的:

Channel ID: channel_6
Resource ID: s9Ya16EtBwMmS49Bf9lbwwQecxQ

I should also note that I do have oauth credentials from Google that I included that do work since I was able to make API calls to get and list the events on my calendar.我还应该注意,我确实有来自 Google 的 oauth 凭据,我包含了这些凭据,这些凭据确实有效,因为我能够拨打 API 电话来获取和列出我日历上的事件。

# Google Credentials
scopes = ['https://www.googleapis.com/auth/calendar']
flow = InstalledAppFlow.from_client_secrets_file("client_secret.json", scopes=scopes)
#We initially had these which sent a URL to open in browswer, which gave a token to enter. But now, we saved that token in a pickle file (pickledump). So now just have to read it from pickleload instead of authenticating every time.
#credentials = flow.run_console()
#pickle.dump(credentials, open("token.pkl", "wb"))
credentials = pickle.load(open("token.pkl", "rb"))
service = build("calendar", "v3", credentials=credentials)

calendar_id = 'googlecalendaremail@email.com'

Maybe there is something more I need to do on the client side specifying which data to send from the calendar when the push is made?也许我需要在客户端做更多的事情来指定在进行推送时从日历发送哪些数据? I do build the service using my credentials and then watch the service.events in the request body so not sure what else is required.我确实使用我的凭据构建服务,然后在请求正文中查看 service.events,因此不确定还需要什么。 Would love if someone could point me in the right direction.如果有人能指出我正确的方向,我会很高兴。 Thank you.谢谢你。

I believe I have fixed the issue.我相信我已经解决了这个问题。 In my server code, I had "request.json" in my print statement.在我的服务器代码中,我的打印语句中有“request.json”。 Which was wrong, it should have just been "request".哪里错了,应该只是“请求”。

Even then, the request channel didn't give me much information after printing it out, just the https URL and the method (in this case, POST).即使这样,请求通道在打印出来后也没有给我太多信息,只有 https URL 和方法(在本例中为 POST)。 Which seems to be confirmed by this post: Google Calendar event Created/Updated/Deleted Webhook?这篇文章似乎证实了这一点: Google Calendar event Created/Updated/Deleted Webhook?

So I am now just going to use this as a trigger to call the API to get an updated list of events.所以我现在打算使用它作为触发器来调用 API 以获取更新的事件列表。 Using this method, I don't have to constantly poll using the API (which would rack up costs), but can just poll it when the webhook tells me something has changed.使用这种方法,我不必经常使用 API 进行轮询(这会增加成本),而是可以在 webhook 告诉我发生了某些变化时进行轮询。

from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    if request.method == 'POST':
        print("Data received from Webhook is: ", request)
        return "Webhook received!"

app.run(host='0.0.0.0', port=8000)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 向服务器 pyzmq 发送数据时出现问题 - Issue in sending data to the server pyzmq Python Google Calendar API内存问题 - Python Google Calendar API memory issue Google Calendar API(Python)send_event_notifications不发送电子邮件 - Google Calendar API (Python) send_event_notifications not sending emails 使用gdata python库发送Google日历活动邀请通知 - Sending Google calendar event invite notifications using gdata python library 连接到服务器并在python中向其发送数据 - connecting to server and sending data to it in python 通过Python和Google SMTP服务器发送电子邮件 - Sending email via Python and Google SMTP server 从 AJAX 向 python flask 发送数据的问题 - Issue with sending data to python flask from AJAX 接收Jira Webhooks数据的Python脚本 - Python script that receives Jira Webhooks data 使用iCalUID导入日历后,在“ events.update()”函数上使用Google Calendar API向“参与者”发送通知时出现问题? - Issue in sending notifications using Google Calendar API on “events.update()” function to the “attendees”, after “import” of a calendar using iCalUID? 使用python将数据发送到SQL Server - Sending data by using python to sql server
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM