Skip to content

Commit 75d5da0

Browse files
authored
Allow to inject default header from clients (#1230)
This update allows additional headers to be set from the bot SDK's client. The behavior is as follows: 1. Non-critical headers, such as the user agent, can be overwritten. 2. critical header like authorization headers cannot be overriden. The goal is to allow the user agent to be overwritten when using this in other projects. Since it doesn't need to be limited to the user agent header, it has been implemented more generally.
1 parent 5175852 commit 75d5da0

File tree

15 files changed

+243
-49
lines changed

15 files changed

+243
-49
lines changed

generator/src/main/resources/line-bot-sdk-nodejs-generator/api-single.pebble

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import * as Types from "../../types.js";
1111
import {ensureJSON} from "../../utils.js";
1212
import {Readable} from "node:stream";
1313

14-
import HTTPFetchClient, { convertResponseToReadable } from "../../http-fetch.js";
14+
import HTTPFetchClient, { convertResponseToReadable, mergeHeaders } from "../../http-fetch.js";
1515

1616
// ===============================================
1717
// This file is autogenerated - Please do not edit
@@ -22,7 +22,7 @@ interface httpClientConfig {
2222
{% if authMethods != null -%}
2323
channelAccessToken: string;
2424
{% endif -%}
25-
// TODO support defaultHeaders?
25+
defaultHeaders?: Record<string, string>;
2626
}
2727

2828

@@ -31,12 +31,16 @@ export class {{operations.classname}} {
3131

3232
constructor(config: httpClientConfig) {
3333
const baseURL = config.baseURL || '{{endpoint(operations.classname)}}';
34+
const defaultHeaders = mergeHeaders(
35+
config.defaultHeaders,
36+
{% if authMethods != null -%}
37+
{ Authorization: "Bearer " + config.channelAccessToken }
38+
{% else -%}
39+
{}
40+
{% endif -%}
41+
);
3442
this.httpClient = new HTTPFetchClient({
35-
defaultHeaders: {
36-
{% if authMethods != null -%}
37-
Authorization: "Bearer " + config.channelAccessToken,
38-
{% endif -%}
39-
},
43+
defaultHeaders: defaultHeaders,
4044
baseURL: baseURL,
4145
});
4246
}

lib/channel-access-token/api/channelAccessTokenClient.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { Readable } from "node:stream";
2424

2525
import HTTPFetchClient, {
2626
convertResponseToReadable,
27+
mergeHeaders,
2728
} from "../../http-fetch.js";
2829

2930
// ===============================================
@@ -32,16 +33,17 @@ import HTTPFetchClient, {
3233

3334
interface httpClientConfig {
3435
baseURL?: string;
35-
// TODO support defaultHeaders?
36+
defaultHeaders?: Record<string, string>;
3637
}
3738

3839
export class ChannelAccessTokenClient {
3940
private httpClient: HTTPFetchClient;
4041

4142
constructor(config: httpClientConfig) {
4243
const baseURL = config.baseURL || "https://api.line.me";
44+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {});
4345
this.httpClient = new HTTPFetchClient({
44-
defaultHeaders: {},
46+
defaultHeaders: defaultHeaders,
4547
baseURL: baseURL,
4648
});
4749
}

lib/http-fetch.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,38 @@ export function convertResponseToReadable(response: Response): Readable {
2626
});
2727
}
2828

29+
export function normalizeHeaders(
30+
headers: Record<string, string> | undefined,
31+
): Record<string, string> {
32+
const normalized: Record<string, string> = {};
33+
if (!headers) {
34+
return normalized;
35+
}
36+
for (const key of Object.keys(headers)) {
37+
normalized[key.toLowerCase()] = headers[key];
38+
}
39+
return normalized;
40+
}
41+
42+
export function mergeHeaders(
43+
base: Record<string, string> | undefined,
44+
override: Record<string, string> | undefined,
45+
): Record<string, string> {
46+
const normalizedBase = normalizeHeaders(base);
47+
const normalizedOverride = normalizeHeaders(override);
48+
return { ...normalizedBase, ...normalizedOverride };
49+
}
50+
2951
export default class HTTPFetchClient {
3052
private readonly baseURL: string;
3153
private readonly defaultHeaders: Record<string, string>;
3254

3355
constructor(config: httpFetchClientConfig) {
3456
this.baseURL = config.baseURL;
35-
this.defaultHeaders = {
36-
"User-Agent": USER_AGENT,
37-
...config.defaultHeaders,
38-
};
57+
this.defaultHeaders = mergeHeaders(
58+
{ "User-Agent": USER_AGENT },
59+
config.defaultHeaders, // allow to override User-Agent
60+
);
3961
}
4062

4163
public async get<T>(url: string, params?: any): Promise<Response> {

lib/insight/api/insightClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { Readable } from "node:stream";
2323

2424
import HTTPFetchClient, {
2525
convertResponseToReadable,
26+
mergeHeaders,
2627
} from "../../http-fetch.js";
2728

2829
// ===============================================
@@ -32,18 +33,19 @@ import HTTPFetchClient, {
3233
interface httpClientConfig {
3334
baseURL?: string;
3435
channelAccessToken: string;
35-
// TODO support defaultHeaders?
36+
defaultHeaders?: Record<string, string>;
3637
}
3738

3839
export class InsightClient {
3940
private httpClient: HTTPFetchClient;
4041

4142
constructor(config: httpClientConfig) {
4243
const baseURL = config.baseURL || "https://api.line.me";
44+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
45+
Authorization: "Bearer " + config.channelAccessToken,
46+
});
4347
this.httpClient = new HTTPFetchClient({
44-
defaultHeaders: {
45-
Authorization: "Bearer " + config.channelAccessToken,
46-
},
48+
defaultHeaders: defaultHeaders,
4749
baseURL: baseURL,
4850
});
4951
}

lib/liff/api/liffClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { Readable } from "node:stream";
2222

2323
import HTTPFetchClient, {
2424
convertResponseToReadable,
25+
mergeHeaders,
2526
} from "../../http-fetch.js";
2627

2728
// ===============================================
@@ -31,18 +32,19 @@ import HTTPFetchClient, {
3132
interface httpClientConfig {
3233
baseURL?: string;
3334
channelAccessToken: string;
34-
// TODO support defaultHeaders?
35+
defaultHeaders?: Record<string, string>;
3536
}
3637

3738
export class LiffClient {
3839
private httpClient: HTTPFetchClient;
3940

4041
constructor(config: httpClientConfig) {
4142
const baseURL = config.baseURL || "https://api.line.me";
43+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
44+
Authorization: "Bearer " + config.channelAccessToken,
45+
});
4246
this.httpClient = new HTTPFetchClient({
43-
defaultHeaders: {
44-
Authorization: "Bearer " + config.channelAccessToken,
45-
},
47+
defaultHeaders: defaultHeaders,
4648
baseURL: baseURL,
4749
});
4850
}

lib/manage-audience/api/manageAudienceBlobClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Readable } from "node:stream";
1919

2020
import HTTPFetchClient, {
2121
convertResponseToReadable,
22+
mergeHeaders,
2223
} from "../../http-fetch.js";
2324

2425
// ===============================================
@@ -28,18 +29,19 @@ import HTTPFetchClient, {
2829
interface httpClientConfig {
2930
baseURL?: string;
3031
channelAccessToken: string;
31-
// TODO support defaultHeaders?
32+
defaultHeaders?: Record<string, string>;
3233
}
3334

3435
export class ManageAudienceBlobClient {
3536
private httpClient: HTTPFetchClient;
3637

3738
constructor(config: httpClientConfig) {
3839
const baseURL = config.baseURL || "https://api-data.line.me";
40+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
41+
Authorization: "Bearer " + config.channelAccessToken,
42+
});
3943
this.httpClient = new HTTPFetchClient({
40-
defaultHeaders: {
41-
Authorization: "Bearer " + config.channelAccessToken,
42-
},
44+
defaultHeaders: defaultHeaders,
4345
baseURL: baseURL,
4446
});
4547
}

lib/manage-audience/api/manageAudienceClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { Readable } from "node:stream";
3535

3636
import HTTPFetchClient, {
3737
convertResponseToReadable,
38+
mergeHeaders,
3839
} from "../../http-fetch.js";
3940

4041
// ===============================================
@@ -44,18 +45,19 @@ import HTTPFetchClient, {
4445
interface httpClientConfig {
4546
baseURL?: string;
4647
channelAccessToken: string;
47-
// TODO support defaultHeaders?
48+
defaultHeaders?: Record<string, string>;
4849
}
4950

5051
export class ManageAudienceClient {
5152
private httpClient: HTTPFetchClient;
5253

5354
constructor(config: httpClientConfig) {
5455
const baseURL = config.baseURL || "https://api.line.me";
56+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
57+
Authorization: "Bearer " + config.channelAccessToken,
58+
});
5559
this.httpClient = new HTTPFetchClient({
56-
defaultHeaders: {
57-
Authorization: "Bearer " + config.channelAccessToken,
58-
},
60+
defaultHeaders: defaultHeaders,
5961
baseURL: baseURL,
6062
});
6163
}

lib/messaging-api/api/messagingApiBlobClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Readable } from "node:stream";
1919

2020
import HTTPFetchClient, {
2121
convertResponseToReadable,
22+
mergeHeaders,
2223
} from "../../http-fetch.js";
2324

2425
// ===============================================
@@ -28,18 +29,19 @@ import HTTPFetchClient, {
2829
interface httpClientConfig {
2930
baseURL?: string;
3031
channelAccessToken: string;
31-
// TODO support defaultHeaders?
32+
defaultHeaders?: Record<string, string>;
3233
}
3334

3435
export class MessagingApiBlobClient {
3536
private httpClient: HTTPFetchClient;
3637

3738
constructor(config: httpClientConfig) {
3839
const baseURL = config.baseURL || "https://api-data.line.me";
40+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
41+
Authorization: "Bearer " + config.channelAccessToken,
42+
});
3943
this.httpClient = new HTTPFetchClient({
40-
defaultHeaders: {
41-
Authorization: "Bearer " + config.channelAccessToken,
42-
},
44+
defaultHeaders: defaultHeaders,
4345
baseURL: baseURL,
4446
});
4547
}

lib/messaging-api/api/messagingApiClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import { Readable } from "node:stream";
6565

6666
import HTTPFetchClient, {
6767
convertResponseToReadable,
68+
mergeHeaders,
6869
} from "../../http-fetch.js";
6970

7071
// ===============================================
@@ -74,18 +75,19 @@ import HTTPFetchClient, {
7475
interface httpClientConfig {
7576
baseURL?: string;
7677
channelAccessToken: string;
77-
// TODO support defaultHeaders?
78+
defaultHeaders?: Record<string, string>;
7879
}
7980

8081
export class MessagingApiClient {
8182
private httpClient: HTTPFetchClient;
8283

8384
constructor(config: httpClientConfig) {
8485
const baseURL = config.baseURL || "https://api.line.me";
86+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
87+
Authorization: "Bearer " + config.channelAccessToken,
88+
});
8589
this.httpClient = new HTTPFetchClient({
86-
defaultHeaders: {
87-
Authorization: "Bearer " + config.channelAccessToken,
88-
},
90+
defaultHeaders: defaultHeaders,
8991
baseURL: baseURL,
9092
});
9193
}

lib/module-attach/api/lineModuleAttachClient.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { Readable } from "node:stream";
1919

2020
import HTTPFetchClient, {
2121
convertResponseToReadable,
22+
mergeHeaders,
2223
} from "../../http-fetch.js";
2324

2425
// ===============================================
@@ -28,18 +29,19 @@ import HTTPFetchClient, {
2829
interface httpClientConfig {
2930
baseURL?: string;
3031
channelAccessToken: string;
31-
// TODO support defaultHeaders?
32+
defaultHeaders?: Record<string, string>;
3233
}
3334

3435
export class LineModuleAttachClient {
3536
private httpClient: HTTPFetchClient;
3637

3738
constructor(config: httpClientConfig) {
3839
const baseURL = config.baseURL || "https://manager.line.biz";
40+
const defaultHeaders = mergeHeaders(config.defaultHeaders, {
41+
Authorization: "Bearer " + config.channelAccessToken,
42+
});
3943
this.httpClient = new HTTPFetchClient({
40-
defaultHeaders: {
41-
Authorization: "Bearer " + config.channelAccessToken,
42-
},
44+
defaultHeaders: defaultHeaders,
4345
baseURL: baseURL,
4446
});
4547
}

0 commit comments

Comments
 (0)