Skip to content

Commit 1975091

Browse files
xingoxuianwith
andauthored
narrowcast api & audience apis (#193)
* add narrowcast api * add narrowcast progress api * add audienceGroup API * fix getUserInteractionStatistics * add test for narrowcast & audience API * add docs * Apply suggestions from code review Co-Authored-By: Ian Gong <gy.ian117@gmail.com> * fix review * add createClickAudienceGroup api Co-authored-by: Ian Gong <gy.ian117@gmail.com>
1 parent 2ecd26f commit 1975091

File tree

5 files changed

+797
-10
lines changed

5 files changed

+797
-10
lines changed

docs/api-reference/client.md

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ class Client {
1515
pushMessage(to: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
1616
replyMessage(replyToken: string, messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
1717
multicast(to: string[], messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
18-
broadcast(messages: Message | Message[], notificationDisabled: boolean = false): Promise<any>
18+
narrowcast(
19+
messages: Message | Message[],
20+
recipient?: ReceieptObject,
21+
filter?: { demographic: DemographicFilterObject },
22+
limit?: { max: number },
23+
): Promise<MessageAPIResponseBase>
24+
broadcast(messages: Message | Message[], notificationDisabled: boolean = false): Promise<MessageAPIResponseBase>
1925
getMessageContent(messageId: string): Promise<Readable>
2026

2127
// Profile
@@ -57,12 +63,78 @@ class Client {
5763
getTargetLimitForAdditionalMessages(): Promise<TargetLimitForAdditionalMessages>
5864
getNumberOfMessagesSentThisMonth(): Promise<NumberOfMessagesSentThisMonth>
5965
getNumberOfSentBroadcastMessages(date: string): Promise<NumberOfMessagesSentResponse>
66+
getNarrowcastProgress(requestId: string): Promise<NarrowcastProgressResponse>
6067

6168
// Insight
6269
getNumberOfMessageDeliveries(date: string): Promise<Types.NumberOfMessageDeliveriesResponse>
6370
getNumberOfFollowers(date: string): Promise<Types.NumberOfFollowersResponse>
6471
getFriendDemographics(): Promise<Types.FriendDemographics>
6572
getUserInteractionStatistics(requestId: string): Promise<Types.UserInteractionStatistics>
73+
74+
// AudienceGroup
75+
createUploadAudienceGroup(impAudienceGroup: {
76+
requestId: string;
77+
description: string;
78+
}) : Promise<{
79+
audienceGroupId: number;
80+
type: string;
81+
description: string;
82+
created: number;
83+
requestId: string;
84+
}>
85+
updateUploadAudienceGroup(
86+
description: string,
87+
audienceGroupId: string,
88+
): Promise<{}>
89+
createClickAudienceGroup(clickAudienceGroup: {
90+
description: string;
91+
requestId: string;
92+
clickUrl?: string;
93+
}) :Promise<{
94+
audienceGroupId: number;
95+
type: string;
96+
created: number;
97+
description: string;
98+
requestId: string;
99+
clickUrl: string;
100+
}>
101+
createImpAudienceGroup(impAudienceGroup: {
102+
requestId: string;
103+
description: string;
104+
}): Promise<{
105+
audienceGroupId: number;
106+
type: string;
107+
description: string;
108+
created: number;
109+
requestId: string;
110+
}>
111+
setDescriptionAudienceGroup(
112+
description: string,
113+
audienceGroupId: string,
114+
): Promise<{}>
115+
deleteAudienceGroup(audienceGroupId: string): Promise<{}>
116+
getAudienceGroup(audienceGroupId: string): Promise<AudienceGroup>
117+
getAudienceGroups(
118+
page: number,
119+
description?: string,
120+
status?: AudienceGroupStatus,
121+
size?: number,
122+
createRoute?: AudienceGroupCreateRoute,
123+
includesExternalPublicGroups?: boolean,
124+
): Promise<{
125+
audienceGroups: AudienceGroups;
126+
hasNextPage: boolean;
127+
totalCount: number;
128+
readWriteAudienceGroupTotalCount: number;
129+
page: number;
130+
size: number;
131+
}>
132+
getAudienceGroupAuthorityLevel(): Promise<{
133+
authorityLevel: Types.AudienceGroupAuthorityLevel
134+
}>
135+
changeAudienceGroupAuthorityLevel(
136+
authorityLevel: Types.AudienceGroupAuthorityLevel
137+
): Promise<{}>
66138
}
67139
```
68140

lib/client.ts

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Readable } from "stream";
22
import HTTPClient from "./http";
33
import * as Types from "./types";
4-
import { AxiosResponse } from "axios";
4+
import { AxiosResponse, AxiosRequestConfig } from "axios";
55

66
import { ensureJSON, toArray } from "./utils";
77

@@ -27,6 +27,7 @@ export default class Client {
2727
Authorization: "Bearer " + this.config.channelAccessToken,
2828
},
2929
responseParser: this.parseHTTPResponse.bind(this),
30+
...config.httpConfig,
3031
});
3132
}
3233

@@ -78,6 +79,22 @@ export default class Client {
7879
});
7980
}
8081

82+
public async narrowcast(
83+
messages: Types.Message | Types.Message[],
84+
recipient?: Types.ReceieptObject,
85+
filter?: { demographic: Types.DemographicFilterObject },
86+
limit?: { max: number },
87+
notificationDisabled: boolean = false,
88+
): Promise<Types.MessageAPIResponseBase> {
89+
return this.http.post(`${MESSAGING_API_PREFIX}/message/narrowcast`, {
90+
messages: toArray(messages),
91+
recipient,
92+
filter,
93+
limit,
94+
notificationDisabled,
95+
});
96+
}
97+
8198
public async broadcast(
8299
messages: Types.Message | Types.Message[],
83100
notificationDisabled: boolean = false,
@@ -303,6 +320,15 @@ export default class Client {
303320
return ensureJSON(res);
304321
}
305322

323+
public async getNarrowcastProgress(
324+
requestId: string,
325+
): Promise<Types.NarrowcastProgressResponse> {
326+
const res = await this.http.get<Types.NarrowcastProgressResponse>(
327+
`${MESSAGING_API_PREFIX}/message/progress/narrowcast?requestId=${requestId}`,
328+
);
329+
return ensureJSON(res);
330+
}
331+
306332
public async getTargetLimitForAdditionalMessages(): Promise<
307333
Types.TargetLimitForAdditionalMessages
308334
> {
@@ -363,6 +389,146 @@ export default class Client {
363389
);
364390
return ensureJSON(res);
365391
}
392+
393+
public async createUploadAudienceGroup(uploadAudienceGroup: {
394+
description: string;
395+
isIfaAudience: boolean;
396+
audiences: { id: string }[];
397+
uploadDescription?: string;
398+
}) {
399+
const res = await this.http.post<{
400+
audienceGroupId: number;
401+
type: string;
402+
description: string;
403+
created: number;
404+
}>(`${MESSAGING_API_PREFIX}/audienceGroup/upload`, {
405+
...uploadAudienceGroup,
406+
});
407+
return ensureJSON(res);
408+
}
409+
410+
public async updateUploadAudienceGroup(
411+
uploadAudienceGroup: {
412+
audienceGroupId: number;
413+
description?: string;
414+
uploadDescription?: string;
415+
audiences: { id: string }[];
416+
},
417+
// for set request timeout
418+
httpConfig?: Partial<AxiosRequestConfig>,
419+
) {
420+
const res = await this.http.put<{}>(
421+
`${MESSAGING_API_PREFIX}/audienceGroup/upload`,
422+
{
423+
...uploadAudienceGroup,
424+
},
425+
httpConfig,
426+
);
427+
return ensureJSON(res);
428+
}
429+
430+
public async createClickAudienceGroup(clickAudienceGroup: {
431+
description: string;
432+
requestId: string;
433+
clickUrl?: string;
434+
}) {
435+
const res = await this.http.post<
436+
{
437+
audienceGroupId: number;
438+
type: string;
439+
created: number;
440+
} & typeof clickAudienceGroup
441+
>(`${MESSAGING_API_PREFIX}/audienceGroup/click`, {
442+
...clickAudienceGroup,
443+
});
444+
return ensureJSON(res);
445+
}
446+
447+
public async createImpAudienceGroup(impAudienceGroup: {
448+
requestId: string;
449+
description: string;
450+
}) {
451+
const res = await this.http.post<
452+
{
453+
audienceGroupId: number;
454+
type: string;
455+
created: number;
456+
} & typeof impAudienceGroup
457+
>(`${MESSAGING_API_PREFIX}/audienceGroup/imp`, {
458+
...impAudienceGroup,
459+
});
460+
return ensureJSON(res);
461+
}
462+
463+
public async setDescriptionAudienceGroup(
464+
description: string,
465+
audienceGroupId: string,
466+
) {
467+
const res = await this.http.put<{}>(
468+
`${MESSAGING_API_PREFIX}/audienceGroup/${audienceGroupId}/updateDescription`,
469+
{
470+
description,
471+
},
472+
);
473+
return ensureJSON(res);
474+
}
475+
476+
public async deleteAudienceGroup(audienceGroupId: string) {
477+
const res = await this.http.delete<{}>(
478+
`${MESSAGING_API_PREFIX}/audienceGroup/${audienceGroupId}`,
479+
);
480+
return ensureJSON(res);
481+
}
482+
483+
public async getAudienceGroup(audienceGroupId: string) {
484+
const res = await this.http.get<Types.AudienceGroup>(
485+
`${MESSAGING_API_PREFIX}/audienceGroup/${audienceGroupId}`,
486+
);
487+
return ensureJSON(res);
488+
}
489+
490+
public async getAudienceGroups(
491+
page: number,
492+
description?: string,
493+
status?: Types.AudienceGroupStatus,
494+
size?: number,
495+
createRoute?: Types.AudienceGroupCreateRoute,
496+
includesExternalPublicGroups?: boolean,
497+
) {
498+
const res = await this.http.get<{
499+
audienceGroups: Types.AudienceGroups;
500+
hasNextPage: boolean;
501+
totalCount: number;
502+
readWriteAudienceGroupTotalCount: number;
503+
page: number;
504+
size: number;
505+
}>(`${MESSAGING_API_PREFIX}/audienceGroup/list`, {
506+
page,
507+
description,
508+
status,
509+
size,
510+
createRoute,
511+
includesExternalPublicGroups,
512+
});
513+
return ensureJSON(res);
514+
}
515+
516+
public async getAudienceGroupAuthorityLevel() {
517+
const res = await this.http.get<{
518+
authorityLevel: Types.AudienceGroupAuthorityLevel;
519+
}>(`${MESSAGING_API_PREFIX}/audienceGroup/authorityLevel`);
520+
return ensureJSON(res);
521+
}
522+
523+
public async changeAudienceGroupAuthorityLevel(
524+
authorityLevel: Types.AudienceGroupAuthorityLevel,
525+
) {
526+
const res = await this.http.put<{}>(
527+
`${MESSAGING_API_PREFIX}/audienceGroup/authorityLevel`,
528+
{ authorityLevel },
529+
);
530+
return ensureJSON(res);
531+
}
366532
}
367533

368534
export class OAuth {

lib/http.ts

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
import axios, { AxiosInstance, AxiosError, AxiosResponse } from "axios";
1+
import axios, {
2+
AxiosInstance,
3+
AxiosError,
4+
AxiosResponse,
5+
AxiosRequestConfig,
6+
} from "axios";
27
import { Readable } from "stream";
38
import { HTTPError, ReadError, RequestError } from "./exceptions";
49
import * as fileType from "file-type";
510
import * as qs from "querystring";
611

712
const pkg = require("../package.json");
813

9-
type httpClientConfig = {
14+
interface httpClientConfig extends Partial<AxiosRequestConfig> {
1015
baseURL?: string;
1116
defaultHeaders?: any;
1217
responseParser?: <T>(res: AxiosResponse) => T;
13-
};
18+
}
1419

1520
export default class HTTPClient {
1621
private instance: AxiosInstance;
@@ -50,11 +55,28 @@ export default class HTTPClient {
5055
headers: { "Content-Type": "application/json" },
5156
});
5257

58+
return this.responseParse(res);
59+
}
60+
61+
private responseParse(res: AxiosResponse) {
5362
const { responseParser } = this.config;
54-
if (responseParser) return responseParser<T>(res);
63+
if (responseParser) return responseParser(res);
5564
else return res.data;
5665
}
5766

67+
public async put<T>(
68+
url: string,
69+
body?: any,
70+
config?: Partial<AxiosRequestConfig>,
71+
): Promise<T> {
72+
const res = await this.instance.put(url, body, {
73+
headers: { "Content-Type": "application/json" },
74+
...config,
75+
});
76+
77+
return this.responseParse(res);
78+
}
79+
5880
public async postForm<T>(url: string, body?: any): Promise<T> {
5981
const res = await this.instance.post(url, qs.stringify(body), {
6082
headers: { "Content-Type": "application/x-www-form-urlencoded" },

0 commit comments

Comments
 (0)