Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

210 lines
5.1KB

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "log"
  7. "net/http"
  8. "strings"
  9. )
  10. //abstract CRUD operation for espoCRM Entity
  11. func crmCreateEntity(entityType string, jsonB []byte) (entity interface{}, err error) {
  12. url := CRMConfig.BaseURL + "api/v1/" + entityType
  13. jsonStr, err := postRAW(jsonB, url, crmBuildCommonAPIHeader())
  14. if err != nil {
  15. entity, _ = crmRescueDuplicateCreate(err, entityType)
  16. return
  17. }
  18. return crmJSON2Entity(entityType, jsonStr)
  19. }
  20. func crmUpdateEntity(entityType string, id string, jsonB []byte) (entity interface{}, err error) {
  21. url := CRMConfig.BaseURL + "api/v1/" + entityType + "/" + id
  22. jsonStr, err := patchRAW(jsonB, url, crmBuildCommonAPIHeader())
  23. if err != nil {
  24. log.Println(err)
  25. return
  26. }
  27. return crmJSON2Entity(entityType, jsonStr)
  28. }
  29. func crmReplaceEntity(entityType string, id string, jsonB []byte) (entity interface{}, err error) {
  30. url := CRMConfig.BaseURL + "api/v1/" + entityType + "/" + id
  31. jsonStr, err := putRAW(jsonB, url, crmBuildCommonAPIHeader())
  32. if err != nil {
  33. log.Println(err)
  34. return
  35. }
  36. return crmJSON2Entity(entityType, jsonStr)
  37. }
  38. func crmDeleteEntity(entityType string, id string) (deleted bool, err error) {
  39. url := CRMConfig.BaseURL + "api/v1/" + entityType + "/" + id
  40. resp, err := deleteRAW(url, crmBuildCommonAPIHeader())
  41. if err != nil {
  42. log.Println(err)
  43. return
  44. }
  45. deleted = strings.ToLower(resp) == "true"
  46. return
  47. }
  48. //give an id, return json
  49. func crmGetEntity(entityType string, id string) (entity interface{}, err error) {
  50. url := CRMConfig.BaseURL + "api/v1/" + entityType + "/" + id
  51. jsonStr, err := getRAW(url, crmBuildCommonAPIHeader())
  52. if err != nil {
  53. log.Println(err)
  54. return
  55. }
  56. return crmJSON2Entity(entityType, jsonStr)
  57. }
  58. func crmBuildCommonAPIHeader() (headers map[string]string) {
  59. headers = map[string]string{}
  60. headers["Authorization"] = crmAuthHeader()
  61. headers["Accept"] = "application/json"
  62. headers["Content-Type"] = "application/json"
  63. return headers
  64. }
  65. //given a json string, convert it to Typed structure
  66. func crmJSON2Entity(entityType string, data string) (r interface{}, err error) {
  67. switch entityType {
  68. case "Lead":
  69. e := crmdLead{}
  70. err = json.Unmarshal([]byte(data), &e)
  71. r = e
  72. case "Account":
  73. //r = crmdAccount{}
  74. default:
  75. log.Fatalf("crmJSON2Entity: Unknown EntityType %s", entityType)
  76. }
  77. if err != nil {
  78. log.Println(err)
  79. }
  80. return
  81. }
  82. func crmRescueDuplicateCreate(e error, entityType string) (entity interface{}, success bool) {
  83. if !isErrIndicateDuplicate(e) {
  84. return
  85. }
  86. entity, err := e.(errorHTTPResponse).XStatusReason().Data2Entity(entityType)
  87. success = err == nil
  88. return
  89. }
  90. func isErrIndicateDuplicate(e error) (yes bool) {
  91. err, isOurError := e.(errorHTTPResponse)
  92. if !isOurError {
  93. return
  94. }
  95. reason := err.XStatusReason()
  96. yes = strings.ToLower(reason.Reason) == "duplicate"
  97. return
  98. }
  99. type crmdSearchFilter struct {
  100. Attribute string
  101. CompareMethod string //startWith, equals, contains, endsWith, like, isNull, isNotNull , notEquals
  102. ExpectValue string
  103. }
  104. type crmdSearchResult struct {
  105. Total int `json:"total"`
  106. List *json.RawMessage `json:"list"`
  107. }
  108. func crmSearchEntity(entityType string, filters []crmdSearchFilter) (result crmdSearchResult, err error) {
  109. url := CRMConfig.BaseURL + "api/v1/" + entityType
  110. req, err := http.NewRequest("GET", url, nil)
  111. if err != nil {
  112. log.Println("crmGetRecord: cannot form good http Request")
  113. log.Print(err)
  114. return
  115. }
  116. //auth header
  117. req.Header.Set("Authorization", crmAuthHeader())
  118. req.Header.Set("Accept", "application/json, text/javascript, */*; q=0.01")
  119. req.Header.Set("Content-Type", "application/json")
  120. //query string
  121. q := req.URL.Query()
  122. q.Add("maxSize", "20")
  123. q.Add("maxSize", "0")
  124. q.Add("sortBy", "createdAt")
  125. q.Add("asc", "false")
  126. for k, v := range filters {
  127. switch v.CompareMethod {
  128. case "startWith", "equals", "contains", "endsWith", "like", "notEquals":
  129. q.Add(fmt.Sprintf("where[%d][type]", k), v.CompareMethod)
  130. q.Add(fmt.Sprintf("where[%d][attribute]", k), v.Attribute)
  131. q.Add(fmt.Sprintf("where[%d][value]", k), v.ExpectValue)
  132. case "isNull", "isNotNull":
  133. q.Add(fmt.Sprintf("where[%d][type]", k), v.CompareMethod)
  134. q.Add(fmt.Sprintf("where[%d][attribute]", k), v.Attribute)
  135. default:
  136. log.Printf("Unknown Compare Method %s", v.CompareMethod)
  137. }
  138. }
  139. req.URL.RawQuery = q.Encode()
  140. debugDumpHTTPRequest(req)
  141. client := &http.Client{}
  142. r, err := client.Do(req)
  143. debugDumpHTTPResponse(r)
  144. if err != nil {
  145. return
  146. }
  147. defer r.Body.Close()
  148. jsonB, err := ioutil.ReadAll(r.Body)
  149. if err != nil {
  150. return
  151. }
  152. err = json.Unmarshal(jsonB, &result)
  153. return
  154. }
  155. func crmFindEntityByID(entityType string, id string) (entity interface{}, err error) {
  156. filters := []crmdSearchFilter{
  157. {"id", "equals", id},
  158. }
  159. cs, err := crmSearchEntity(entityType, filters)
  160. if err != nil || cs.Total < 1 {
  161. return
  162. }
  163. if cs.Total > 1 {
  164. log.Printf("ERROR: more than one(%d) %s associated with %s", cs.Total, entityType, id)
  165. }
  166. switch entityType {
  167. case "Lead":
  168. e := []crmdLead{}
  169. err = json.Unmarshal(*cs.List, &e)
  170. if (err != nil) || (len(e) != cs.Total) {
  171. return
  172. }
  173. entity = e[0]
  174. case "Account":
  175. return
  176. }
  177. return
  178. }