Webhooks for Frappe

Merged into develop branch Web hooks or Reverse API by revant · Pull Request #4090 · frappe/frappe · GitHub

Webhooks are “user-defined HTTP callbacks”. You can create webhook which triggers on Doc Event of the selected DocType. When the doc_events occurs, the source site makes an HTTP request to the URI configured for the webhook. Users can configure them to cause events on one site to invoke behaviour on another.

Add a webhook

e.g. Quotation-on_update
Select the fields to be sent as post body and its key can be overridden.

Example response of request sent by frappe server

on Quotation - on_update to 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"
}

https://github.com/frappe/frappe/blob/develop/frappe/docs/user/en/guides/integration/webhooks.md

24 Likes

Next step …hub with data migration :grimacing:

5 Likes

Wow! Things just keep getting better and better… Thanks a lot for the great job :+1:t3:

Kind regards,

First thank you @revant_one for this awesome addition. Do you think I can utilize Webhooks in the following scenario:

  • Multiple Erpnext websites e.g Companies (here each company has its own Erpnext instance under subdomain)
  • One Erpnext website acts as unified customer portal
  • The Companies utilize Webhooks to send updates to the portal
  • costumers in portal can also make actions which triggers webhooks where the request URL is to the respective company

Do you think web hooks are suitable for such scenario?

I think it is suitable for such scenario. You can try it out.
Endpoints to receive the data sent by webhook have to be implemented on portal and on company servers.

You can also use it in combination with Custom apps for cloud users [extend ERPNext with microservices] to achieve single sign on

@revant_one thanks a lot. Yes I was planning to test the microsrvices , how do you think microservices would help me in that scenario?

Now i’m setting up WSO2 Identity Server and will test the single sign on with your integration of Open ID

Each of your frappe server is a separate service? Single Identity provider can provide userids to all your services. No need to create users on all services separately. Just Login via Frappe via the main Frappe IDP

I’ve not use this service.

In case of frappe, primary identity provider is one of your frappe server.
This server will host all your identities. OAuth 2 provider for Frappe Apps - #12 by revant_one

1 Like

I think I get what you mean, but correct me if I’m wrong.
Have all the Webhooks in a Microservice Custom App that will be installed on Companies servers
where this Microservice Custom App is granted tokens by OAuth 2.0 (here I assume all the companies share the same identity provider) , at the same time use Webhoks at the portal to inform the Microservice Custom App of any changes made by the customer

1 Like

Thanks @revant_one soon I’ll be in touch with MN Technique. You guys are doing amazing work

3 Likes

Access related clarification.

By using Login via Frappe it creates a new user on the microservice or logs in to user if it exists.
e.g. user@holdingcompany.com exists in IDP, you setup a new service on subcom.com and you can login via frappe on subcom.com with useid as user@holdingcompany.com and It will create a new user on subcom.com

If erpnext_connector is installed on microservice, as it logs in via frappe it also stores the token for consuming resources from holdingcompany.com later.

If erpnext_connector is not installed it will just login via the ID on IDP, no token will be stored and you cannot access resources from holdingcompany.com without the token.

2 Likes

Is this functionality working? I tried creating webhooks to post with little success!!

I tried webhook on after_insert of a Note. It is working.
I could make POST request to given url.

Okay. Let me dig a little deeper.

How can I call webhook on particular condition?

Is there any way to bulk create webhooks?

That cannot be done, you only have a choice of doc_events available for selection on webhook. Check if you can manage your code logic around firing doc_events.

No specific way to bulk create webhooks.
Webhook is just another doctype,

Try Data import?
bench console?

@mayankjain Yes.

And how about using doc id in the URL as a placeholder? Is that possible?

Didn’t get you.