You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 line
5.0KB

  1. package main
  2. import (
  3. "encoding/base64"
  4. "encoding/json"
  5. "fmt"
  6. "io/ioutil"
  7. "log"
  8. "os"
  9. )
  10. type crmFileInfo struct {
  11. Name string `json:"name"`
  12. Type string `json:"type"`
  13. Role string `json:"role"`
  14. Size int64 `json:"size"`
  15. }
  16. type attachmentID struct {
  17. ID string `json:"attachmentId"`
  18. }
  19. func crmUploadFile(path string) (fileID string, fileInfo crmFileInfo, err error) {
  20. fileInfo, err = getFileInfo4CRM(path)
  21. headers, err := crmPrepareAttachmentHTTPHeader(fileInfo)
  22. data, err := crmFileDataString(path, fileInfo)
  23. url := crmUploadAttachmentURL()
  24. resp, err := postRAW([]byte(data), url, headers)
  25. fileID, err = crmFileIDFromJSON(resp)
  26. log.Println(fileID)
  27. log.Println(err)
  28. return
  29. }
  30. //crmFileIDFromHTTP read attachment id from http response
  31. // as http response cannot be 'rewind', this function is
  32. // specifically used for one purpose only.
  33. // i.e. upload attachment to EspoCRM
  34. func crmFileIDFromJSON(jsonStr string) (fileID string, err error) {
  35. attach := attachmentID{}
  36. err = json.Unmarshal([]byte(jsonStr), &attach)
  37. return attach.ID, err
  38. }
  39. //crmPrepareAttachmentHTTPHeader when uploading a file, we need its mime, auth header, etc.
  40. func crmPrepareAttachmentHTTPHeader(fileInfo crmFileInfo) (headers map[string]string, err error) {
  41. headers = map[string]string{}
  42. headers["Authorization"] = crmAuthHeader()
  43. headers["Accept"] = "application/json"
  44. headers["Content-Type"] = fileInfo.Type
  45. return headers, err
  46. }
  47. func crmUploadAttachmentURL() string {
  48. return CRMConfig.BaseURL + "api/v1/Attachment/action/upload"
  49. }
  50. func crmAuthHeader() string {
  51. //return "Basic cGF0cmljazpiNjFmYWRlMTM5OWYwY2ZjNmZjZjcxNTU0OTljNTNkOQ=="
  52. s := CRMConfig.UserName + ":" + CRMConfig.UserPass
  53. r := base64.StdEncoding.EncodeToString([]byte(s))
  54. return "Basic " + r
  55. }
  56. //crmFileDataString, encode a base64 string of the given file
  57. //so that the receiver EspoCRM can correctly understand and decode it.
  58. //"data:image/png;base64,iVB....="
  59. //
  60. //TODO: for big files, this might ave issue cause out of memory
  61. func crmFileDataString(path string, fileInfo crmFileInfo) (encoded string, err error) {
  62. content, err := ioutil.ReadFile(path)
  63. if err != nil {
  64. return "", err
  65. }
  66. b64content := base64.StdEncoding.EncodeToString(content)
  67. encoded = fmt.Sprintf("data:%s;base64,%s", fileInfo.Type, b64content)
  68. //encode it
  69. return encoded, nil
  70. }
  71. func crmUploadAttachmentMeta(fileID string, fileInfo crmFileInfo) (resp string, err error) {
  72. headers := map[string]string{}
  73. headers["Authorization"] = crmAuthHeader()
  74. headers["Accept"] = "application/json, text/javascript, */*; q=0.01"
  75. headers["Content-Type"] = "application/json"
  76. fileInfo.Role = "Attachment"
  77. jb, _ := json.Marshal(fileInfo)
  78. log.Println(string(jb))
  79. URL := crmAttachmentMetaURL(fileID)
  80. resp, err = putRAW(jb, URL, headers)
  81. return
  82. }
  83. func crmAttachmentMetaURL(fileID string) string {
  84. //return "https://c.hitxy.org.au/api/v1/Attachment/" + fileID
  85. return CRMConfig.BaseURL + "api/v1/Attachment/" + fileID
  86. }
  87. type attachmentInfo struct {
  88. ID string `json:"id"` //"id": "591e55398345683ee",
  89. Name string `json:"name"` //"name": "static_qr_code_without_logo.png",
  90. Deleted bool `json:"deleted"` //"deleted": false,
  91. Type string `json:"type"` // "type": "image\/png",
  92. Size int `json:"size"` //"size": 509,
  93. SourceID string `json:"sourceId"` //"sourceId": null,
  94. CreateAT string `json:"createAt"` //"createdAt": "2017-05-19 02:15:21",
  95. Role string `json:"role"` //"role": "Attachment",
  96. Storage string `json:"storage"` //"storage": null,
  97. StorageFielPath string `json:"storageFilePath"` //"storageFilePath": null,
  98. Global bool `json:"global"` // "global": false,
  99. ParentID string `json:"parentId"` // "parentId": null,
  100. ParentType string `json:"parentType"` // "parentType": null,
  101. RelatedID string `json:"relatedId"` // "relatedId": null,
  102. RelatedType string `json:"relatedType"` // "relatedType": null,
  103. CreatedByID string `json:"createdById"` // "createdById": "1",
  104. CreatedbyName string `json:"createdByName"` // "createdByName": "Admin"
  105. }
  106. func crmCreateAttachment(path string) (result attachmentInfo, err error) {
  107. fileID, fileInfo, err := crmUploadFile(path)
  108. aInfo, err := crmUploadAttachmentMeta(fileID, fileInfo)
  109. if err != nil {
  110. return
  111. }
  112. json.Unmarshal([]byte(aInfo), &result)
  113. return
  114. }
  115. func crmDownloadAttachmentAs(fileID, saveAs string) (err error) {
  116. f, err := crmDownloadAttachment(fileID)
  117. if err != nil {
  118. return
  119. }
  120. err = os.Rename(f, saveAs)
  121. return
  122. }
  123. func crmDownloadAttachment(fileID string) (filename string, err error) {
  124. u := crmURL4DownloadAttachmet(fileID)
  125. headers := map[string]string{}
  126. headers["Authorization"] = crmAuthHeader()
  127. f, _, err := saveURLwithHTTPHeader(u, headers)
  128. log.Println(f)
  129. return f, err
  130. }
  131. func crmURL4DownloadAttachmet(fileID string) string {
  132. return CRMConfig.BaseURL + "?entryPoint=download&id=" + fileID
  133. }