Django Webhook 接收 Mailgun 的 post 请求

Posted

技术标签:

【中文标题】Django Webhook 接收 Mailgun 的 post 请求【英文标题】:Django Webhook receive post request for Mailgun 【发布时间】:2020-12-25 18:36:51 【问题描述】:

我在 Django 中设置了一个 webhook 来接收来自 Mailgun 的更新。

mailgun POST 有效负载以以下格式传送到 webhook:


  “signature”:
  
    "timestamp": "1529006854",
    "token": "a8ce0edb2dd8301dee6c2405235584e45aa91d1e9f979f3de0",
    "signature": "d2271d12299f6592d9d44cd9d250f0704e4674c30d79d07c47a66f95ce71cf55"
  
  “event-data”:
  
    "event": "opened",
    "timestamp": 1529006854.329574,
    "id": "DACSsAdVSeGpLid7TN03WA",
    // ...
  

如果我尝试使用下面的代码检索 event 参数,我会收到一条错误消息 TypeError: 'method' object is not subscriptable

@csrf_exempt
@require_POST
def mailgun(request):
    event_data = request.POST.get['event-data']['event']
    return HttpResponse(event_data, status=200)

感谢任何帮助。

【问题讨论】:

【参考方案1】:

尝试更新.get调用函数并添加一些输入检查,即:

if request.POST.get('event-data'):
    event_data = request.POST.get('event-data')['event']
    return HttpResponse(event_data, status=200)
else:
    return HttpResponse("[unknown event]", status=400)

或者如果您确定 event-data 永远不会为空或 null 直接调用:

request.POST['event-data']['event']

【讨论】:

如果我运行第一个命令,我得到:TypeError: 'NoneType' object is not subscriptable @Rutnet 您是否有可能收到空的event-data @Rutnet 用扩展示例更新了我的答案(如果传入的数据不是您所期望的,则响应 400 状态代码) 我认为事件数据没有正确返回。这是event_data的结构documentation.mailgun.com/en/latest/user_manual.html#webhooks 好的,你能展示一下 (print(dict(request.POST))) 你从 mailgun 收到的内容吗?【参考方案2】:

经过大量故障排除后,答案隐藏在下面的 *** 链接中。在 Python 3.0 到 Python 3.5.x 中,json.loads() 将只接受一个 unicode 字符串,因此您必须在将 request.body(它是一个字节字符串)传递给 json.loads() 之前对其进行解码。

Trying to parse `request.body` from POST in Django

body_unicode = request.body.decode('utf-8')
body = json.loads(body_unicode)
content = body['event-data']
recipient = content['recipient']

【讨论】:

以上是关于Django Webhook 接收 Mailgun 的 post 请求的主要内容,如果未能解决你的问题,请参考以下文章

Django实现自动发布(2视图-任务接收)

Paypal webhook 接收器 asp

邮件服务器拒绝 MailGun 发送的邮件(发往它控制的域)

为啥 Stripe 事件不会触发并且不会被 webhook 接收?

如何通过传出 webhook 接收交互?

接收不到shopify webhook 发送post请求