Skip to content

Commit 0678d7e

Browse files
github-actions[bot]github-actions
andauthored
Support new Membership API and Webhook (#1163)
line/line-openapi#86 # Support new Membership API and Webhook We have implemented and supported new API and Webhook about Membership. ## API to get a list of users who joined the membership You can obtain a list of user IDs for users who have joined the membership of your LINE Official Account by calling `client.getJoinedMembershipUsers(...)`. Documents: https://developers.line.biz/en/reference/messaging-api/#get-membership-user-ids ## Membership Webhook We have introduced new Webhook events `MembershipEvent` that indicates that a user has joined, left or renewed a membership of your LINE Official Account. Documents: https://developers.line.biz/en/reference/messaging-api/#membership-event ## For more details For more details, check out the announcement: https://developers.line.biz/en/news/2025/02/13/membership-api/ Co-authored-by: github-actions <[email protected]>
1 parent c1718c6 commit 0678d7e

File tree

14 files changed

+375
-1
lines changed

14 files changed

+375
-1
lines changed

lib/messaging-api/.openapi-generator/FILES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ model/genderDemographicFilter.ts
6666
model/getAggregationUnitNameListResponse.ts
6767
model/getAggregationUnitUsageResponse.ts
6868
model/getFollowersResponse.ts
69+
model/getJoinedMembershipUsersResponse.ts
6970
model/getMembershipSubscriptionResponse.ts
7071
model/getMessageContentTranscodingResponse.ts
7172
model/getWebhookEndpointResponse.ts

lib/messaging-api/api/messagingApiClient.ts

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { ErrorResponse } from "../model/errorResponse.js";
1818
import { GetAggregationUnitNameListResponse } from "../model/getAggregationUnitNameListResponse.js";
1919
import { GetAggregationUnitUsageResponse } from "../model/getAggregationUnitUsageResponse.js";
2020
import { GetFollowersResponse } from "../model/getFollowersResponse.js";
21+
import { GetJoinedMembershipUsersResponse } from "../model/getJoinedMembershipUsersResponse.js";
2122
import { GetMembershipSubscriptionResponse } from "../model/getMembershipSubscriptionResponse.js";
2223
import { GetWebhookEndpointResponse } from "../model/getWebhookEndpointResponse.js";
2324
import { GroupMemberCountResponse } from "../model/groupMemberCountResponse.js";
@@ -589,6 +590,63 @@ export class MessagingApiClient {
589590
const parsedBody = text ? JSON.parse(text) : null;
590591
return { httpResponse: res, body: parsedBody };
591592
}
593+
/**
594+
* Get a list of user IDs who joined the membership.
595+
* @param membershipId Membership plan ID.
596+
* @param start A continuation token to get next remaining membership user IDs. Returned only when there are remaining user IDs that weren\'t returned in the userIds property in the previous request. The continuation token expires in 24 hours (86,400 seconds).
597+
* @param limit The max number of items to return for this API call. The value is set to 300 by default, but the max acceptable value is 1000.
598+
*
599+
* @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-membership-user-ids"> Documentation</a>
600+
*/
601+
public async getJoinedMembershipUsers(
602+
membershipId: number,
603+
start?: string,
604+
limit?: number,
605+
): Promise<GetJoinedMembershipUsersResponse> {
606+
return (
607+
await this.getJoinedMembershipUsersWithHttpInfo(
608+
membershipId,
609+
start,
610+
limit,
611+
)
612+
).body;
613+
}
614+
615+
/**
616+
* Get a list of user IDs who joined the membership..
617+
* This method includes HttpInfo object to return additional information.
618+
* @param membershipId Membership plan ID.
619+
* @param start A continuation token to get next remaining membership user IDs. Returned only when there are remaining user IDs that weren\'t returned in the userIds property in the previous request. The continuation token expires in 24 hours (86,400 seconds).
620+
* @param limit The max number of items to return for this API call. The value is set to 300 by default, but the max acceptable value is 1000.
621+
*
622+
* @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-membership-user-ids"> Documentation</a>
623+
*/
624+
public async getJoinedMembershipUsersWithHttpInfo(
625+
membershipId: number,
626+
start?: string,
627+
limit?: number,
628+
): Promise<Types.ApiResponseType<GetJoinedMembershipUsersResponse>> {
629+
const queryParams = {
630+
start: start,
631+
limit: limit,
632+
};
633+
Object.keys(queryParams).forEach((key: keyof typeof queryParams) => {
634+
if (queryParams[key] === undefined) {
635+
delete queryParams[key];
636+
}
637+
});
638+
639+
const res = await this.httpClient.get(
640+
"/v2/bot/membership/{membershipId}/users/ids".replace(
641+
"{membershipId}",
642+
String(membershipId),
643+
),
644+
queryParams,
645+
);
646+
const text = await res.text();
647+
const parsedBody = text ? JSON.parse(text) : null;
648+
return { httpResponse: res, body: parsedBody };
649+
}
592650
/**
593651
* Get a list of memberships.
594652
*
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/**
2+
* LINE Messaging API
3+
* This document describes LINE Messaging API.
4+
*
5+
* The version of the OpenAPI document: 0.0.1
6+
*
7+
*
8+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9+
* https://openapi-generator.tech
10+
* Do not edit the class manually.
11+
*/
12+
13+
/**
14+
* List of users who have joined the membership
15+
*/
16+
export type GetJoinedMembershipUsersResponse = {
17+
/**
18+
* A list of user IDs who joined the membership. Users who have not agreed to the bot user agreement, are not following the bot, or are not active will be excluded. If there are no users in the membership, an empty list will be returned.
19+
*
20+
* @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-membership-user-ids">userIds Documentation</a>
21+
*/
22+
userIds: Array<string> /**/;
23+
/**
24+
* A continuation token to get next remaining membership user IDs. Returned only when there are remaining user IDs that weren\'t returned in the userIds property in the previous request. The continuation token expires in 24 hours (86,400 seconds).
25+
*
26+
* @see <a href="https://developers.line.biz/en/reference/messaging-api/#get-membership-user-ids">next Documentation</a>
27+
*/
28+
next?: string /**/;
29+
};

lib/messaging-api/model/models.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export * from "./genderDemographicFilter.js";
6161
export * from "./getAggregationUnitNameListResponse.js";
6262
export * from "./getAggregationUnitUsageResponse.js";
6363
export * from "./getFollowersResponse.js";
64+
export * from "./getJoinedMembershipUsersResponse.js";
6465
export * from "./getMembershipSubscriptionResponse.js";
6566
export * from "./getMessageContentTranscodingResponse.js";
6667
export * from "./getWebhookEndpointResponse.js";

lib/messaging-api/tests/api/MessagingApiClientTest.spec.ts

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { ErrorResponse } from "../../model/errorResponse.js";
77
import { GetAggregationUnitNameListResponse } from "../../model/getAggregationUnitNameListResponse.js";
88
import { GetAggregationUnitUsageResponse } from "../../model/getAggregationUnitUsageResponse.js";
99
import { GetFollowersResponse } from "../../model/getFollowersResponse.js";
10+
import { GetJoinedMembershipUsersResponse } from "../../model/getJoinedMembershipUsersResponse.js";
1011
import { GetMembershipSubscriptionResponse } from "../../model/getMembershipSubscriptionResponse.js";
1112
import { GetWebhookEndpointResponse } from "../../model/getWebhookEndpointResponse.js";
1213
import { GroupMemberCountResponse } from "../../model/groupMemberCountResponse.js";
@@ -1472,6 +1473,144 @@ describe("MessagingApiClient", () => {
14721473
server.close();
14731474
});
14741475

1476+
it("getJoinedMembershipUsersWithHttpInfo", async () => {
1477+
let requestCount = 0;
1478+
1479+
const server = createServer((req, res) => {
1480+
requestCount++;
1481+
1482+
equal(req.method, "GET");
1483+
const reqUrl = new URL(req.url, "http://localhost/");
1484+
equal(
1485+
reqUrl.pathname,
1486+
"/v2/bot/membership/{membershipId}/users/ids"
1487+
.replace("{membershipId}", "0") // number
1488+
.replace("{start}", "DUMMY") // string
1489+
.replace("{limit}", "0"), // number
1490+
);
1491+
1492+
// Query parameters
1493+
const queryParams = new URLSearchParams(reqUrl.search);
1494+
equal(
1495+
queryParams.get("start"),
1496+
String(
1497+
// start: string
1498+
"DUMMY" as unknown as string, // paramName=start(enum)
1499+
),
1500+
);
1501+
equal(
1502+
queryParams.get("limit"),
1503+
String(
1504+
// limit: number
1505+
"DUMMY" as unknown as number, // paramName=limit(enum)
1506+
),
1507+
);
1508+
1509+
equal(req.headers["authorization"], `Bearer ${channel_access_token}`);
1510+
equal(req.headers["user-agent"], "@line/bot-sdk/1.0.0-test");
1511+
1512+
res.writeHead(200, { "Content-Type": "application/json" });
1513+
res.end(JSON.stringify({}));
1514+
});
1515+
await new Promise(resolve => {
1516+
server.listen(0);
1517+
server.on("listening", resolve);
1518+
});
1519+
1520+
const serverAddress = server.address();
1521+
if (typeof serverAddress === "string" || serverAddress === null) {
1522+
throw new Error("Unexpected server address: " + serverAddress);
1523+
}
1524+
1525+
const client = new MessagingApiClient({
1526+
channelAccessToken: channel_access_token,
1527+
baseURL: `http://localhost:${String(serverAddress.port)}/`,
1528+
});
1529+
1530+
const res = await client.getJoinedMembershipUsersWithHttpInfo(
1531+
// membershipId: number
1532+
0, // paramName=membershipId(number or int or long)
1533+
1534+
// start: string
1535+
"DUMMY" as unknown as string, // paramName=start(enum)
1536+
1537+
// limit: number
1538+
"DUMMY" as unknown as number, // paramName=limit(enum)
1539+
);
1540+
1541+
equal(requestCount, 1);
1542+
server.close();
1543+
});
1544+
1545+
it("getJoinedMembershipUsers", async () => {
1546+
let requestCount = 0;
1547+
1548+
const server = createServer((req, res) => {
1549+
requestCount++;
1550+
1551+
equal(req.method, "GET");
1552+
const reqUrl = new URL(req.url, "http://localhost/");
1553+
equal(
1554+
reqUrl.pathname,
1555+
"/v2/bot/membership/{membershipId}/users/ids"
1556+
.replace("{membershipId}", "0") // number
1557+
.replace("{start}", "DUMMY") // string
1558+
.replace("{limit}", "0"), // number
1559+
);
1560+
1561+
// Query parameters
1562+
const queryParams = new URLSearchParams(reqUrl.search);
1563+
equal(
1564+
queryParams.get("start"),
1565+
String(
1566+
// start: string
1567+
"DUMMY" as unknown as string, // paramName=start(enum)
1568+
),
1569+
);
1570+
equal(
1571+
queryParams.get("limit"),
1572+
String(
1573+
// limit: number
1574+
"DUMMY" as unknown as number, // paramName=limit(enum)
1575+
),
1576+
);
1577+
1578+
equal(req.headers["authorization"], `Bearer ${channel_access_token}`);
1579+
equal(req.headers["user-agent"], "@line/bot-sdk/1.0.0-test");
1580+
1581+
res.writeHead(200, { "Content-Type": "application/json" });
1582+
res.end(JSON.stringify({}));
1583+
});
1584+
await new Promise(resolve => {
1585+
server.listen(0);
1586+
server.on("listening", resolve);
1587+
});
1588+
1589+
const serverAddress = server.address();
1590+
if (typeof serverAddress === "string" || serverAddress === null) {
1591+
throw new Error("Unexpected server address: " + serverAddress);
1592+
}
1593+
1594+
const client = new MessagingApiClient({
1595+
channelAccessToken: channel_access_token,
1596+
baseURL: `http://localhost:${String(serverAddress.port)}/`,
1597+
});
1598+
1599+
const res = await client.getJoinedMembershipUsers(
1600+
// membershipId: number
1601+
0, // paramName=membershipId(number or int or long)
1602+
1603+
// start: string
1604+
"DUMMY" as unknown as string, // paramName=start(enum)
1605+
1606+
// limit: number
1607+
"DUMMY" as unknown as number, // paramName=limit(enum)
1608+
);
1609+
1610+
equal(requestCount, 1);
1611+
server.close();
1612+
});
1613+
14751614
it("getMembershipListWithHttpInfo", async () => {
14761615
let requestCount = 0;
14771616

lib/webhook/.openapi-generator/FILES

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ model/imageMessageContent.ts
2929
model/imageSet.ts
3030
model/joinEvent.ts
3131
model/joinedMembers.ts
32+
model/joinedMembershipContent.ts
3233
model/leaveEvent.ts
3334
model/leftMembers.ts
35+
model/leftMembershipContent.ts
3436
model/linkContent.ts
3537
model/linkThingsContent.ts
3638
model/locationMessageContent.ts
3739
model/memberJoinedEvent.ts
3840
model/memberLeftEvent.ts
41+
model/membershipContent.ts
42+
model/membershipEvent.ts
3943
model/mention.ts
4044
model/mentionee.ts
4145
model/messageContent.ts
@@ -47,6 +51,7 @@ model/pnpDelivery.ts
4751
model/pnpDeliveryCompletionEvent.ts
4852
model/postbackContent.ts
4953
model/postbackEvent.ts
54+
model/renewedMembershipContent.ts
5055
model/roomSource.ts
5156
model/scenarioResult.ts
5257
model/scenarioResultThingsContent.ts

lib/webhook/model/event.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { JoinEvent } from "./models.js";
2626
import { LeaveEvent } from "./models.js";
2727
import { MemberJoinedEvent } from "./models.js";
2828
import { MemberLeftEvent } from "./models.js";
29+
import { MembershipEvent } from "./models.js";
2930
import { MessageEvent } from "./models.js";
3031
import { ModuleEvent } from "./models.js";
3132
import { PostbackEvent } from "./models.js";
@@ -47,6 +48,7 @@ export type Event =
4748
| LeaveEvent // leave
4849
| MemberJoinedEvent // memberJoined
4950
| MemberLeftEvent // memberLeft
51+
| MembershipEvent // membership
5052
| MessageEvent // message
5153
| ModuleEvent // module
5254
| PostbackEvent // postback
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Webhook Type Definition
3+
* Webhook event definition of the LINE Messaging API
4+
*
5+
* The version of the OpenAPI document: 1.0.0
6+
*
7+
*
8+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9+
* https://openapi-generator.tech
10+
* Do not edit the class manually.
11+
*/
12+
13+
import { MembershipContent } from "./membershipContent.js";
14+
15+
import { MembershipContentBase } from "./models.js";
16+
17+
export type JoinedMembershipContent = MembershipContentBase & {
18+
type: "joined";
19+
/**
20+
* The ID of the membership that the user joined. This is defined for each membership.
21+
*/
22+
membershipId: number /**/;
23+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* Webhook Type Definition
3+
* Webhook event definition of the LINE Messaging API
4+
*
5+
* The version of the OpenAPI document: 1.0.0
6+
*
7+
*
8+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9+
* https://openapi-generator.tech
10+
* Do not edit the class manually.
11+
*/
12+
13+
import { MembershipContent } from "./membershipContent.js";
14+
15+
import { MembershipContentBase } from "./models.js";
16+
17+
export type LeftMembershipContent = MembershipContentBase & {
18+
type: "left";
19+
/**
20+
* The ID of the membership that the user left. This is defined for each membership.
21+
*/
22+
membershipId: number /**/;
23+
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* Webhook Type Definition
3+
* Webhook event definition of the LINE Messaging API
4+
*
5+
* The version of the OpenAPI document: 1.0.0
6+
*
7+
*
8+
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
9+
* https://openapi-generator.tech
10+
* Do not edit the class manually.
11+
*/
12+
13+
import { JoinedMembershipContent } from "./models.js";
14+
import { LeftMembershipContent } from "./models.js";
15+
import { RenewedMembershipContent } from "./models.js";
16+
17+
export type MembershipContent =
18+
| JoinedMembershipContent // joined
19+
| LeftMembershipContent // left
20+
| RenewedMembershipContent; // renewed
21+
22+
/**
23+
* Content of the membership event.
24+
*/
25+
export type MembershipContentBase = {
26+
/**
27+
* Type of membership event.
28+
*/
29+
type: string /**/;
30+
};

0 commit comments

Comments
 (0)