diff --git a/modules/apiact/line.go b/modules/apiact/line.go deleted file mode 100644 index c78f9f2..0000000 --- a/modules/apiact/line.go +++ /dev/null @@ -1,33 +0,0 @@ -package apiact - -import "net/url" - -// Line - -type Line struct { - URL string - APIVersion string - AccessToken string -} - -// NewLineApi - -func NewLineApi(apiVersion string) (line *Line, err error) { - if len(apiVersion) == 0 { - apiVersion = "v2" - } - line = &Line{} - line.URL = "https://api.line.me" - line.APIVersion = apiVersion - return -} - -func (p *Line) getAPIURL(urlPath string) (apiURL string, err error) { - u, err := url.Parse(p.URL) - if err != nil { - return "", err - } - u, err = u.Parse("/v2") - if err != nil { - return "", err - } - return -} diff --git a/modules/apiact/line/line.go b/modules/apiact/line/line.go new file mode 100644 index 0000000..cb68d58 --- /dev/null +++ b/modules/apiact/line/line.go @@ -0,0 +1,238 @@ +package line + +import ( + "bytes" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "path" + + "git.trj.tw/golang/mtgbot/modules/apiact" + "git.trj.tw/golang/mtgbot/modules/config" + jsoniter "github.com/json-iterator/go" +) + +var json = jsoniter.ConfigCompatibleWithStandardLibrary + +// Line - +type Line struct { + URL string + APIVersion string + AccessToken string +} + +// Message - +type Message struct { + Type string `json:"type"` +} + +// TextMessage - +type TextMessage struct { + Message + Text string `json:"text"` +} + +// ImageMessage - +type ImageMessage struct { + Message + OriginalContentURL string `json:"originalContentUrl"` + PreviewImageURL string `json:"previewImageUrl"` +} + +// VideoMessage - +type VideoMessage struct { + Message + OriginalContentURL string `json:"originalContentUrl"` + PreviewImageURL string `json:"previewImageUrl"` +} + +// UserInfo - +type UserInfo struct { + DisplayName string `json:"displayName"` + UserID string `json:"userId"` +} + +type pushBody struct { + To string `json:"to"` + Messages []interface{} `json:"messages"` +} + +type replyBody struct { + ReplyToken string `json:"replyToken"` + Messages []interface{} `json:"messages"` +} + +// NewLineApi - +func NewLineApi(apiVersion string) (line *Line, err error) { + if len(apiVersion) == 0 { + apiVersion = "v2" + } + line = &Line{} + line.URL = "https://api.line.me" + line.APIVersion = apiVersion + + conf := config.GetConf() + + if len(conf.Line.Access) == 0 { + return nil, errors.New("access token is empty") + } + + line.AccessToken = conf.Line.Access + return +} + +func (p *Line) getAPIURL(urlPath string) (apiURL string, err error) { + u, err := url.Parse(p.URL) + if err != nil { + return "", err + } + + u.Path = path.Join(u.Path, p.APIVersion, urlPath) + + return u.String(), nil +} + +func (p *Line) getHeader() (header map[string]string) { + header = make(map[string]string) + + header["Content-Type"] = "application/json" + header["Authorization"] = fmt.Sprintf("Bearer %s", p.AccessToken) + + return +} + +// NewTextMessage - +func NewTextMessage(text string) (msg TextMessage, err error) { + msg = TextMessage{} + if len(text) == 0 { + return msg, errors.New("message is empty") + } + + msg.Type = "text" + msg.Text = text + return +} + +// NewImageMessage - +func NewImageMessage(originalURL, previewURL string) (msg ImageMessage, err error) { + msg = ImageMessage{} + if len(originalURL) == 0 || len(previewURL) == 0 { + return msg, errors.New("original url or preview url is empty") + } + msg.Type = "image" + msg.OriginalContentURL = originalURL + msg.PreviewImageURL = previewURL + return +} + +// NewVideoMessage - +func NewVideoMessage(originalURL, previewURL string) (msg VideoMessage, err error) { + msg = VideoMessage{} + if len(originalURL) == 0 || len(previewURL) == 0 { + return msg, errors.New("original url or preview url is empty") + } + msg.Type = "video" + msg.OriginalContentURL = originalURL + msg.PreviewImageURL = previewURL + return +} + +func checkMessageStruct(msg interface{}) (valid bool) { + switch msg.(type) { + case TextMessage: + case ImageMessage: + case VideoMessage: + return true + } + return false +} + +// PushMessage - +func (p *Line) PushMessage(to string, msg interface{}) (err error) { + if len(to) == 0 { + return errors.New("target is empty") + } + apiURL, err := p.getAPIURL("/bot/message/push") + if err != nil { + return err + } + + if !checkMessageStruct(msg) { + return errors.New("message struct validate fail") + } + + body := &pushBody{To: to} + body.Messages = append(body.Messages, msg) + + dataByte, err := json.Marshal(body) + if err != nil { + return err + } + + dataReader := bytes.NewReader(dataByte) + + resp, err := p.sendAPI(apiURL, "POST", dataReader) + if err != nil { + return err + } + defer resp.Body.Close() + return +} + +// ReplyMessage - +func (p *Line) ReplyMessage(token string, msg interface{}) (err error) { + if len(token) == 0 { + return errors.New("reply token is empty") + } + apiURL, err := p.getAPIURL("/bot/message/reply") + if err != nil { + return err + } + + if !checkMessageStruct(msg) { + return errors.New("message struct validate fail") + } + + body := &replyBody{ReplyToken: token} + body.Messages = append(body.Messages, msg) + + dataByte, err := json.Marshal(body) + if err != nil { + return err + } + + dataReader := bytes.NewReader(dataByte) + + resp, err := p.sendAPI(apiURL, "POST", dataReader) + if err != nil { + return err + } + defer resp.Body.Close() + return +} + +func (p *Line) sendAPI(apiURL, method string, body io.Reader) (resp *http.Response, err error) { + if len(apiURL) == 0 { + return nil, errors.New("api url is empty") + } + + reqObj := apiact.RequestObject{ + Method: method, + URL: apiURL, + Body: body, + Headers: p.getHeader(), + } + req, err := apiact.GetRequest(reqObj) + if err != nil { + return nil, err + } + + resp, err = http.DefaultClient.Do(req) + if err != nil { + return nil, err + } + + return +} diff --git a/modules/apiact/tcgplayer.go b/modules/apiact/tcgplayer/tcgplayer.go similarity index 88% rename from modules/apiact/tcgplayer.go rename to modules/apiact/tcgplayer/tcgplayer.go index 6b98aec..78dacc1 100644 --- a/modules/apiact/tcgplayer.go +++ b/modules/apiact/tcgplayer/tcgplayer.go @@ -1,4 +1,4 @@ -package apiact +package tcgplayer import ( "errors" @@ -11,6 +11,7 @@ import ( "strings" "time" + "git.trj.tw/golang/mtgbot/modules/apiact" "git.trj.tw/golang/mtgbot/modules/config" jsoniter "github.com/json-iterator/go" ) @@ -26,8 +27,8 @@ type TCGPlayer struct { Expire time.Time } -// TCGPlayerAPIRes - -type TCGPlayerAPIRes struct { +// APIRes - +type APIRes struct { Success bool `json:"success"` Errors []string `json:"errors"` Results []map[string]interface{} `json:"results"` @@ -78,13 +79,13 @@ func (p *TCGPlayer) GetToken() (err error) { apiURL, err := p.getAPIURL("/token", false) dataReader := strings.NewReader(fmt.Sprintf("grant_type=client_credentials&client_id=%s&client_secret=%s", conf.TCGPlayer.PublicKey, conf.TCGPlayer.PrivateKey)) - reqObj := RequestObject{} + reqObj := apiact.RequestObject{} reqObj.Method = "POST" reqObj.URL = apiURL reqObj.Body = dataReader reqObj.Headers = p.getHeader() - req, err := GetRequest(reqObj) + req, err := apiact.GetRequest(reqObj) if err != nil { return err } @@ -123,8 +124,8 @@ func (p *TCGPlayer) GetToken() (err error) { return } -// TCGPlayerCategory - -type TCGPlayerCategory struct { +// Category - +type Category struct { CaegoryID int `json:"categoryId"` Name string `json:"name"` DisplayName string `json:"displayName"` @@ -138,14 +139,14 @@ type TCGPlayerCategory struct { } // ListCategory - -func (p *TCGPlayer) ListCategory(limit, offset int) (category []*TCGPlayerCategory, err error) { +func (p *TCGPlayer) ListCategory(limit, offset int) (category []*Category, err error) { apiURL, err := p.getAPIURL("/catalog/categories", true) if err != nil { return nil, err } tmpStruct := struct { TCGPlayerAPIRes - Results []*TCGPlayerCategory `json:"results"` + Results []*Category `json:"results"` }{} if limit < 1 { @@ -161,13 +162,13 @@ func (p *TCGPlayer) ListCategory(limit, offset int) (category []*TCGPlayerCatego apiURL += fmt.Sprintf("?%s", qsVal.Encode()) - reqObj := RequestObject{ + reqObj := apiact.RequestObject{ Method: "GET", Headers: p.getHeader(), URL: apiURL, } - req, err := GetRequest(reqObj) + req, err := apiact.GetRequest(reqObj) if err != nil { return nil, err } @@ -198,8 +199,8 @@ func (p *TCGPlayer) ListCategory(limit, offset int) (category []*TCGPlayerCatego return tmpStruct.Results, nil } -// TCGPlayerCategoryGroup - -type TCGPlayerCategoryGroup struct { +// CategoryGroup - +type CategoryGroup struct { GroupID int `json:"groupId"` Name string `json:"name"` Abbreviation string `json:"abbreviation"` @@ -210,7 +211,7 @@ type TCGPlayerCategoryGroup struct { } // ListCategoryGroups - -func (p *TCGPlayer) ListCategoryGroups(categoryID, limit, offset int) (groups []*TCGPlayerCategoryGroup, err error) { +func (p *TCGPlayer) ListCategoryGroups(categoryID, limit, offset int) (groups []*CategoryGroup, err error) { apiURL, err := p.getAPIURL(fmt.Sprintf("/catalog/categories/%d/groups", categoryID), true) if err != nil { return nil, err @@ -230,18 +231,18 @@ func (p *TCGPlayer) ListCategoryGroups(categoryID, limit, offset int) (groups [] tmpStruct := struct { TCGPlayerAPIRes - TotalItems int `json:"totalItems"` - Results []*TCGPlayerCategoryGroup `json:"results"` + TotalItems int `json:"totalItems"` + Results []*CategoryGroup `json:"results"` }{} _ = tmpStruct - reqObj := RequestObject{ + reqObj := apiact.RequestObject{ Method: "GET", Headers: p.getHeader(), URL: apiURL, } - req, err := GetRequest(reqObj) + req, err := apiact.GetRequest(reqObj) if err != nil { return nil, err } @@ -274,8 +275,8 @@ func (p *TCGPlayer) ListCategoryGroups(categoryID, limit, offset int) (groups [] return tmpStruct.Results, nil } -// TCGPlayerProductPrice - -type TCGPlayerProductPrice struct { +// ProductPrice - +type ProductPrice struct { ProductID int `json:"productId"` LowPrice float32 `json:"lowPrice"` MidPrice float32 `json:"midPrice"` @@ -286,7 +287,7 @@ type TCGPlayerProductPrice struct { } // ListGroupProductPrice - -func (p *TCGPlayer) ListGroupProductPrice(groupID int) (prices []*TCGPlayerProductPrice, err error) { +func (p *TCGPlayer) ListGroupProductPrice(groupID int) (prices []*ProductPrice, err error) { apiURL, err := p.getAPIURL(fmt.Sprintf("/pricing/group/%d", groupID), true) if err != nil { return nil, err @@ -294,15 +295,15 @@ func (p *TCGPlayer) ListGroupProductPrice(groupID int) (prices []*TCGPlayerProdu tmpStruct := struct { TCGPlayerAPIRes - Results []*TCGPlayerProductPrice `json:"results"` + Results []*ProductPrice `json:"results"` }{} - reqObj := RequestObject{ + reqObj := apiact.RequestObject{ URL: apiURL, Headers: p.getHeader(), Method: "GET", } - req, err := GetRequest(reqObj) + req, err := apiact.GetRequest(reqObj) if err != nil { return nil, err }