No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

272 líneas
6.3KB

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