Webhooks

Webhook 是“用户自定义的 HTTP 回调”。对于选定的文档类型,您可以根据需要创建一个 Webhook,使其在特定条件下触发特定文档事件。

当 doc_event 发生时,源站点会向 Webhook 配置的 URI 发起 HTTP 请求。用户可以配置这些 Webhook,利用一个站点上的事件来触发另一个站点上的行为。

配置 Webhook

要添加 Webhook,请前往:

集成 > Webhook > Webhook

  1. 选择需要触发 Webhook 的文档类型(例如:Quotation)。
  2. 选择将触发 Webhook 的文档事件(例如:on_update)。
  3. (可选)您可以设置额外的文档条件,以便在特定场景下触发 Webhook。
  4. 输入一个有效的请求 URL,该 URL 将接收 Webhook 数据。
  5. 选择请求方法。默认方法为 POST。
  6. (可选)您可以向请求中添加 HTTP 头。(例如:如果需要发送 API 密钥,这会很有用)。

您也可以通过取消勾选 Enabled 复选框来禁用 Webhook。只有启用的 Webhook 才会被触发。

数据结构

  • 如果您的请求结构基于表单,您可以在表格中选择文档中的字段,该表格使用字段名作为 key。
  • 如果您的请求结构基于 JSON,您可以使用 Jinja 模板从文档中插入字段(请确保将字段用双引号括起来)。

Webhook 安全

为了可选地为您的 Webhook 请求增加安全性,并确保 Webhook 确实来自 Frappe,您可以随请求设置一个“Webhook 密钥”。请勿公开分享该密钥。

如果启用,在请求发送前会添加一个额外的请求头(X-Frappe-Webhook-Signature),其值由密钥根据请求负载生成,格式为 base64 编码的 HMAC-SHA256 哈希值。

Webhook 请求示例

  • 文档类型:Quotation
  • 文档事件:on_update
  • 请求 URL:https://httpbin.org/post
  • 请求结构:Form URL-Encoded
  • Webhook 请求头:
  1. 键:Content-Type:,值:application/x-www-form-urlencoded
  • Webhook 数据:
  1. 字段名:name,键:id
  2. 字段名:items,键:lineItems

上述配置将生成以下 JSON 请求(由 Frappe 服务器在 Quotation – on_update 时发送至 https://httpbin.org/post):

{
 "args": {},
 "data": "{"lineItems": [{"stock_qty": 1.0, "base_price_list_rate": 1.0, "image": "", "creation": "2017-09-14 13:41:58.373023", "base_amount": 1.0, "qty": 1.0, "margin_rate_or_amount": 0.0, "rate": 1.0, "owner": "Administrator", "stock_uom": "Unit", "base_net_amount": 1.0, "page_break": 0, "modified_by": "Administrator", "base_net_rate": 1.0, "discount_percentage": 0.0, "item_name": "I1", "amount": 1.0, "actual_qty": 0.0, "net_rate": 1.0, "conversion_factor": 1.0, "warehouse": "Finished Goods - R", "docstatus": 0, "prevdoc_docname": null, "uom": "Unit", "description": "I1", "parent": "QTN-00001", "brand": null, "gst_hsn_code": null, "base_rate": 1.0, "item_code": "I1", "projected_qty": 0.0, "margin_type": "", "doctype": "Quotation Item", "rate_with_margin": 0.0, "pricing_rule": null, "price_list_rate": 1.0, "name": "QUOD/00001", "idx": 1, "item_tax_rate": "{}", "item_group": "Products", "modified": "2017-09-14 17:09:51.239271", "parenttype": "Quotation", "customer_item_code": null, "net_amount": 1.0, "prevdoc_doctype": null, "parentfield": "items"}], "id": "QTN-00001"}",
 "files": {},
 "form": {},
 "headers": {
 "Accept": "*/*",
 "Accept-Encoding": "gzip, deflate",
 "Connection": "close",
 "Content-Length": "1075",
 "Host": "httpbin.org",
 "User-Agent": "python-requests/2.18.1"
 },
 "json": {
 "id": "QTN-00001",
 "lineItems": [
 {
 "actual_qty": 0.0,
 "amount": 1.0,
 "base_amount": 1.0,
 "base_net_amount": 1.0,
 "base_net_rate": 1.0,
 "base_price_list_rate": 1.0,
 "base_rate": 1.0,
 "brand": null,
 "conversion_factor": 1.0,
 "creation": "2017-09-14 13:41:58.373023",
 "customer_item_code": null,
 "description": "I1",
 "discount_percentage": 0.0,
 "docstatus": 0,
 "doctype": "Quotation Item",
 "gst_hsn_code": null,
 "idx": 1,
 "image": "",
 "item_code": "I1",
 "item_group": "Products",
 "item_name": "I1",
 "item_tax_rate": "{}",
 "margin_rate_or_amount": 0.0,
 "margin_type": "",
 "modified": "2017-09-14 17:09:51.239271",
 "modified_by": "Administrator",
 "name": "QUOD/00001",
 "net_amount": 1.0,
 "net_rate": 1.0,
 "owner": "Administrator",
 "page_break": 0,
 "parent": "QTN-00001",
 "parentfield": "items",
 "parenttype": "Quotation",
 "prevdoc_docname": null,
 "prevdoc_doctype": null,
 "price_list_rate": 1.0,
 "pricing_rule": null,
 "projected_qty": 0.0,
 "qty": 1.0,
 "rate": 1.0,
 "rate_with_margin": 0.0,
 "stock_qty": 1.0,
 "stock_uom": "Unit",
 "uom": "Unit",
 "warehouse": "Finished Goods - R"
 }
 ]
 },
 "url": "https://httpbin.org/post"
}

示例 JSON 请求体

对于销售交易上的 Webhook,我们可以按如下方式构造 JSON 数据:

{
 "id": "{{ doc.name }}",
 "total": "{{ doc.total }} EUR",
 "total_net_weight": "{{ doc.total_net_weight }} kg",
 "customer": "{{ doc.customer }}",
 "created": "{{ doc.creation }}",
 "items": {{ doc["items"] | tojson }}
}

Webhook 请求日志

每次成功请求都会创建一条 Webhook 请求日志,其中包含所有相关详细信息。