text: (window.webpackJsonp=window.webpackJsonp||[]).push([[18],{167:function(t,s,n){"use strict";n.r(s);var a=n(0),e=Object(a.a)({},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("div",{staticClass:"content"},[t._m(0),t._v(" "),n("p",[t._v("A webhook server for LINE messaging API is just a plain HTTP(S) server. When\nthere is a observable user event, an HTTP request will be sent to a\npre-configured webhook server.")]),t._v(" "),n("p",[t._v("About configuration of webhook itself, please refer to "),n("a",{attrs:{href:"https://developers.line.me/en/docs/messaging-api/reference/#webhooks",target:"_blank",rel:"noopener noreferrer"}},[t._v("Webhook"),n("OutboundLink")],1),t._v("\nof the official document.")]),t._v(" "),t._m(1),t._v(" "),n("ul",[n("li",[n("a",{attrs:{href:"https://developers.line.me/en/docs/messaging-api/reference/#signature-validation",target:"_blank",rel:"noopener noreferrer"}},[t._v("Signature validation"),n("OutboundLink")],1)]),t._v(" "),n("li",[n("a",{attrs:{href:"https://developers.line.me/en/docs/messaging-api/reference/#webhook-event-objects",target:"_blank",rel:"noopener noreferrer"}},[t._v("Webhook event object parsing"),n("OutboundLink")],1)])]),t._v(" "),n("p",[n("strong",[t._v("Signature validation")]),t._v(" is checking if a request is actually sent from real\nLINE servers, not a fraud. The validation is conducted by checking\nthe "),n("a",{attrs:{href:"https://developers.line.me/en/docs/messaging-api/reference/#signature-validation",target:"_blank",rel:"noopener noreferrer"}},[t._v("X-Line-Signature"),n("OutboundLink")],1),t._v(" header\nand request body. There is a "),n("router-link",{attrs:{to:"./../api-reference/validate-signature.html"}},[n("code",[t._v("validateSignature()")])]),t._v("\nfunction to do this.")],1),t._v(" "),n("p",[n("strong",[t._v("Webhook event object parsing")]),t._v(" is literally parsing webhook event objects,\nwhich contains information of each webhook event. The objects are provided as\nrequest body in JSON format, so any body parser will work here. For interal\nobject types in this SDK, please refer to "),n("router-link",{attrs:{to:"./../api-reference/message-and-event-objects.html"}},[t._v("Message and event objects")]),t._v(".")],1),t._v(" "),n("p",[t._v("There is a function to generate a "),n("a",{attrs:{href:"https://github.com/senchalabs/connect",target:"_blank",rel:"noopener noreferrer"}},[t._v("connect"),n("OutboundLink")],1),t._v(" middleware,\n"),n("router-link",{attrs:{to:"./../api-reference/middleware.html"}},[n("code",[t._v("middleware()")])]),t._v(", to conduct both of them. If\nyour server can make use of connect middlewares, such as "),n("a",{attrs:{href:"https://expressjs.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Express"),n("OutboundLink")],1),t._v(",\nusing the middleware is a recommended way to build a webhook server.")],1),t._v(" "),t._m(2),t._v(" "),n("p",[n("a",{attrs:{href:"https://expressjs.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Express"),n("OutboundLink")],1),t._v(" is a minimal web framework for Node.js, which\nis widely used in Node.js communities. You can surely build a webhook server\nwith any web framework, but we use Express as an example here for its\npopularity.")]),t._v(" "),n("p",[t._v("We skip the detailed guide for Express.  If more information is needed about\nExpress, please refer to its documentation.")]),t._v(" "),n("p",[t._v("Here is an example of an HTTP server built with Express.")]),t._v(" "),t._m(3),t._m(4),t._v(" "),t._m(5),t._m(6),t._v(" "),t._m(7),t._v(" "),t._m(8),n("p",[t._v("The middleware will throw an exception when the "),n("a",{attrs:{href:"https://developers.line.me/en/docs/messaging-api/reference/#signature-validation",target:"_blank",rel:"noopener noreferrer"}},[t._v("X-Line-Signature"),n("OutboundLink")],1),t._v("\nheader is not set. If you want to handle usual user requests, the middleware\nshouldn't be used for them.")]),t._v(" "),t._m(9),t._v(" "),t._m(10),n("p",[t._v("If another body parser already parsed a request's body, the webhook middleware\ncannot access to the raw body of the request. The raw body should be retrieved\nfor signature validation.")]),t._v(" "),n("p",[t._v("However, there are environments where "),n("code",[t._v("req.body")]),t._v(" is pre-parsed, such as\n"),n("a",{attrs:{href:"https://firebase.google.com/docs/functions/http-events",target:"_blank",rel:"noopener noreferrer"}},[t._v("Firebase Cloud Functions"),n("OutboundLink")],1),t._v(".\nIf it parses the body into string or buffer, the middleware will use the body\nas it is and work just fine. If the pre-parsed body is an object, the webhook\nmiddleware will fail to work. In the case, please use "),n("router-link",{attrs:{to:"./../api-reference/validate-signature.html"}},[n("code",[t._v("validateSignature()")])]),t._v("\nmanually with raw body.")],1),t._v(" "),t._m(11),t._v(" "),t._m(12),t._v(" "),t._m(13),t._v(" "),n("p",[t._v("For type references of the errors, please refer to "),n("router-link",{attrs:{to:"./../api-reference/exceptions.html"}},[t._v("the API reference")]),t._v(".")],1),t._v(" "),n("p",[t._v("The errors can be handled with "),n("a",{attrs:{href:"https://github.com/senchalabs/connect#error-middleware",target:"_blank",rel:"noopener noreferrer"}},[t._v("error middleware"),n("OutboundLink")],1),t._v(".")]),t._v(" "),t._m(14),t._m(15),t._v(" "),n("p",[t._v("The webhook URL should have HTTPS protocol. There are several ways to build an\nHTTPS server. For example, here is a "),n("a",{attrs:{href:"https://expressjs.com/en/api.html#app.listen",target:"_blank",rel:"noopener noreferrer"}},[t._v("documentation"),n("OutboundLink")],1),t._v("\nof making Express work with HTTPS. You can also set HTTPS in web servers like\n"),n("a",{attrs:{href:"https://www.nginx.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("NGINX"),n("OutboundLink")],1),t._v(". This guide will not cover HTTPS configuration,\nbut do not forget to set HTTPS beforehand.")]),t._v(" "),n("p",[t._v("For development and test usages, "),n("a",{attrs:{href:"https://ngrok.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngrok"),n("OutboundLink")],1),t._v(" works perfectly.")])])},[function(){var t=this.$createElement,s=this._self._c||t;return s("h1",{attrs:{id:"webhook"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#webhook","aria-hidden":"true"}},[this._v("#")]),this._v(" Webhook")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"what-a-webhook-server-should-do"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#what-a-webhook-server-should-do","aria-hidden":"true"}},[this._v("#")]),this._v(" What a webhook server should do")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"build-a-webhook-server-with-express"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#build-a-webhook-server-with-express","aria-hidden":"true"}},[this._v("#")]),this._v(" Build a webhook server with Express")])},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("div",{staticClass:"language-js extra-class"},[n("pre",{pre:!0,attrs:{class:"language-js"}},[n("code",[n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" express "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'express'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" app "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("express")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("post")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'/webhook'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("req"),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  res"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("json")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("listen")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token number"}},[t._v("8080")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("p",[this._v("The server above listens to 8080 and will response with an empty object for\n"),s("code",[this._v("POST /webhook")]),this._v(". We will add webhook functionality to this server.")])},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("div",{staticClass:"language-js extra-class"},[n("pre",{pre:!0,attrs:{class:"language-js"}},[n("code",[n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" express "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'express'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" middleware "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'@line/bot-sdk'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("middleware\n\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" app "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("express")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" config "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  channelAccessToken"),n("span",{attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),n("span",{attrs:{class:"token string"}},[t._v("'YOUR_CHANNEL_ACCESS_TOKEN'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n  channelSecret"),n("span",{attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),n("span",{attrs:{class:"token string"}},[t._v("'YOUR_CHANNEL_SECRET'")]),t._v("\n"),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("post")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'/webhook'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("middleware")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("req"),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  req"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("events "),n("span",{attrs:{class:"token comment"}},[t._v("// webhook event objects")]),t._v("\n  req"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("destination "),n("span",{attrs:{class:"token comment"}},[t._v("// user ID of the bot (optional)")]),t._v("\n  "),n("span",{attrs:{class:"token operator"}},[t._v("...")]),t._v("\n"),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("listen")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token number"}},[t._v("8080")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("p",[this._v("We have imported "),s("code",[this._v("middleware")]),this._v(" from the package and make the Express app to use\nthe middleware. The middlware validates the request and parses webhook event\nobject. It embeds body-parser and parses them to objects. If you have a reason\nto use another body-parser separately for other routes, please keep in mind the\nfollowings.")])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"do-not-use-the-webhook-middleware-for-other-usual-routes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#do-not-use-the-webhook-middleware-for-other-usual-routes","aria-hidden":"true"}},[this._v("#")]),this._v(" Do not use the webhook "),s("code",[this._v("middleware()")]),this._v(" for other usual routes")])},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("div",{staticClass:"language-js extra-class"},[n("pre",{pre:!0,attrs:{class:"language-js"}},[n("code",[n("span",{attrs:{class:"token comment"}},[t._v("// don't")]),t._v("\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token function"}},[t._v("middleware")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),n("span",{attrs:{class:"token comment"}},[t._v("// do")]),t._v("\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'/webhook'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("middleware")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h3",{attrs:{id:"do-not-use-another-body-parser-before-the-webhook-middleware"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#do-not-use-another-body-parser-before-the-webhook-middleware","aria-hidden":"true"}},[this._v("#")]),this._v(" Do not use another body-parser before the webhook "),s("code",[this._v("middleware()")])])},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("div",{staticClass:"language-js extra-class"},[n("pre",{pre:!0,attrs:{class:"language-js"}},[n("code",[n("span",{attrs:{class:"token comment"}},[t._v("// don't")]),t._v("\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bodyParser"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("json")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'/webhook'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("middleware")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),n("span",{attrs:{class:"token comment"}},[t._v("// do")]),t._v("\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'/webhook'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("middleware")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("bodyParser"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("json")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"error-handling"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#error-handling","aria-hidden":"true"}},[this._v("#")]),this._v(" Error handling")])},function(){var t=this.$createElement,s=this._self._c||t;return s("p",[this._v("There are two types of errors thrown by the middleware, one is "),s("code",[this._v("SignatureValidationFailed")]),this._v("\nand the other is "),s("code",[this._v("JSONParseError")]),this._v(".")])},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("ul",[n("li",[n("code",[t._v("SignatureValidationFailed")]),t._v(" is thrown when a request doesn't have a signature.")]),t._v(" "),n("li",[n("code",[t._v("SignatureValidationFailed")]),t._v(" is thrown when a request has a wrong signature.")]),t._v(" "),n("li",[n("code",[t._v("JSONParseError")]),t._v(" occurs when a request body cannot be parsed as JSON.")])])},function(){var t=this,s=t.$createElement,n=t._self._c||s;return n("div",{staticClass:"language-js extra-class"},[n("pre",{pre:!0,attrs:{class:"language-js"}},[n("code",[n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" express "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'express'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" middleware "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'@line/bot-sdk'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("middleware\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" JSONParseError "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'@line/bot-sdk'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("JSONParseError\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" SignatureValidationFailed "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("require")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'@line/bot-sdk'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("SignatureValidationFailed\n\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" app "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token function"}},[t._v("express")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),n("span",{attrs:{class:"token keyword"}},[t._v("const")]),t._v(" config "),n("span",{attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  channelAccessToken"),n("span",{attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),n("span",{attrs:{class:"token string"}},[t._v("'YOUR_CHANNEL_ACCESS_TOKEN'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n  channelSecret"),n("span",{attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),n("span",{attrs:{class:"token string"}},[t._v("'YOUR_CHANNEL_SECRET'")]),t._v("\n"),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token function"}},[t._v("middleware")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("post")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token string"}},[t._v("'/webhook'")]),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("req"),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  res"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("json")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("req"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("events"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token comment"}},[t._v("// req.body will be webhook event object")]),t._v("\n"),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("use")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" req"),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res"),n("span",{attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" next"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n  "),n("span",{attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err "),n("span",{attrs:{class:"token keyword"}},[t._v("instanceof")]),t._v(" "),n("span",{attrs:{class:"token class-name"}},[t._v("SignatureValidationFailed")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    res"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("status")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token number"}},[t._v("401")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("send")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signature"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),n("span",{attrs:{class:"token keyword"}},[t._v("return")]),t._v("\n  "),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),n("span",{attrs:{class:"token keyword"}},[t._v("else")]),t._v(" "),n("span",{attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err "),n("span",{attrs:{class:"token keyword"}},[t._v("instanceof")]),t._v(" "),n("span",{attrs:{class:"token class-name"}},[t._v("JSONParseError")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n    res"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("status")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token number"}},[t._v("400")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("send")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),t._v("raw"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n    "),n("span",{attrs:{class:"token keyword"}},[t._v("return")]),t._v("\n  "),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n  "),n("span",{attrs:{class:"token function"}},[t._v("next")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),t._v("err"),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),n("span",{attrs:{class:"token comment"}},[t._v("// will throw default 500")]),t._v("\n"),n("span",{attrs:{class:"token punctuation"}},[t._v("}")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\napp"),n("span",{attrs:{class:"token punctuation"}},[t._v(".")]),n("span",{attrs:{class:"token function"}},[t._v("listen")]),n("span",{attrs:{class:"token punctuation"}},[t._v("(")]),n("span",{attrs:{class:"token number"}},[t._v("8080")]),n("span",{attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])])},function(){var t=this.$createElement,s=this._self._c||t;return s("h2",{attrs:{id:"https"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#https","aria-hidden":"true"}},[this._v("#")]),this._v(" HTTPS")])}],!1,null,null,null);e.options.__file="webhook.md";s.default=e.exports}}]);