Skip to content

Commit c883f52

Browse files
authored
chore: getLineRequestId -> x-line-request-id plain object (#157)
* chore: getLineRequestId -> x-line-request-id plain object * add test for http branch
1 parent 4b2b525 commit c883f52

File tree

7 files changed

+67
-51
lines changed

7 files changed

+67
-51
lines changed

docs/api-reference/client.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ class Client {
1212
constructor(config: ClientConfig) {}
1313

1414
// Message
15-
pushMessage(to: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIBasicResponse>
16-
replyMessage(replyToken: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIBasicResponse>
17-
multicast(to: string[], messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIBasicResponse>
15+
pushMessage(to: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
16+
replyMessage(replyToken: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
17+
multicast(to: string[], messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
1818
broadcast(messages: Message | Message[], notificationDisabled: boolean = false): Promise<any>
1919
getMessageContent(messageId: string): Promise<Readable>
2020

@@ -88,7 +88,7 @@ in [the Client guide](../guide/client.md).
8888

8989
### Message
9090

91-
#### `pushMessage(to: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIBasicResponse>`
91+
#### `pushMessage(to: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>`
9292

9393
It corresponds to the [Push message](https://developers.line.me/en/docs/messaging-api/reference/#send-push-message) API.
9494

@@ -101,7 +101,7 @@ client.pushMessage('user_or_group_or_room_id', {
101101
})
102102
```
103103

104-
#### `replyMessage(replyToken: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIBasicResponse>`
104+
#### `replyMessage(replyToken: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>`
105105

106106
It corresponds to the [Reply message](https://developers.line.me/en/docs/messaging-api/reference/#send-reply-message) API.
107107

@@ -116,7 +116,7 @@ client.replyMessage(event.replyToken, {
116116
})
117117
```
118118

119-
#### `multicast(to: string[], messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIBasicResponse>`
119+
#### `multicast(to: string[], messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>`
120120

121121
It corresponds to the [Multicast](https://developers.line.me/en/docs/messaging-api/reference/#send-multicast-messages) API.
122122

lib/client.ts

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Readable } from "stream";
22
import HTTPClient from "./http";
33
import * as Types from "./types";
44
import { JSONParseError } from "./exceptions";
5+
import { AxiosResponse } from "axios";
56

67
function toArray<T>(maybeArr: T | T[]): T[] {
78
return Array.isArray(maybeArr) ? maybeArr : [maybeArr];
@@ -27,40 +28,33 @@ export default class Client {
2728
}
2829

2930
this.config = config;
30-
this.http = new HTTPClient(
31-
process.env.API_BASE_URL || "https://api.line.me/v2/bot/",
32-
{
31+
this.http = new HTTPClient({
32+
baseURL: process.env.API_BASE_URL || "https://api.line.me/v2/bot/",
33+
defaultHeaders: {
3334
Authorization: "Bearer " + this.config.channelAccessToken,
3435
},
35-
);
36-
}
37-
38-
private setLineRequestId(response: object, lineRequestId: string): boolean {
39-
return Reflect.defineProperty(response, "getLineRequestId", {
40-
enumerable: false,
41-
value: (): string => {
42-
return lineRequestId;
43-
},
36+
responseParser: this.parseHTTPResponse.bind(this),
4437
});
4538
}
4639

47-
private async postMessagingAPI(
48-
url: string,
49-
body?: any,
50-
): Promise<Types.MessageAPIResponseBase> {
51-
const res = await this.http.postJson(url, body);
52-
// header names are lower-cased
53-
// https://nodejs.org/api/http.html#http_message_headers
54-
this.setLineRequestId(res.data, res.headers["x-line-request-id"]);
55-
return res.data as Types.MessageAPIResponseBase;
40+
private parseHTTPResponse(response: AxiosResponse) {
41+
const { LINE_REQUEST_ID_HTTP_HEADER_NAME } = Types;
42+
let resBody = {
43+
...response.data,
44+
};
45+
if (response.headers[LINE_REQUEST_ID_HTTP_HEADER_NAME]) {
46+
resBody[LINE_REQUEST_ID_HTTP_HEADER_NAME] =
47+
response.headers[LINE_REQUEST_ID_HTTP_HEADER_NAME];
48+
}
49+
return resBody;
5650
}
5751

5852
public pushMessage(
5953
to: string,
6054
messages: Types.Message | Types.Message[],
6155
notificationDisabled: boolean = false,
6256
): Promise<Types.MessageAPIResponseBase> {
63-
return this.postMessagingAPI("/message/push", {
57+
return this.http.post("/message/push", {
6458
messages: toArray(messages),
6559
to,
6660
notificationDisabled,
@@ -72,7 +66,7 @@ export default class Client {
7266
messages: Types.Message | Types.Message[],
7367
notificationDisabled: boolean = false,
7468
): Promise<Types.MessageAPIResponseBase> {
75-
return this.postMessagingAPI("/message/reply", {
69+
return this.http.post("/message/reply", {
7670
messages: toArray(messages),
7771
replyToken,
7872
notificationDisabled,
@@ -84,7 +78,7 @@ export default class Client {
8478
messages: Types.Message | Types.Message[],
8579
notificationDisabled: boolean = false,
8680
): Promise<Types.MessageAPIResponseBase> {
87-
return this.postMessagingAPI("/message/multicast", {
81+
return this.http.post("/message/multicast", {
8882
messages: toArray(messages),
8983
to,
9084
notificationDisabled,
@@ -94,7 +88,7 @@ export default class Client {
9488
public async broadcast(
9589
messages: Types.Message | Types.Message[],
9690
notificationDisabled: boolean = false,
97-
): Promise<any> {
91+
): Promise<Types.MessageAPIResponseBase> {
9892
return this.http.post("/message/broadcast", {
9993
messages: toArray(messages),
10094
notificationDisabled,

lib/http.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
1-
import axios, { AxiosInstance, AxiosError } from "axios";
2-
import { AxiosResponse } from "axios";
1+
import axios, { AxiosInstance, AxiosError, AxiosResponse } from "axios";
32
import { Readable } from "stream";
43
import { HTTPError, ReadError, RequestError } from "./exceptions";
54
import * as fileType from "file-type";
65

76
const pkg = require("../package.json");
87

8+
type httpClientConfig = {
9+
baseURL?: string;
10+
defaultHeaders?: any;
11+
responseParser?: <T>(res: AxiosResponse) => T;
12+
};
13+
914
export default class HTTPClient {
1015
private instance: AxiosInstance;
16+
private config: httpClientConfig;
1117

12-
constructor(baseURL?: string, defaultHeaders?: any) {
18+
constructor(config: httpClientConfig = {}) {
19+
this.config = config;
20+
const { baseURL, defaultHeaders } = config;
1321
this.instance = axios.create({
1422
baseURL,
1523
headers: Object.assign({}, defaultHeaders, {
@@ -36,15 +44,14 @@ export default class HTTPClient {
3644
return res.data as Readable;
3745
}
3846

39-
public postJson(url: string, body?: any): Promise<AxiosResponse> {
40-
return this.instance.post(url, body, {
47+
public async post<T>(url: string, body?: any): Promise<T> {
48+
const res = await this.instance.post(url, body, {
4149
headers: { "Content-Type": "application/json" },
4250
});
43-
}
4451

45-
public async post<T>(url: string, body?: any): Promise<T> {
46-
const res = await this.postJson(url, body);
47-
return res.data;
52+
const { responseParser } = this.config;
53+
if (responseParser) return responseParser<T>(res);
54+
else return res.data;
4855
}
4956

5057
public async postBinary<T>(

lib/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,7 @@ export type NumberOfSentBroadcastMessages = {
18011801
success?: number;
18021802
};
18031803

1804+
export const LINE_REQUEST_ID_HTTP_HEADER_NAME = "x-line-request-id";
18041805
export type MessageAPIResponseBase = {
1805-
getLineRequestId: () => string;
1806+
[LINE_REQUEST_ID_HTTP_HEADER_NAME]?: string;
18061807
};

test/client.spec.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ describe("client", () => {
5353
equal(req.method, "POST");
5454
equal(req.body.replyToken, "test_reply_token");
5555
deepEqual(req.body.messages, [testMsg]);
56-
deepEqual(res, {});
57-
equal(res.getLineRequestId(), "X-Line-Request-Id");
56+
equal(res["x-line-request-id"], "X-Line-Request-Id");
5857
});
5958

6059
it("push", async () => {
@@ -65,8 +64,7 @@ describe("client", () => {
6564
equal(req.method, "POST");
6665
equal(req.body.to, "test_user_id");
6766
deepEqual(req.body.messages, [testMsg]);
68-
deepEqual(res, {});
69-
equal(res.getLineRequestId(), "X-Line-Request-Id");
67+
equal(res["x-line-request-id"], "X-Line-Request-Id");
7068
});
7169

7270
it("multicast", async () => {
@@ -82,8 +80,7 @@ describe("client", () => {
8280
"test_user_id_3",
8381
]);
8482
deepEqual(req.body.messages, [testMsg, testMsg]);
85-
deepEqual(res, {});
86-
equal(res.getLineRequestId(), "X-Line-Request-Id");
83+
equal(res["x-line-request-id"], "X-Line-Request-Id");
8784
});
8885

8986
it("broadcast", async () => {
@@ -93,7 +90,7 @@ describe("client", () => {
9390
equal(req.path, "/message/broadcast");
9491
equal(req.method, "POST");
9592
deepEqual(req.body.messages, [testMsg, testMsg]);
96-
deepEqual(res, {});
93+
equal(res["x-line-request-id"], "X-Line-Request-Id");
9794
});
9895

9996
it("getProfile", async () => {

test/http.spec.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ const getRecentReq = (): any =>
1414
JSON.parse(readFileSync(join(__dirname, "helpers/request.json")).toString());
1515

1616
describe("http", () => {
17-
const http = new HTTPClient(`http://localhost:${TEST_PORT}`, {
18-
"test-header-key": "Test-Header-Value",
17+
const http = new HTTPClient({
18+
baseURL: `http://localhost:${TEST_PORT}`,
19+
defaultHeaders: {
20+
"test-header-key": "Test-Header-Value",
21+
},
1922
});
2023

2124
before(() => listen(TEST_PORT));
@@ -150,4 +153,14 @@ describe("http", () => {
150153
equal(err.code, "ENOTFOUND");
151154
}
152155
});
156+
157+
it("will generate default params", async () => {
158+
const http = new HTTPClient();
159+
const res = await http.get<any>(`http://localhost:${TEST_PORT}/get`);
160+
const req = getRecentReq();
161+
equal(req.method, "GET");
162+
equal(req.path, "/get");
163+
equal(req.headers["user-agent"], `${pkg.name}/${pkg.version}`);
164+
deepEqual(res, {});
165+
});
153166
});

test/middleware.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ describe("middleware", () => {
1919
headers: any = {
2020
"X-Line-Signature": "wqJD7WAIZhWcXThMCf8jZnwG3Hmn7EF36plkQGkj48w=",
2121
},
22-
) => new HTTPClient(`http://localhost:${TEST_PORT}`, headers);
22+
) =>
23+
new HTTPClient({
24+
baseURL: `http://localhost:${TEST_PORT}`,
25+
defaultHeaders: headers,
26+
});
2327

2428
before(() => listen(TEST_PORT, m));
2529
after(() => close());

0 commit comments

Comments
 (0)