Repository: line/line-bot-sdk-go
Pull request #417 (2024-01-27 15:02:40)

bugfix: can't add multiple query-params
The generated client has never sent more than 1 query-parameter to LINE api. This is because the generated client keeps overriding the `query` variable for every query-parameters an endpoint has.

I raised this MR to fix this issue by using `url.Values.Add(..., ...)` method instead.

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/line/line-bot-sdk-go/pull/417?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`247a707`)](https://app.codecov.io/gh/line/line-bot-sdk-go/commit/247a7071922cbfa6a64e4207187d0a1ea43c3fe0?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line) 55.19% compared to head [(`fcac8f4`)](https://app.codecov.io/gh/line/line-bot-sdk-go/pull/417?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line) 55.19%.
> Report is 1 commits behind head on master.

> :exclamation: Current head fcac8f4 differs from pull request most recent head 657aa02. Consider uploading reports for the commit 657aa02 to get more accurate results


<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master     #417   +/-   ##
=======================================
  Coverage   55.19%   55.19%           
=======================================
  Files          87       87           
  Lines        5479     5479           
=======================================
  Hits         3024     3024           
  Misses       2233     2233           
  Partials      222      222           
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/line/line-bot-sdk-go/pull/417?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line).


Patch:
diff --git a/.github/workflows/generated-code.yml b/.github/workflows/generated-code.yml
index d67390f..95b72fd 100644
--- a/.github/workflows/generated-code.yml
+++ b/.github/workflows/generated-code.yml
@@ -15,6 +15,8 @@ jobs:
         uses: actions/checkout@v4
         with:
           submodules: recursive
+      - name: Update submodules
+        run: git submodule update --remote --recursive
 
       - name: Set up Python
         uses: actions/setup-python@v5
diff --git a/generator/pom.xml b/generator/pom.xml
index e8f5390..86b6358 100644
--- a/generator/pom.xml
+++ b/generator/pom.xml
@@ -107,7 +107,7 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-shade-plugin</artifactId>
-                <version>3.5.1</version>
+                <version>3.5.2</version>
                 <executions>
                     <execution>
                         <phase>package</phase>
@@ -134,19 +134,19 @@
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-api</artifactId>
-            <version>5.10.1</version>
+            <version>5.10.2</version>
             <scope>test</scope>
         </dependency>
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter-engine</artifactId>
-            <version>5.10.1</version>
+            <version>5.10.2</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <openapi-generator-version>7.2.0</openapi-generator-version>
+        <openapi-generator-version>7.3.0</openapi-generator-version>
         <maven-plugin-version>1.0.0</maven-plugin-version>
     </properties>
 </project>
diff --git a/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble b/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble
index f1d4134..74b1251 100644
--- a/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble
+++ b/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble
@@ -266,9 +266,9 @@ func (client *{{ classname }}) {{ op.operationId }}WithHttpInfo(
     {% endfor %}
 
     {% if op.hasQueryParams -%}
-	var query url.Values
+	query := url.Values{}
 	    {% for qp in op.queryParams -%}
-    query = url.Values{"{{ qp.paramName }}": []string{ {{ stringify(qp) }} }}
+    query.Add("{{ qp.paramName }}", {{ stringify(qp) }})
 	    {% endfor %}
     req.URL.RawQuery = query.Encode()
     {% endif %}
diff --git a/line-openapi b/line-openapi
index 310a504..4c9ddf3 160000
--- a/line-openapi
+++ b/line-openapi
@@ -1,1 +1,1 @@
-Subproject commit 310a504c44246176989edc052f2a21db9e531668
+Subproject commit 4c9ddf30b3507d20c620b8f644d0ad7ea8112110
diff --git a/linebot/channel_access_token/api_channel_access_token.go b/linebot/channel_access_token/api_channel_access_token.go
index 6381f7f..2bd4736 100644
--- a/linebot/channel_access_token/api_channel_access_token.go
+++ b/linebot/channel_access_token/api_channel_access_token.go
@@ -151,9 +151,9 @@ func (client *ChannelAccessTokenAPI) GetsAllValidChannelAccessTokenKeyIdsWithHtt
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"clientAssertionType": []string{clientAssertionType}}
-	query = url.Values{"clientAssertion": []string{clientAssertion}}
+	query := url.Values{}
+	query.Add("clientAssertionType", clientAssertionType)
+	query.Add("clientAssertion", clientAssertion)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -741,8 +741,8 @@ func (client *ChannelAccessTokenAPI) VerifyChannelTokenByJWTWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"accessToken": []string{accessToken}}
+	query := url.Values{}
+	query.Add("accessToken", accessToken)
 
 	req.URL.RawQuery = query.Encode()
 
diff --git a/linebot/insight/api_insight.go b/linebot/insight/api_insight.go
index 5b15b23..7f997e2 100644
--- a/linebot/insight/api_insight.go
+++ b/linebot/insight/api_insight.go
@@ -206,8 +206,8 @@ func (client *InsightAPI) GetMessageEventWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"requestId": []string{requestId}}
+	query := url.Values{}
+	query.Add("requestId", requestId)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -277,8 +277,8 @@ func (client *InsightAPI) GetNumberOfFollowersWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -348,8 +348,8 @@ func (client *InsightAPI) GetNumberOfMessageDeliveriesWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -435,10 +435,10 @@ func (client *InsightAPI) GetStatisticsPerUnitWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"customAggregationUnit": []string{customAggregationUnit}}
-	query = url.Values{"from": []string{from}}
-	query = url.Values{"to": []string{to}}
+	query := url.Values{}
+	query.Add("customAggregationUnit", customAggregationUnit)
+	query.Add("from", from)
+	query.Add("to", to)
 
 	req.URL.RawQuery = query.Encode()
 
diff --git a/linebot/manage_audience/api_manage_audience.go b/linebot/manage_audience/api_manage_audience.go
index 1e553e5..da1d7cc 100644
--- a/linebot/manage_audience/api_manage_audience.go
+++ b/linebot/manage_audience/api_manage_audience.go
@@ -725,13 +725,13 @@ func (client *ManageAudienceAPI) GetAudienceGroupsWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"page": []string{strconv.FormatInt(page, 10)}}
-	query = url.Values{"description": []string{description}}
-	query = url.Values{"status": []string{string(status)}}
-	query = url.Values{"size": []string{strconv.FormatInt(size, 10)}}
-	query = url.Values{"includesExternalPublicGroups": []string{strconv.FormatBool(includesExternalPublicGroups)}}
-	query = url.Values{"createRoute": []string{string(createRoute)}}
+	query := url.Values{}
+	query.Add("page", strconv.FormatInt(page, 10))
+	query.Add("description", description)
+	query.Add("status", string(status))
+	query.Add("size", strconv.FormatInt(size, 10))
+	query.Add("includesExternalPublicGroups", strconv.FormatBool(includesExternalPublicGroups))
+	query.Add("createRoute", string(createRoute))
 
 	req.URL.RawQuery = query.Encode()
 
diff --git a/linebot/messaging_api/.openapi-generator/FILES b/linebot/messaging_api/.openapi-generator/FILES
index bc4223a..f005d19 100644
--- a/linebot/messaging_api/.openapi-generator/FILES
+++ b/linebot/messaging_api/.openapi-generator/FILES
@@ -19,6 +19,8 @@ model_camera_roll_action.go
 model_carousel_column.go
 model_carousel_template.go
 model_chat_reference.go
+model_clipboard_action.go
+model_clipboard_imagemap_action.go
 model_confirm_template.go
 model_create_rich_menu_alias_request.go
 model_datetime_picker_action.go
diff --git a/linebot/messaging_api/api_messaging_api.go b/linebot/messaging_api/api_messaging_api.go
index d859ae3..6cc4baa 100644
--- a/linebot/messaging_api/api_messaging_api.go
+++ b/linebot/messaging_api/api_messaging_api.go
@@ -617,8 +617,8 @@ func (client *MessagingApiAPI) GetAdPhoneMessageStatisticsWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -696,9 +696,9 @@ func (client *MessagingApiAPI) GetAggregationUnitNameListWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"limit": []string{limit}}
-	query = url.Values{"start": []string{start}}
+	query := url.Values{}
+	query.Add("limit", limit)
+	query.Add("start", start)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -935,9 +935,9 @@ func (client *MessagingApiAPI) GetFollowersWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"start": []string{start}}
-	query = url.Values{"limit": []string{strconv.FormatInt(int64(limit), 10)}}
+	query := url.Values{}
+	query.Add("start", start)
+	query.Add("limit", strconv.FormatInt(int64(limit), 10))
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1163,8 +1163,8 @@ func (client *MessagingApiAPI) GetGroupMembersIdsWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"start": []string{start}}
+	query := url.Values{}
+	query.Add("start", start)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1408,8 +1408,8 @@ func (client *MessagingApiAPI) GetNarrowcastProgressWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"requestId": []string{requestId}}
+	query := url.Values{}
+	query.Add("requestId", requestId)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1479,8 +1479,8 @@ func (client *MessagingApiAPI) GetNumberOfSentBroadcastMessagesWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1550,8 +1550,8 @@ func (client *MessagingApiAPI) GetNumberOfSentMulticastMessagesWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1621,8 +1621,8 @@ func (client *MessagingApiAPI) GetNumberOfSentPushMessagesWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1692,8 +1692,8 @@ func (client *MessagingApiAPI) GetNumberOfSentReplyMessagesWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -1763,8 +1763,8 @@ func (client *MessagingApiAPI) GetPNPMessageStatisticsWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"date": []string{date}}
+	query := url.Values{}
+	query.Add("date", date)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -2091,8 +2091,8 @@ func (client *MessagingApiAPI) GetRichMenuBatchProgressWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"requestId": []string{requestId}}
+	query := url.Values{}
+	query.Add("requestId", requestId)
 
 	req.URL.RawQuery = query.Encode()
 
@@ -2439,8 +2439,8 @@ func (client *MessagingApiAPI) GetRoomMembersIdsWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"start": []string{start}}
+	query := url.Values{}
+	query.Add("start", start)
 
 	req.URL.RawQuery = query.Encode()
 
diff --git a/linebot/messaging_api/model_action.go b/linebot/messaging_api/model_action.go
index b47ace2..2c58185 100644
--- a/linebot/messaging_api/model_action.go
+++ b/linebot/messaging_api/model_action.go
@@ -64,6 +64,16 @@ func setDiscriminatorPropertyAction(r ActionInterface) ActionInterface {
 			v.Type = "cameraRoll"
 		}
 		return v
+	case *ClipboardAction:
+		if v.Type == "" {
+			v.Type = "clipboard"
+		}
+		return v
+	case ClipboardAction:
+		if v.Type == "" {
+			v.Type = "clipboard"
+		}
+		return v
 	case *DatetimePickerAction:
 		if v.Type == "" {
 			v.Type = "datetimepicker"
@@ -170,6 +180,12 @@ func UnmarshalAction(data []byte) (ActionInterface, error) {
 			return nil, fmt.Errorf("UnmarshalAction: Cannot read cameraRoll: %w", err)
 		}
 		return cameraRoll, nil
+	case "clipboard":
+		var clipboard ClipboardAction
+		if err := json.Unmarshal(data, &clipboard); err != nil {
+			return nil, fmt.Errorf("UnmarshalAction: Cannot read clipboard: %w", err)
+		}
+		return clipboard, nil
 	case "datetimepicker":
 		var datetimepicker DatetimePickerAction
 		if err := json.Unmarshal(data, &datetimepicker); err != nil {
diff --git a/linebot/messaging_api/model_clipboard_action.go b/linebot/messaging_api/model_clipboard_action.go
new file mode 100644
index 0000000..9e8a4b1
--- /dev/null
+++ b/linebot/messaging_api/model_clipboard_action.go
@@ -0,0 +1,56 @@
+/**
+ * LINE Messaging API
+ * This document describes LINE Messaging API.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+//go:generate python3 ../../generate-code.py
+package messaging_api
+
+import (
+	"encoding/json"
+)
+
+// ClipboardAction
+// ClipboardAction
+// https://developers.line.biz/en/reference/messaging-api/#clipboard-action
+type ClipboardAction struct {
+	Action
+
+	/**
+	 * Label for the action.
+	 */
+	Label string `json:"label,omitempty"`
+
+	/**
+	 * Text that is copied to the clipboard. Max character limit: 1000  (Required)
+	 */
+	ClipboardText string `json:"clipboardText"`
+}
+
+// MarshalJSON customizes the JSON serialization of the ClipboardAction struct.
+func (r *ClipboardAction) MarshalJSON() ([]byte, error) {
+
+	type Alias ClipboardAction
+	return json.Marshal(&struct {
+		*Alias
+
+		Type string `json:"type,omitempty"`
+	}{
+		Alias: (*Alias)(r),
+
+		Type: "clipboard",
+	})
+}
diff --git a/linebot/messaging_api/model_clipboard_imagemap_action.go b/linebot/messaging_api/model_clipboard_imagemap_action.go
new file mode 100644
index 0000000..7610398
--- /dev/null
+++ b/linebot/messaging_api/model_clipboard_imagemap_action.go
@@ -0,0 +1,61 @@
+/**
+ * LINE Messaging API
+ * This document describes LINE Messaging API.
+ *
+ * The version of the OpenAPI document: 0.0.1
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+//go:generate python3 ../../generate-code.py
+package messaging_api
+
+import (
+	"encoding/json"
+)
+
+// ClipboardImagemapAction
+// ClipboardImagemapAction
+// https://developers.line.biz/en/reference/messaging-api/#imagemap-clipboard-action-object
+type ClipboardImagemapAction struct {
+	ImagemapAction
+
+	/**
+	 * Get Area
+	 */
+	Area *ImagemapArea `json:"area"`
+
+	/**
+	 * Text that is copied to the clipboard. Max character limit: 1000  (Required)
+	 */
+	ClipboardText string `json:"clipboardText"`
+
+	/**
+	 * Get Label
+	 */
+	Label string `json:"label,omitempty"`
+}
+
+// MarshalJSON customizes the JSON serialization of the ClipboardImagemapAction struct.
+func (r *ClipboardImagemapAction) MarshalJSON() ([]byte, error) {
+
+	type Alias ClipboardImagemapAction
+	return json.Marshal(&struct {
+		*Alias
+
+		Type string `json:"type"`
+	}{
+		Alias: (*Alias)(r),
+
+		Type: "clipboard",
+	})
+}
diff --git a/linebot/messaging_api/model_imagemap_action.go b/linebot/messaging_api/model_imagemap_action.go
index 89cf8cc..771b388 100644
--- a/linebot/messaging_api/model_imagemap_action.go
+++ b/linebot/messaging_api/model_imagemap_action.go
@@ -44,6 +44,16 @@ func (e UnknownImagemapAction) GetType() string {
 
 func setDiscriminatorPropertyImagemapAction(r ImagemapActionInterface) ImagemapActionInterface {
 	switch v := r.(type) {
+	case *ClipboardImagemapAction:
+		if v.Type == "" {
+			v.Type = "clipboard"
+		}
+		return v
+	case ClipboardImagemapAction:
+		if v.Type == "" {
+			v.Type = "clipboard"
+		}
+		return v
 	case *MessageImagemapAction:
 		if v.Type == "" {
 			v.Type = "message"
@@ -94,6 +104,12 @@ func UnmarshalImagemapAction(data []byte) (ImagemapActionInterface, error) {
 	}
 
 	switch discriminator {
+	case "clipboard":
+		var clipboard ClipboardImagemapAction
+		if err := json.Unmarshal(data, &clipboard); err != nil {
+			return nil, fmt.Errorf("UnmarshalImagemapAction: Cannot read clipboard: %w", err)
+		}
+		return clipboard, nil
 	case "message":
 		var message MessageImagemapAction
 		if err := json.Unmarshal(data, &message); err != nil {
diff --git a/linebot/module/api_line_module.go b/linebot/module/api_line_module.go
index 0aef472..370ef2d 100644
--- a/linebot/module/api_line_module.go
+++ b/linebot/module/api_line_module.go
@@ -307,9 +307,9 @@ func (client *LineModuleAPI) GetModulesWithHttpInfo(
 		return nil, nil, err
 	}
 
-	var query url.Values
-	query = url.Values{"start": []string{start}}
-	query = url.Values{"limit": []string{strconv.FormatInt(int64(limit), 10)}}
+	query := url.Values{}
+	query.Add("start", start)
+	query.Add("limit", strconv.FormatInt(int64(limit), 10))
 
 	req.URL.RawQuery = query.Encode()
 
diff --git a/linebot/version.go b/linebot/version.go
index eb22cc5..8b7203a 100644
--- a/linebot/version.go
+++ b/linebot/version.go
@@ -16,7 +16,7 @@
 
 package linebot
 
-const version = "8.2.1"
+const version = "8.4.0"
 
 func GetVersion() string {
 	return version
diff --git a/linebot/webhook/.openapi-generator/FILES b/linebot/webhook/.openapi-generator/FILES
index ebc9d6c..8109415 100644
--- a/linebot/webhook/.openapi-generator/FILES
+++ b/linebot/webhook/.openapi-generator/FILES
@@ -18,6 +18,7 @@ model_emoji.go
 model_event.go
 model_event_mode.go
 model_file_message_content.go
+model_follow_detail.go
 model_follow_event.go
 model_group_source.go
 model_image_message_content.go
diff --git a/linebot/webhook/model_follow_detail.go b/linebot/webhook/model_follow_detail.go
new file mode 100644
index 0000000..5495bfd
--- /dev/null
+++ b/linebot/webhook/model_follow_detail.go
@@ -0,0 +1,31 @@
+/**
+ * Webhook Type Definition
+ * Webhook event definition of the LINE Messaging API
+ *
+ * The version of the OpenAPI document: 1.0.0
+ *
+ *
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+/**
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
+ * https://openapi-generator.tech
+ * Do not edit the class manually.
+ */
+
+//go:generate python3 ../../generate-code.py
+package webhook
+
+// FollowDetail
+// FollowDetail
+
+type FollowDetail struct {
+
+	/**
+	 * Whether a user has added your LINE Official Account as a friend or unblocked. (Required)
+	 */
+	IsUnblocked bool `json:"isUnblocked"`
+}
diff --git a/linebot/webhook/model_follow_event.go b/linebot/webhook/model_follow_event.go
index ff6a703..0f208ec 100644
--- a/linebot/webhook/model_follow_event.go
+++ b/linebot/webhook/model_follow_event.go
@@ -59,6 +59,11 @@ type FollowEvent struct {
 	 * Reply token used to send reply message to this event (Required)
 	 */
 	ReplyToken string `json:"replyToken"`
+
+	/**
+	 * Get Follow
+	 */
+	Follow *FollowDetail `json:"follow"`
 }
 
 func (cr *FollowEvent) UnmarshalJSON(data []byte) error {
@@ -134,6 +139,15 @@ func (cr *FollowEvent) UnmarshalJSON(data []byte) error {
 
 	}
 
+	if raw["follow"] != nil {
+
+		err = json.Unmarshal(raw["follow"], &cr.Follow)
+		if err != nil {
+			return fmt.Errorf("JSON parse error in FollowDetail(Follow): %w", err)
+		}
+
+	}
+
 	return nil
 }
 


Test patch:
diff --git a/linebot/messaging_api/tests/handwritten/api_GetFollowers_test.go b/linebot/messaging_api/tests/handwritten/api_GetFollowers_test.go
index 231c991..6dcbedc 100644
--- a/linebot/messaging_api/tests/handwritten/api_GetFollowers_test.go
+++ b/linebot/messaging_api/tests/handwritten/api_GetFollowers_test.go
@@ -3,7 +3,6 @@ package tests
 import (
 	"encoding/json"
 	"fmt"
-	"log"
 	"net/http"
 	"net/http/httptest"
 	"testing"
@@ -11,16 +10,23 @@ import (
 	"github.com/line/line-bot-sdk-go/v8/linebot/messaging_api"
 )
 
-func TestGetFollowers_ItShouldCorrectlyPassLimitQueryParameter(t *testing.T) {
+func TestGetFollowers_ItShouldCorrectlyPassLimitAndStartQueryParameter(t *testing.T) {
 	expectedLimit := "1000"
+	expectedStart := "some-start"
 	server := httptest.NewServer(
 		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 			gotLimit := r.URL.Query().Get("limit")
+			gotStart := r.URL.Query().Get("start")
 			if gotLimit != expectedLimit {
 				w.Header().Set("TEST-ERROR", fmt.Sprintf("incorrect limit being sent from client. expected %s, got %s", expectedLimit, gotLimit))
 				w.WriteHeader(http.StatusInternalServerError)
 				return
 			}
+			if gotStart != expectedStart {
+				w.Header().Set("TEST-ERROR", fmt.Sprintf("incorrect start being sent from client. expected %s, got %s", expectedStart, gotStart))
+				w.WriteHeader(http.StatusInternalServerError)
+				return
+			}
 			json.NewEncoder(w).Encode(messaging_api.GetFollowersResponse{UserIds: []string{}, Next: "abcdef"})
 		}),
 	)
@@ -31,11 +37,7 @@ func TestGetFollowers_ItShouldCorrectlyPassLimitQueryParameter(t *testing.T) {
 	if err != nil {
 		t.Fatalf("Failed to create client: %v", err)
 	}
-	resp, _, err := client.GetFollowersWithHttpInfo("", 1000)
-	if err != nil {
-		t.Fatalf("Failed to get followers: %v", err)
-	}
-	log.Printf("Got response: %v", resp)
+	resp, _, _ := client.GetFollowersWithHttpInfo("some-start", 1000)
 	if resp.StatusCode != http.StatusOK {
 		t.Errorf("Not getting 200 response back: %s", resp.Header.Get("TEST-ERROR"))
 	}