diff --git a/README.md b/README.md index 9b34f6a6..5e5b13b3 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ import ( "github.com/line/line-bot-sdk-go/v8/linebot/liff" "github.com/line/line-bot-sdk-go/v8/linebot/manage_audience" "github.com/line/line-bot-sdk-go/v8/linebot/messaging_api" + "github.com/line/line-bot-sdk-go/v8/linebot/membership" "github.com/line/line-bot-sdk-go/v8/linebot/module" "github.com/line/line-bot-sdk-go/v8/linebot/module_attach" "github.com/line/line-bot-sdk-go/v8/linebot/shop" diff --git a/generate-code.py b/generate-code.py index f24db9b2..e0a0655a 100644 --- a/generate-code.py +++ b/generate-code.py @@ -53,6 +53,7 @@ def generate_clients(): "module-attach.yml", "module.yml", "messaging-api.yml", + "membership.yml", ] for sourceYaml in components: diff --git a/linebot/membership/.openapi-generator-ignore b/linebot/membership/.openapi-generator-ignore new file mode 100644 index 00000000..7484ee59 --- /dev/null +++ b/linebot/membership/.openapi-generator-ignore @@ -0,0 +1,23 @@ +# OpenAPI Generator Ignore +# Generated by openapi-generator https://github.com/openapitools/openapi-generator + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/linebot/membership/.openapi-generator/FILES b/linebot/membership/.openapi-generator/FILES new file mode 100644 index 00000000..43257873 --- /dev/null +++ b/linebot/membership/.openapi-generator/FILES @@ -0,0 +1,8 @@ +api_membership.go +model_error_response.go +model_get_membership_subscription_response.go +model_membership.go +model_membership_list_response.go +model_membership_meta.go +model_membership_user.go +model_subscription.go diff --git a/linebot/membership/.openapi-generator/VERSION b/linebot/membership/.openapi-generator/VERSION new file mode 100644 index 00000000..41225218 --- /dev/null +++ b/linebot/membership/.openapi-generator/VERSION @@ -0,0 +1 @@ +7.0.0 \ No newline at end of file diff --git a/linebot/membership/api_membership.go b/linebot/membership/api_membership.go new file mode 100644 index 00000000..113c6422 --- /dev/null +++ b/linebot/membership/api_membership.go @@ -0,0 +1,237 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "path" + "strings" + + "github.com/line/line-bot-sdk-go/v8/linebot" +) + +type MembershipAPI struct { + httpClient *http.Client + endpoint *url.URL + channelToken string + ctx context.Context +} + +// MembershipAPIOption type +type MembershipAPIOption func(*MembershipAPI) error + +// New returns a new bot client instance. +func NewMembershipAPI(channelToken string, options ...MembershipAPIOption) (*MembershipAPI, error) { + if channelToken == "" { + return nil, errors.New("missing channel access token") + } + + c := &MembershipAPI{ + channelToken: channelToken, + httpClient: http.DefaultClient, + } + + u, err := url.ParseRequestURI("https://api.line.me") + if err != nil { + return nil, err + } + c.endpoint = u + + for _, option := range options { + err := option(c) + if err != nil { + return nil, err + } + } + return c, nil +} + +// WithContext method +func (call *MembershipAPI) WithContext(ctx context.Context) *MembershipAPI { + call.ctx = ctx + return call +} + +func (client *MembershipAPI) Do(req *http.Request) (*http.Response, error) { + if client.channelToken != "" { + req.Header.Set("Authorization", "Bearer "+client.channelToken) + } + req.Header.Set("User-Agent", "LINE-BotSDK-Go/"+linebot.GetVersion()) + if client.ctx != nil { + req = req.WithContext(client.ctx) + } + return client.httpClient.Do(req) +} + +func (client *MembershipAPI) Url(endpointPath string) string { + newPath := path.Join(client.endpoint.Path, endpointPath) + u := *client.endpoint + u.Path = newPath + return u.String() +} + +// WithHTTPClient function +func WithHTTPClient(c *http.Client) MembershipAPIOption { + return func(client *MembershipAPI) error { + client.httpClient = c + return nil + } +} + +// WithEndpointClient function +func WithEndpoint(endpoint string) MembershipAPIOption { + return func(client *MembershipAPI) error { + u, err := url.ParseRequestURI(endpoint) + if err != nil { + return err + } + client.endpoint = u + return nil + } +} + +// GetMembershipList +// +// Get a list of memberships. +// Parameters: + +// https://developers.line.biz/en/reference/messaging-api/#get-membership-plans +func (client *MembershipAPI) GetMembershipList() (*MembershipListResponse, error) { + _, body, error := client.GetMembershipListWithHttpInfo() + return body, error +} + +// GetMembershipList +// If you want to take advantage of the HTTPResponse object for status codes and headers, use this signature. +// +// Get a list of memberships. +// Parameters: + +// https://developers.line.biz/en/reference/messaging-api/#get-membership-plans +func (client *MembershipAPI) GetMembershipListWithHttpInfo() (*http.Response, *MembershipListResponse, error) { + path := "/membership/v1/list" + + req, err := http.NewRequest(http.MethodGet, client.Url(path), nil) + if err != nil { + return nil, nil, err + } + + res, err := client.Do(req) + + if err != nil { + return res, nil, err + } + + if res.StatusCode/100 != 2 { + bodyBytes, err := io.ReadAll(res.Body) + bodyReader := bytes.NewReader(bodyBytes) + if err != nil { + return res, nil, fmt.Errorf("failed to read response body: %w", err) + } + res.Body = io.NopCloser(bodyReader) + return res, nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, string(bodyBytes)) + } + + defer res.Body.Close() + + decoder := json.NewDecoder(res.Body) + result := MembershipListResponse{} + if err := decoder.Decode(&result); err != nil { + return res, nil, fmt.Errorf("failed to decode JSON: %w", err) + } + return res, &result, nil + +} + +// GetMembershipSubscription +// +// Get a user's membership subscription. +// Parameters: +// userId User ID + +// https://developers.line.biz/en/reference/messaging-api/#get-a-users-membership-subscription-status +func (client *MembershipAPI) GetMembershipSubscription( + + userId string, + +) (*GetMembershipSubscriptionResponse, error) { + _, body, error := client.GetMembershipSubscriptionWithHttpInfo( + + userId, + ) + return body, error +} + +// GetMembershipSubscription +// If you want to take advantage of the HTTPResponse object for status codes and headers, use this signature. +// +// Get a user's membership subscription. +// Parameters: +// userId User ID + +// https://developers.line.biz/en/reference/messaging-api/#get-a-users-membership-subscription-status +func (client *MembershipAPI) GetMembershipSubscriptionWithHttpInfo( + + userId string, + +) (*http.Response, *GetMembershipSubscriptionResponse, error) { + path := "/membership/v1/subscription/{userId}" + + path = strings.Replace(path, "{userId}", userId, -1) + + req, err := http.NewRequest(http.MethodGet, client.Url(path), nil) + if err != nil { + return nil, nil, err + } + + res, err := client.Do(req) + + if err != nil { + return res, nil, err + } + + if res.StatusCode/100 != 2 { + bodyBytes, err := io.ReadAll(res.Body) + bodyReader := bytes.NewReader(bodyBytes) + if err != nil { + return res, nil, fmt.Errorf("failed to read response body: %w", err) + } + res.Body = io.NopCloser(bodyReader) + return res, nil, fmt.Errorf("unexpected status code: %d, %s", res.StatusCode, string(bodyBytes)) + } + + defer res.Body.Close() + + decoder := json.NewDecoder(res.Body) + result := GetMembershipSubscriptionResponse{} + if err := decoder.Decode(&result); err != nil { + return res, nil, fmt.Errorf("failed to decode JSON: %w", err) + } + return res, &result, nil + +} diff --git a/linebot/membership/model_error_response.go b/linebot/membership/model_error_response.go new file mode 100644 index 00000000..a696d84e --- /dev/null +++ b/linebot/membership/model_error_response.go @@ -0,0 +1,36 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// ErrorResponse +// ErrorResponse + +type ErrorResponse struct { + + /** + * Error message (Required) + */ + Message string `json:"message"` + + /** + * Get Details + */ + Details []string `json:"details"` +} diff --git a/linebot/membership/model_get_membership_subscription_response.go b/linebot/membership/model_get_membership_subscription_response.go new file mode 100644 index 00000000..28d90687 --- /dev/null +++ b/linebot/membership/model_get_membership_subscription_response.go @@ -0,0 +1,31 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// GetMembershipSubscriptionResponse +// A user's membership subscription status +// https://developers.line.biz/en/reference/messaging-api/#get-a-users-membership-subscription-status +type GetMembershipSubscriptionResponse struct { + + /** + * List of subscription information (Required) + */ + Subscriptions []Subscription `json:"subscriptions"` +} diff --git a/linebot/membership/model_membership.go b/linebot/membership/model_membership.go new file mode 100644 index 00000000..925ae56a --- /dev/null +++ b/linebot/membership/model_membership.go @@ -0,0 +1,89 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// Membership +// Membership + +type Membership struct { + + /** + * Membership plan ID. (Required) + */ + MembershipId int32 `json:"membershipId"` + + /** + * Membership plan name. (Required) + */ + Title string `json:"title"` + + /** + * Membership plan description. (Required) + */ + Description string `json:"description"` + + /** + * List of membership plan perks. (Required) + */ + Benefits []string `json:"benefits"` + + /** + * Monthly fee for membership plan. (e.g. 1500.00) (Required) + */ + Price float64 `json:"price"` + + /** + * The currency of membership.price. (Required) + */ + Currency MembershipCURRENCY `json:"currency"` + + /** + * Number of members subscribed to the membership plan. (Required) + */ + MemberCount int32 `json:"memberCount"` + + /** + * The upper limit of members who can subscribe. If no upper limit is set, it will be null. (Required) + */ + MemberLimit int32 `json:"memberLimit"` + + /** + * Payment method for users who subscribe to a membership plan. (Required) + */ + IsInAppPurchase bool `json:"isInAppPurchase"` + + /** + * Membership plan status. (Required) + */ + IsPublished bool `json:"isPublished"` +} + +// MembershipCURRENCY type +/* The currency of membership.price. */ +type MembershipCURRENCY string + +// MembershipCURRENCY constants +const ( + MembershipCURRENCY_JPY MembershipCURRENCY = "JPY" + + MembershipCURRENCY_TWD MembershipCURRENCY = "TWD" + + MembershipCURRENCY_THB MembershipCURRENCY = "THB" +) diff --git a/linebot/membership/model_membership_list_response.go b/linebot/membership/model_membership_list_response.go new file mode 100644 index 00000000..a3e797fe --- /dev/null +++ b/linebot/membership/model_membership_list_response.go @@ -0,0 +1,31 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// MembershipListResponse +// List of memberships + +type MembershipListResponse struct { + + /** + * List of membership information (Required) + */ + Memberships []Membership `json:"memberships"` +} diff --git a/linebot/membership/model_membership_meta.go b/linebot/membership/model_membership_meta.go new file mode 100644 index 00000000..39496879 --- /dev/null +++ b/linebot/membership/model_membership_meta.go @@ -0,0 +1,69 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// MembershipMeta +// Object containing information about the membership plan. + +type MembershipMeta struct { + + /** + * Membership plan ID. (Required) + */ + MembershipId int32 `json:"membershipId"` + + /** + * Membership plan name. (Required) + */ + Title string `json:"title"` + + /** + * Membership plan description. (Required) + */ + Description string `json:"description"` + + /** + * List of membership plan perks. (Required) + */ + Benefits []string `json:"benefits"` + + /** + * Monthly fee for membership plan. (e.g. 1500.00) (Required) + */ + Price float64 `json:"price"` + + /** + * The currency of membership.price. (Required) + */ + Currency MembershipMetaCURRENCY `json:"currency"` +} + +// MembershipMetaCURRENCY type +/* The currency of membership.price. */ +type MembershipMetaCURRENCY string + +// MembershipMetaCURRENCY constants +const ( + MembershipMetaCURRENCY_JPY MembershipMetaCURRENCY = "JPY" + + MembershipMetaCURRENCY_TWD MembershipMetaCURRENCY = "TWD" + + MembershipMetaCURRENCY_THB MembershipMetaCURRENCY = "THB" +) diff --git a/linebot/membership/model_membership_user.go b/linebot/membership/model_membership_user.go new file mode 100644 index 00000000..9315eb5a --- /dev/null +++ b/linebot/membership/model_membership_user.go @@ -0,0 +1,46 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// MembershipUser +// Object containing user membership subscription information. + +type MembershipUser struct { + + /** + * The user's member number in the membership plan. (Required) + */ + MembershipNo int32 `json:"membershipNo"` + + /** + * UNIX timestamp at which the user subscribed to the membership. (Required) + */ + JoinedTime int32 `json:"joinedTime"` + + /** + * Next payment date for membership plan. - Format: yyyy-MM-dd (e.g. 2024-02-08) - Timezone: UTC+9 (Required) + */ + NextBillingDate string `json:"nextBillingDate"` + + /** + * The period of time in months that the user has been subscribed to a membership plan. If a user previously canceled and then re-subscribed to the same membership plan, only the period after the re-subscription will be counted. (Required) + */ + TotalSubscriptionMonths int32 `json:"totalSubscriptionMonths"` +} diff --git a/linebot/membership/model_subscription.go b/linebot/membership/model_subscription.go new file mode 100644 index 00000000..9e8d5129 --- /dev/null +++ b/linebot/membership/model_subscription.go @@ -0,0 +1,36 @@ +/** + * Membership API + * This document describes LINE Official Account Membership 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 membership + +// Subscription +// An array of memberships. + +type Subscription struct { + + /** + * Get Membership + */ + Membership *MembershipMeta `json:"membership"` + + /** + * Get User + */ + User *MembershipUser `json:"user"` +} diff --git a/linebot/membership/tests/api/api_membership_test_test.go b/linebot/membership/tests/api/api_membership_test_test.go new file mode 100644 index 00000000..cf615df2 --- /dev/null +++ b/linebot/membership/tests/api/api_membership_test_test.go @@ -0,0 +1,69 @@ +package tests + +import ( + "crypto/rand" + "fmt" + "io" + "log" + "net/http" + "net/http/httptest" + "os" + "strings" + "testing" + + "github.com/line/line-bot-sdk-go/v8/linebot/membership" +) + + +func TestGetMembershipList(t *testing.T) { + server := httptest.NewServer( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + + w.WriteHeader(http.StatusOK) + w.Write([]byte("{}")) + }), + ) + + client, err := membership.NewMembershipAPI( + "MY_CHANNEL_TOKEN", + membership.WithEndpoint(server.URL), + ) + if err != nil { + t.Fatalf("Failed to create client: %v", err) + } + resp, err := client.GetMembershipList( + + ) + if err != nil { + t.Fatalf("Failed to call API: %v", err) + } +} + +func TestGetMembershipSubscription(t *testing.T) { + server := httptest.NewServer( + http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + + + w.WriteHeader(http.StatusOK) + w.Write([]byte("{}")) + }), + ) + + client, err := membership.NewMembershipAPI( + "MY_CHANNEL_TOKEN", + membership.WithEndpoint(server.URL), + ) + if err != nil { + t.Fatalf("Failed to create client: %v", err) + } + resp, err := client.GetMembershipSubscription( + "hello", + + + ) + if err != nil { + t.Fatalf("Failed to call API: %v", err) + } +} +