Repository: line/line-bot-sdk-nodejs
Pull request #444 (2023-05-17 00:46:09)

feat: push,multicast accept customAggregationUnits as optional.
Based on [this announcement](https://developers.line.biz/ja/news/2022/09/28/messaging-api-updated/), customAggregationUnits is opened to every developer now, this sdk also adopt it as option.

The customAggregationUnits has validation rules so I also added a function to validate it and test cases. But if it's not needed for now I"ll remove it.

Thank you.


Patch:
diff --git a/lib/client.ts b/lib/client.ts
index 4839427..d26e90a 100644
--- a/lib/client.ts
+++ b/lib/client.ts
@@ -66,6 +66,7 @@ export default class Client {
     to: string,
     messages: Types.Message | Types.Message[],
     notificationDisabled: boolean = false,
+    customAggregationUnits?: string[],
   ): Promise<Types.MessageAPIResponseBase> {
     return this.http.post(
       `${MESSAGING_API_PREFIX}/message/push`,
@@ -73,6 +74,7 @@ export default class Client {
         messages: toArray(messages),
         to,
         notificationDisabled,
+        customAggregationUnits,
       },
       this.generateRequestConfig(),
     );
@@ -94,6 +96,7 @@ export default class Client {
     to: string[],
     messages: Types.Message | Types.Message[],
     notificationDisabled: boolean = false,
+    customAggregationUnits?: string[],
   ): Promise<Types.MessageAPIResponseBase> {
     return this.http.post(
       `${MESSAGING_API_PREFIX}/message/multicast`,
@@ -101,6 +104,7 @@ export default class Client {
         messages: toArray(messages),
         to,
         notificationDisabled,
+        customAggregationUnits,
       },
       this.generateRequestConfig(),
     );
@@ -196,6 +200,33 @@ export default class Client {
     );
   }
 
+  public validateCustomAggregationUnits(units: string[]): {
+    messages: string[];
+    valid: boolean;
+  } {
+    const messages: string[] = [];
+    if (units.length > 1) {
+      messages.push("customAggregationUnits can only contain one unit");
+    }
+    units.forEach((unit, index) => {
+      if (unit.length > 30) {
+        messages.push(
+          `customAggregationUnits[${index}] must be less than or equal to 30 characters`,
+        );
+      }
+      if (!/^[a-zA-Z0-9_]+$/.test(unit)) {
+        messages.push(
+          `customAggregationUnits[${index}] must be alphanumeric characters or underscores`,
+        );
+      }
+    });
+
+    return {
+      messages,
+      valid: messages.length === 0,
+    };
+  }
+
   public async getProfile(userId: string): Promise<Types.Profile> {
     const profile = await this.http.get<Types.Profile>(
       `${MESSAGING_API_PREFIX}/profile/${userId}`,


Test patch:
diff --git a/test/client.spec.ts b/test/client.spec.ts
index 6e97d47..5dbda33 100644
--- a/test/client.spec.ts
+++ b/test/client.spec.ts
@@ -349,6 +349,45 @@ describe("client", () => {
     strictEqual(res["x-line-request-id"], "X-Line-Request-Id");
   });
 
+  describe("validateCustomAggregationUnits", () => {
+    it("should validate correctly when input is valid", () => {
+      const units = ["promotion_A1"];
+      const result = client.validateCustomAggregationUnits(units);
+      strictEqual(result.valid, true);
+      strictEqual(result.messages.length, 0);
+    });
+
+    it("should return invalid when there is more than one unit", () => {
+      const units = ["promotion_A1", "promotion_A2"];
+      const result = client.validateCustomAggregationUnits(units);
+      strictEqual(result.valid, false);
+      strictEqual(
+        result.messages[0],
+        "customAggregationUnits can only contain one unit",
+      );
+    });
+
+    it("should return invalid when a unit has more than 30 characters", () => {
+      const units = ["promotion_A1_with_a_very_long_name"];
+      const result = client.validateCustomAggregationUnits(units);
+      strictEqual(result.valid, false);
+      strictEqual(
+        result.messages[0],
+        "customAggregationUnits[0] must be less than or equal to 30 characters",
+      );
+    });
+
+    it("should return invalid when a unit has invalid characters", () => {
+      const units = ["promotion_A1!"];
+      const result = client.validateCustomAggregationUnits(units);
+      strictEqual(result.valid, false);
+      strictEqual(
+        result.messages[0],
+        "customAggregationUnits[0] must be alphanumeric characters or underscores",
+      );
+    });
+  });
+
   it("getProfile", async () => {
     const scope = mockGet(MESSAGING_API_PREFIX, "/profile/test_user_id");