使用 Google Apps 脚本创建 Strava Webhook 订阅时出现问题

Posted

技术标签:

【中文标题】使用 Google Apps 脚本创建 Strava Webhook 订阅时出现问题【英文标题】:Problem creating a Strava webhook subscription using Google Apps Script 【发布时间】:2020-09-12 00:18:26 【问题描述】:

编辑 2 - 我现在已经对这个问题提供了自己的答案 - 任何进一步的想法或意见仍将不胜感激

编辑 1 - 潜在相关信息:

我在Content Service 文档页面的底部找到了这个脚注,上面写着:

出于安全原因,内容服务返回的内容不是从script.google.com 提供的,而是重定向到script.googleusercontent.com 的一次性URL。这意味着,如果您使用内容服务将数据返回到另一个应用程序,则必须确保将 HTTP 客户端配置为遵循重定向。例如,在 cURL 命令行实用程序中,添加标志 -L。有关如何启用此行为的更多信息,请查看您的 HTTP 客户端的文档。

这似乎是相关的,因为我使用 ContentService 为 Strava 的 GET 请求提供数据 - 这是否意味着它收到的响应来自不同的 URL,因此不是来自指定的回调 URL?


我一直在尝试使用 Google Apps 脚本创建一个对 Strava 的 webhook 订阅,我觉得我非常接近解决它,但我遇到了最后一个我似乎无法通过的障碍.

here 中列出了用于创建 Strava 的 webhook 订阅的文档,我已经到了向 Strava API 发出 POST 请求订阅的阶段。然后,Strava 向我指定的 callback_url 发送一个 HTTP GET 请求,其中包含一些参数 - 其中最重要的是 hub.challenge 参数。这个参数必须在 2 秒内通过我的回调地址发回,以便验证链接。这就是我感到悲伤的地方。

function doGet(e) 

  var hubChal = e.parameter["hub.challenge"];

  var result = 
    "hub.challenge": hubChal
  ;

  return ContentService.createTextOutput(JSON.stringify(result))
    .setMimeType(ContentService.MimeType.JSON);


以上是我当前处理传入 GET 请求的函数。

在文档中指出:

您的回调地址必须在两秒内响应来自 Strava 订阅服务的 GET 请求。响应应指示状态代码 200,并应将响应正文中的 hub.challenge 字段回显为 application/json 内容类型: “hub.challenge”:”15f7d1a91c1f40f8a748fd134752feb3”

但是,当我将 POST 发送到 webhook 订阅 API 时,我会在 Postman 上收到此响应:


    "message": "Bad Request",
    "errors": [
        
            "resource": "PushSubscription",
            "field": "callback url",
            "code": "GET to callback URL does not return 200"
        
    ]

我检查了文档页面上提供的故障排除建议,其中的一个元素提供了一个示例 GET 请求,供您发送给自己,以查看您的回调地址提供的回报:

检查对上述请求的响应是否显示200 状态并正确回显JSON 正文中的hub.challenge。上述示例 curl 请求的响应正文应类似于 “hub.challenge”:”15f7d1a91c1f40f8a748fd134752feb3”

使用以下虚拟 GET 请求:

your-callback-url?hub.verify_token=test&hub.challenge=15f7d1a91c1f40f8a748fd134752feb3&hub.mode=subscribe

插入我的回调 url 并通过 Postman 发送 GET 请求会向我返回以下内容:


    "hub.challenge": "15f7d1a91c1f40f8a748fd134752feb3"

同时显示 200 OK 状态代码并且在 2 秒内。

我真的看不出我在这里做错了什么,因为我似乎满足了设置订阅的标准。值得一提的是,我对 Google Apps 脚本不是很熟悉,所以我完全有可能甚至很可能遗漏了一些基本的东西,但我一辈子都看不到它。

我已经阅读了所有的故障排除建议,尽管昨天搜索了整个下午和晚上,但仍然无法在网上找到答案。任何帮助将不胜感激 - 谢谢。

【问题讨论】:

【参考方案1】:

我不熟悉 Goole Apps 脚本(顺便说一句,非常酷!),但听起来你对 Strava 网络钩子很了解。

听起来您的 doGet 方法返回的不是 200。您是否有一个日志功能,可以输出 doGet 方法正在发送的内容、返回的内容等?

如果您还没有,您可能需要查看Strava tutorial on subscribing to webhooks using Node, Express and Ngrok。一些额外的步骤,但相当容易遵循和调试。

【讨论】:

嗨,Seth,感谢您的回复 - 根据错误,它听起来确实像返回 200 以外的东西,但是,当我从 Postman 发送一个模仿 Strava GET 请求的虚拟 GET 请求时,我收到了 200 回,没有任何问题。至于日志记录,脚本实际上是附加到 Google 表格中的,所以我经常将信息以日志的形式粘贴到其中 - 我会看看粘贴我返回的数据是否能阐明我正在发送的数据似乎完全正常。 您如何通过 Postman 发送 hub.challenge 信息? Strava 文档说它应该作为 HTTP 表单数据发送(而不是 URL 中的查询字符串参数)。它适用于 curl 请求吗? $ curl -X POST https://www.strava.com/api/v3/push_subscriptions \ -F client_id=YOUR_CLIENT_ID_HERE \ -F client_secret=YOUR_SECRET_HERE \ -F 'callback_url=http://a-valid.com/url' \ -F 'verify_token=STRAVA' 因此 hub.challenge 信息是从 Strava 发送给我的 GET 请求中获取的,然后使用 e.parameter["hub.challenge"] 进行复制。然后将其解析为正确的形式并发送回 Strava。我没有尝试过 curl 请求,因为我无法让它工作,但我会弄清楚并发送一个 - 感谢您的建议。 我想通了,似乎收到了完全相同的消息:"message":"Bad Request","errors":["resource":"PushSubscription","field ":"callback url","code":"GET to callback URL does not return 200"] 从我的控制台复制并粘贴。我想至少排除了这一点 - 虽然非常令人沮丧! 我设法设置并让 ngrok 工作;经过一番修修补补,我成功地创建了一个 webhook 订阅。我向我的 ngrok 服务器发送了相同的虚拟 GET 请求以查看我返回的内容,并且返回的 JSON 是相同的 - 但是返回数据的标头非常不同。明天我稍微不那么累的时候上传一些截图。开始认为这可能是 Google Apps Script 的限制!【参考方案2】:

我相信我终于找到了我的问题,但不幸的是,似乎无法使用 Google Apps 脚本为 Strava 设置 webhook 订阅 - 至少在使用 ContentService 向 Strava GET 请求提供数据时是不可能的。

在 ContentService 文档的末尾写道:

出于安全原因,内容服务返回的内容不是从script.google.com 提供的,而是重定向到script.googleusercontent.com 的一次性URL。这意味着如果您使用内容服务将数据返回到另一个应用程序,您必须确保将 HTTP 客户端配置为遵循重定向。例如,在 cURL 命令行实用程序中,添加标志 -L。有关如何启用此行为的更多信息,请查看您的 HTTP 客户端的文档。

问题在于 Strava 期望并且只会接受附加到其 GET 请求响应的 200 状态代码,但是 ContentService 会向这个一次性 URL 发送 302 重定向。我可以通过在我的虚拟 GET 请求的请求设置中关闭“自动遵循重定向”来在 Postman 中验证这一点:

https://i.stack.imgur.com/vAvIm.png

由于我在 Postman 上默认启用了自动重定向,因此在发送我自己的请求时,我在任何时候都没有看到 302,导致一切看起来都井然有序。

如果有解决此 ContentService 问题的方法,那么请通知我,因为这样做的结果是我现在必须轮询 Strava 以获取新数据(嘘),这将让我的成品更加笨重。

希望这篇文章现在能够帮助任何其他人在未来发现自己遇到我的问题,并为他们节省几天的困惑!

【讨论】:

以上是关于使用 Google Apps 脚本创建 Strava Webhook 订阅时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Google Apps 脚本创建/更改具有给定 Meet URL 的 Google 日历活动?

使用 Google Apps 脚本创建 Etag 字符串

使用 Google Apps 脚本创建 Strava Webhook 订阅时出现问题

使用 Google Apps 脚本在 Google 表格中创建新表格

在 Google Apps 脚本中使用高级 Gmail 服务创建与表情符号兼容的 Gmail 草稿

从移动应用程序执行 Google Apps 脚本功能