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 // NullString - type NullString *string // String - func String(s string) NullString { return &s } // NullInt - type NullInt *int // Int - func Int(i int) NullInt { return &i } // Line - type Line struct { URL string APIVersion string AccessToken string } // 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 } 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 }