|
- package flashduty
-
- import (
- "bytes"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "net/url"
- "time"
-
- "github.com/ccfos/nightingale/v6/center/cconf"
-
- "github.com/toolkits/pkg/logger"
- )
-
- var (
- Api string
- Headers map[string]string
- Timeout time.Duration
- )
-
- func Init(fdConf cconf.FlashDuty) {
- Api = fdConf.Api
- Headers = make(map[string]string)
- Headers = fdConf.Headers
-
- if fdConf.Timeout == 0 {
- Timeout = 5 * time.Second
- } else {
- Timeout = fdConf.Timeout * time.Millisecond
- }
- }
-
- type dutyResp struct {
- RequestId string `json:"request_id"`
- Data Data `json:"data"`
- Error struct {
- Code string `json:"code"`
- Message string `json:"message"`
- } `json:"error"`
- }
-
- type Data struct {
- P int `json:"p"`
- Limit int `json:"limit"`
- Total int `json:"total"`
- Items []Item `json:"items"`
- }
-
- type Item struct {
- MemberID int `json:"member_id"`
- MemberName string `json:"member_name"`
- Phone string `json:"phone"`
- Email string `json:"email"`
- EmailVerified string `json:"email_verified"`
- }
-
- func PostFlashDuty(path string, appKey string, body interface{}) error {
- _, err := PostFlashDutyWithResp(path, appKey, body)
- return err
- }
-
- func PostFlashDutyWithResp(path string, appKey string, body interface{}) (Data, error) {
- urlParams := url.Values{}
- urlParams.Add("app_key", appKey)
- var url string
- if Api != "" {
- url = fmt.Sprintf("%s%s?%s", Api, path, urlParams.Encode())
- } else {
- url = fmt.Sprintf("%s%s?%s", "https://api.flashcat.cloud", path, urlParams.Encode())
- }
- response, code, err := PostJSON(url, Timeout, Headers, body)
- req, _ := json.Marshal(body)
- logger.Infof("flashduty post: url=%s, req=%s; response=%s, code=%d", url, string(req), string(response), code)
-
- var resp dutyResp
- if err == nil {
- e := json.Unmarshal(response, &resp)
- if e == nil && resp.Error.Message != "" {
- err = fmt.Errorf("flashduty post error: %s", resp.Error.Message)
- }
- }
-
- return resp.Data, err
- }
-
- func PostJSON(url string, timeout time.Duration, headers map[string]string, v interface{}, retries ...int) (response []byte, code int, err error) {
- var bs []byte
-
- bs, err = json.Marshal(v)
- if err != nil {
- return
- }
-
- bf := bytes.NewBuffer(bs)
-
- client := http.Client{
- Timeout: timeout,
- }
-
- req, err := http.NewRequest("POST", url, bf)
- if err != nil {
- return
- }
- req.Header.Set("Content-Type", "application/json")
-
- if len(headers) > 0 {
- for k, v := range headers {
- req.Header.Set(k, v)
- }
- }
-
- var resp *http.Response
-
- if len(retries) > 0 {
- for i := 0; i < retries[0]; i++ {
- resp, err = client.Do(req)
- if err == nil {
- break
- }
-
- tryagain := ""
- if i+1 < retries[0] {
- tryagain = " try again"
- }
-
- logger.Warningf("failed to curl %s error: %s"+tryagain, url, err)
-
- if i+1 < retries[0] {
- time.Sleep(time.Millisecond * 200)
- }
- }
- } else {
- resp, err = client.Do(req)
- }
-
- if err != nil {
- return
- }
-
- code = resp.StatusCode
-
- if resp.Body != nil {
- defer resp.Body.Close()
- response, err = io.ReadAll(resp.Body)
- }
-
- return
- }
|