Просмотр исходного кода

create attachment at EspoCRM done ~ yeah

master
Patrick Peng Sun 8 лет назад
Родитель
Сommit
6e66c17d79
4 измененных файлов: 99 добавлений и 42 удалений
  1. +76
    -31
      crmAttachment.go
  2. +5
    -4
      crmAttachment_test.go
  3. +10
    -0
      fileinfo.go
  4. +8
    -7
      upload.go

+ 76
- 31
crmAttachment.go Просмотреть файл

@@ -1,47 +1,101 @@
package main

import (
"encoding/base64"
"encoding/json"
"fmt"
"io/ioutil"
"log"
)

type crmFileInfo struct {
Name string `json:"name"`
Type string `json:"type"`
Role string `json:"role"`
Size int64 `json:"size"`
}

type attachmentID struct {
ID string `json:"attachmentId"`
}

func crmAttachFile(path string) (fileID string) {
//http post
r, _ := crmPostAttach(path)
func crmUploadFile(path string) (fileID string, fileInfo crmFileInfo, err error) {

fileInfo, err = getFileInfo4CRM(path)
headers, err := crmUploadFileHTTPHeader(fileInfo)
data, err := crmFileDataString(path, fileInfo)
url := crmUploadAttachmentURL()
resp, err := postRAW([]byte(data), url, headers)
fileID, err = crmFileIDFromJSON(resp)
log.Println(fileID)
log.Println(err)
return
}

//crmFileIDFromHTTP read attachment id from http response
// as http response cannot be 'rewind', this function is
// specifically used for one purpose only.
// i.e. upload attachment to EspoCRM
func crmFileIDFromJSON(jsonStr string) (fileID string, err error) {
attach := attachmentID{}
json.Unmarshal([]byte(r), &attach)
return attach.ID
err = json.Unmarshal([]byte(jsonStr), &attach)
return attach.ID, err
}

func crmPostAttachmentURL() string {
//crmUploadFileHTTPHeader when uploading a file, we need its mime, auth header, etc.
func crmUploadFileHTTPHeader(fileInfo crmFileInfo) (headers map[string]string, err error) {
headers = map[string]string{}
headers["Authorization"] = crmAuthHeader()
headers["Accept"] = "application/json"
headers["Content-Type"] = fileInfo.Type
return headers, err
}

func crmUploadAttachmentURL() string {
return "https://c.hitxy.org.au/api/v1/Attachment/action/upload"
}

func crmAuthHeader() string {
return "Basic cGF0cmljazpiNjFmYWRlMTM5OWYwY2ZjNmZjZjcxNTU0OTljNTNkOQ=="
//return "Basic cGF0cmljazp3b3JraGFyZA=="
//return "Basic cGF0cmljazpiNjFmYWRlMTM5OWYwY2ZjNmZjZjcxNTU0OTljNTNkOQ=="
return "Basic cGF0cmljazp3b3JraGFyZA=="
}

func crmFileDataString(path string) string {
//read file
//crmFileDataString, encode a base64 string of the given file
//so that the receiver EspoCRM can correctly understand and decode it.
//"data:image/png;base64,iVB....="
//
//TODO: for big files, this might ave issue cause out of memory
func crmFileDataString(path string, fileInfo crmFileInfo) (encoded string, err error) {
content, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}
b64content := base64.StdEncoding.EncodeToString(content)
encoded = fmt.Sprintf("data:%s;base64,%s", fileInfo.Type, b64content)

//encode it
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAXIAAAFyAQMAAADS6sNKAAAABlBMVEX///8AAABVwtN+AAABsklEQVR4nO2aS47EIAxEkXKAHClX7yPlAJHcwR8MgZnljCqqWrjzefQG29iQUiiKoiiK+h+J67Krcqg566s93n3I4/J2s1/1apP7shq9vU2PkMfk67TrO/UCN5s9M0ch/wq+uoI6hYjFO/k38Yaa0eHkX8GXYe6b0Wc9Qh6Sz3rssz/Msh4jD8X3I9t6raX2miKPxasr3F1UjfJTl+rN0HCFbfIf8kC8zn033NBTmyqx9oo8Ml97J98Faeu1ds7aVE31GHk43k1U3mHkfJRi5CF58V3MLrN7U+WJ4OEP5JF4i2grxYLPreq5MiOPxQdweWYvLZWrPxxT0JOH4rPKHraq16UbeTg+UrlEAWYOEPX2yn/IY/GezyVLbc/nl/8beVw+HucBRFULf0XI4/IZ1j73w8liWYg8Eh+ldoT1ERsgnWeQx+X7kZnA9xz03O8iD8X7tEeXXErpv9eyQeSBebsJIJtm94cpP5AH43cP8OinfKk2zeeP5GH56KfSFeZDCfKovNjOtcjYSv3oD+QxeP1prbL1U/m91llGkQfjXddQb9t54u/1G3kEnqIoiqKov9QXf1Q2La7tzOYAAAAASUVORK5CYII="
return encoded, nil
}

func crmPostAttach(path string) (resp string, err error) {
func crmUploadAttachmentMeta(fileID string, fileInfo crmFileInfo) (resp string, err error) {
headers := map[string]string{}
headers["Authorization"] = crmAuthHeader()
headers["Accept"] = "application/json, text/javascript, */*; q=0.01"
data := []byte(crmFileDataString(path))
URL := crmPostAttachmentURL()
resp, err = postRAW(data, URL, headers)
headers["Content-Type"] = "application/json"

fileInfo.Role = "Attachment"
jb, _ := json.Marshal(fileInfo)
log.Println(string(jb))

URL := crmAttachmentMetaURL(fileID)
resp, err = putRAW(jb, URL, headers)
return
}

func crmAttachmentMetaURL(fileID string) string {
return "https://c.hitxy.org.au/api/v1/Attachment/" + fileID
}

type attachmentInfo struct {
ID string `json:"id"` //"id": "591e55398345683ee",
Name string `json:"name"` //"name": "static_qr_code_without_logo.png",
@@ -62,21 +116,12 @@ type attachmentInfo struct {
CreatedbyName string `json:"createdByName"` // "createdByName": "Admin"
}

func crmPatchAttachmentInfo(id string) (j string) {
info := map[string]interface{}{}
//{"name":"static_qr_code_without_logo.png","type":"image/png","role":"Attachment","size":509}
info["name"] = "static_qr_code_without_logo.png"
info["type"] = "image/png"
info["role"] = "Attachment"
info["size"] = 509
url := "https://c.hitxy.org.au/api/v1/Attachment/591e5f7b9463d7147"

headers := map[string]string{}
headers["Authorization"] = crmAuthHeader()
headers["Content-Type"] = "application/json"

jb, _ := json.Marshal(info)
log.Println(string(jb))
j, _ = putRAW(jb, url, headers)
func crmCreateAttachment(path string) (result attachmentInfo, err error) {
fileID, fileInfo, err := crmUploadFile(path)
aInfo, err := crmUploadAttachmentMeta(fileID, fileInfo)
if err != nil {
return
}
json.Unmarshal([]byte(aInfo), &result)
return
}

+ 5
- 4
crmAttachment_test.go Просмотреть файл

@@ -5,13 +5,14 @@ import "log"
import "encoding/json"

func TestCRMAttachFile(t *testing.T) {
id := crmAttachFile("media_for_test/200x200.png")
log.Println(id)
r, e := crmCreateAttachment("media_for_test/200x200.png")
log.Println(r)
log.Println(e)
}

func TestPatchAttachmentInfo(t *testing.T) {
crmPatchAttachmentInfo("591e5f7b9463d7147")
//crmPatchAttachmentInfo("591e5f7b9463d7147")
crmCreateAttachment("abc")
}

func TestDecodeJsonResponse(t *testing.T) {

+ 10
- 0
fileinfo.go Просмотреть файл

@@ -6,6 +6,8 @@ import (
"os"
"strings"

"path/filepath"

filetype "gopkg.in/h2non/filetype.v1"
)

@@ -93,3 +95,11 @@ func isJPG(path string) bool {
check2 := strings.EqualFold("image/jpeg", mime)
return check1 && check2
}

//get file Info for uploading CRM attachment /files
func getFileInfo4CRM(path string) (info crmFileInfo, err error) {
info.Name = filepath.Base(path) + filepath.Ext(path)
info.Type, _, err = getFileMime(path)
info.Size, err = getFileSize(path)
return
}

+ 8
- 7
upload.go Просмотреть файл

@@ -8,7 +8,6 @@ import (
"log"
"mime/multipart"
"net/http"
"net/http/httputil"
"os"
)

@@ -56,7 +55,9 @@ func postFileForm(filename string, targetURL string, formFieldName string) (strJ
}

func postJSON(jsonB []byte, targetURL string) (resp string, err error) {
return postRAW(jsonB, targetURL, nil)
headers := map[string]string{}
headers["Content-Type"] = "application/json"
return postRAW(jsonB, targetURL, headers)
}

func postRAW(data []byte, targetURL string, headers map[string]string) (resp string, err error) {
@@ -86,11 +87,11 @@ func httpRaw(httpMethod, targetURL string, data []byte, headers map[string]strin
}
defer r.Body.Close()

dump, err := httputil.DumpResponse(r, true)
if err != nil {
log.Fatal(err)
}
fmt.Printf("dump : %q", dump)
// dump, err := httputil.DumpResponse(r, true)
// if err != nil {
// log.Fatal(err)
// }
// fmt.Printf("dump : %q", dump)

b, _ := ioutil.ReadAll(r.Body)
resp = string(b)

Загрузка…
Отмена
Сохранить