Skip to content

Commit 8f49bd0

Browse files
author
Hyunje Jun
authored
Add destination field (#102)
* Add new WebhookRequestBody type To handle 'destination' field. * Fix middleware tests to handle 'destination' field * Update docs to mention of 'destination' field * Make originalError of HTTPError public Also make it any. * [kitchensink] Add console.log for destination * Use valid destintion for tests * Make destination a required field
1 parent d42a1ae commit 8f49bd0

File tree

6 files changed

+43
-7
lines changed

6 files changed

+43
-7
lines changed

docs/api-reference/middleware.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ app.use(middleware(config))
3737
3838
// or directly with handler
3939
app.post('/webhook', middleware(config), (req, res) => {
40-
req.body.events // will include webhook events
40+
req.body.events // webhook event objects
41+
req.body.destination // user ID of the bot (optional)
4142
...
4243
})
4344
```

docs/guide/webhook.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,9 @@ const config = {
6767
}
6868

6969
app.post('/webhook', middleware(config), (req, res) => {
70-
res.json(req.body.events) // req.body will be webhook event object
70+
req.body.events // webhook event objects
71+
req.body.destination // user ID of the bot (optional)
72+
...
7173
})
7274

7375
app.listen(8080)

examples/kitchensink/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ app.get('/callback', (req, res) => res.end(`I'm listening. Please access with PO
3131

3232
// webhook callback
3333
app.post('/callback', line.middleware(config), (req, res) => {
34+
if (req.body.destination) {
35+
console.log("Destination User ID: " + req.body.destination);
36+
}
37+
3438
// req.body.events should be an array of events
3539
if (!Array.isArray(req.body.events)) {
3640
return res.status(500).end();

lib/exceptions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export class HTTPError extends Error {
3131
message: string,
3232
public statusCode: number,
3333
public statusMessage: string,
34-
private originalError: Error,
34+
public originalError: any,
3535
) {
3636
super(message);
3737
}

lib/types.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,23 @@ export type Profile = {
1818
statusMessage: string;
1919
};
2020

21+
/**
22+
* Request body which is sent by webhook.
23+
*
24+
* @see [Request body](https://developers.line.me/en/reference/messaging-api/#request-body)
25+
*/
26+
export type WebhookRequestBody = {
27+
/**
28+
* User ID of a bot that should receive webhook events. The user ID value is a string that matches the regular expression, U[0-9a-f]{32}.
29+
*/
30+
destination: string;
31+
32+
/**
33+
* Information about the event
34+
*/
35+
events: Array<WebhookEvent>;
36+
};
37+
2138
/**
2239
* JSON objects which contain events generated on the LINE Platform.
2340
*

test/middleware.spec.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ const TEST_PORT = parseInt(process.env.TEST_PORT, 10);
1111

1212
const m = middleware({ channelSecret: "test_channel_secret" });
1313

14-
const getRecentReq = (): any =>
14+
const getRecentReq = (): { body: Types.WebhookRequestBody } =>
1515
JSON.parse(readFileSync(join(__dirname, "helpers/request.json")).toString());
1616

1717
describe("middleware", () => {
1818
const http = (
1919
headers: any = {
20-
"X-Line-Signature": "qeDy61PbQK+aO97Bs8zjaFgYjQxFruGd13pfXPQoBRU=",
20+
"X-Line-Signature": "wqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
2121
},
2222
) => new HTTPClient(`http://localhost:${TEST_PORT}`, headers);
2323

@@ -43,9 +43,11 @@ describe("middleware", () => {
4343
return http()
4444
.post(`/webhook`, {
4545
events: [webhook],
46+
destination: "Uaaaabbbbccccddddeeeeffff",
4647
})
4748
.then(() => {
4849
const req = getRecentReq();
50+
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
4951
deepEqual(req.body.events, [webhook]);
5052
});
5153
});
@@ -54,9 +56,11 @@ describe("middleware", () => {
5456
return http()
5557
.post(`/mid-text`, {
5658
events: [webhook],
59+
destination: "Uaaaabbbbccccddddeeeeffff",
5760
})
5861
.then(() => {
5962
const req = getRecentReq();
63+
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
6064
deepEqual(req.body.events, [webhook]);
6165
});
6266
});
@@ -65,9 +69,11 @@ describe("middleware", () => {
6569
return http()
6670
.post(`/mid-buffer`, {
6771
events: [webhook],
72+
destination: "Uaaaabbbbccccddddeeeeffff",
6873
})
6974
.then(() => {
7075
const req = getRecentReq();
76+
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
7177
deepEqual(req.body.events, [webhook]);
7278
});
7379
});
@@ -76,19 +82,22 @@ describe("middleware", () => {
7682
return http()
7783
.post(`/mid-rawbody`, {
7884
events: [webhook],
85+
destination: "Uaaaabbbbccccddddeeeeffff",
7986
})
8087
.then(() => {
8188
const req = getRecentReq();
89+
deepEqual(req.body.destination, "Uaaaabbbbccccddddeeeeffff");
8290
deepEqual(req.body.events, [webhook]);
8391
});
8492
});
8593

8694
it("fails on wrong signature", () => {
8795
return http({
88-
"X-Line-Signature": "qeDy61PbQK+aO97Bs8zjbFgYjQxFruGd13pfXPQoBRU=",
96+
"X-Line-Signature": "WqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
8997
})
9098
.post(`/webhook`, {
9199
events: [webhook],
100+
destination: "Uaaaabbbbccccddddeeeeffff",
92101
})
93102
.catch((err: HTTPError) => {
94103
equal(err.statusCode, 401);
@@ -107,7 +116,10 @@ describe("middleware", () => {
107116

108117
it("fails on empty signature", () => {
109118
return http({})
110-
.post(`/webhook`, { events: [webhook] })
119+
.post(`/webhook`, {
120+
events: [webhook],
121+
destination: "Uaaaabbbbccccddddeeeeffff",
122+
})
111123
.then((res: any) => {
112124
throw new Error();
113125
})

0 commit comments

Comments
 (0)