mirror of
https://github.com/retailcrm/mg-bot-api-client-go.git
synced 2024-11-25 06:16:03 +03:00
add file upload and download methods
This commit is contained in:
parent
31cdf97775
commit
d427667b29
110
v1/client.go
110
v1/client.go
@ -1,9 +1,11 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -437,7 +439,7 @@ func (c *MgClient) MessageSend(request MessageSendRequest) (MessageSendResponse,
|
|||||||
var resp MessageSendResponse
|
var resp MessageSendResponse
|
||||||
outgoing, _ := json.Marshal(&request)
|
outgoing, _ := json.Marshal(&request)
|
||||||
|
|
||||||
data, status, err := c.PostRequest("/messages", []byte(outgoing))
|
data, status, err := c.PostRequest("/messages", bytes.NewBuffer(outgoing))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return resp, status, err
|
return resp, status, err
|
||||||
}
|
}
|
||||||
@ -677,6 +679,112 @@ func (c *MgClient) CommandDelete(request string) (map[string]interface{}, int, e
|
|||||||
return resp, status, err
|
return resp, status, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFile implement get file url
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6")
|
||||||
|
//
|
||||||
|
// data, status, err := client.GetFile("file_ID")
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("%v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fmt.Printf("%s\n", data.ID)
|
||||||
|
func (c *MgClient) GetFile(request string) (FullFileResponse, int, error) {
|
||||||
|
var resp FullFileResponse
|
||||||
|
var b []byte
|
||||||
|
|
||||||
|
data, status, err := c.GetRequest(fmt.Sprintf("/files/%s", request), b)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if e := json.Unmarshal(data, &resp); e != nil {
|
||||||
|
return resp, status, e
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
return resp, status, c.Error(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadFile upload file
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// resp, err := http.Get("https://via.placeholder.com/300")
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("%v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// defer resp.Body.Close()
|
||||||
|
//
|
||||||
|
// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6")
|
||||||
|
//
|
||||||
|
// data, status, err := client.UploadFile(resp.Body)
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("%v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fmt.Printf("%s\n%s", data.ID, status)
|
||||||
|
func (c *MgClient) UploadFile(request io.Reader) (UploadFileResponse, int, error) {
|
||||||
|
var resp UploadFileResponse
|
||||||
|
|
||||||
|
data, status, err := c.PostRequest("/files/upload", request)
|
||||||
|
if err != nil {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if e := json.Unmarshal(data, &resp); e != nil {
|
||||||
|
return resp, status, e
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
return resp, status, c.Error(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadFileByURL upload file by url
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// uploadFileResponse, st, err := c.UploadFileByURL(UploadFileByUrlRequest{
|
||||||
|
// Url: "https://via.placeholder.com/300",
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("%v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fmt.Printf("%s\n%s", uploadFileResponse.ID, status)
|
||||||
|
func (c *MgClient) UploadFileByURL(request UploadFileByUrlRequest) (UploadFileResponse, int, error) {
|
||||||
|
var resp UploadFileResponse
|
||||||
|
outgoing, _ := json.Marshal(&request)
|
||||||
|
|
||||||
|
data, status, err := c.PostRequest("/files/upload_by_url", bytes.NewBuffer(outgoing))
|
||||||
|
if err != nil {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if e := json.Unmarshal(data, &resp); e != nil {
|
||||||
|
return resp, status, e
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
return resp, status, c.Error(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
// WsMeta let you receive url & headers to open web socket connection
|
// WsMeta let you receive url & headers to open web socket connection
|
||||||
func (c *MgClient) WsMeta(events []string) (string, http.Header, error) {
|
func (c *MgClient) WsMeta(events []string) (string, http.Header, error) {
|
||||||
var url string
|
var url string
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,7 +41,10 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func client() *MgClient {
|
func client() *MgClient {
|
||||||
return New(mgURL, mgToken)
|
c := New(mgURL, mgToken)
|
||||||
|
c.Debug = true
|
||||||
|
|
||||||
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMgClient_Bots(t *testing.T) {
|
func TestMgClient_Bots(t *testing.T) {
|
||||||
@ -197,7 +199,7 @@ func TestMgClient_Messages(t *testing.T) {
|
|||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, message := range data {
|
for _, message := range data {
|
||||||
assert.NotEmpty(t, message.Content)
|
assert.NotEmpty(t, message.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -433,6 +435,55 @@ func TestMgClient_WsMeta(t *testing.T) {
|
|||||||
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
|
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMgClient_UploadFile(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
|
||||||
|
resp, err := http.Get("https://via.placeholder.com/300")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
data, status, err := c.UploadFile(resp.Body)
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
t.Errorf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("File %+v is upload", data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMgClient_ImageMessages(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
|
||||||
|
uploadFileResponse, st, err := c.UploadFileByURL(UploadFileByUrlRequest{
|
||||||
|
Url: "https://via.placeholder.com/300",
|
||||||
|
})
|
||||||
|
|
||||||
|
if st != http.StatusOK {
|
||||||
|
t.Errorf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("File %+v is upload", uploadFileResponse.ID)
|
||||||
|
|
||||||
|
i, err := strconv.ParseUint(os.Getenv("MG_BOT_CHAT"), 10, 64)
|
||||||
|
message := MessageSendRequest{
|
||||||
|
Type: MsgTypeImage,
|
||||||
|
Scope: MessageScopePublic,
|
||||||
|
Items: []Item{{ID: uploadFileResponse.ID}},
|
||||||
|
ChatID: i,
|
||||||
|
}
|
||||||
|
|
||||||
|
data, status, err := c.MessageSend(message)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%d %v", status, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.NotEmpty(t, data.MessageID)
|
||||||
|
}
|
||||||
|
|
||||||
func RandStringBytesMaskImprSrc(n int) string {
|
func RandStringBytesMaskImprSrc(n int) string {
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
|
// A src.Int63() generates 63 random bits, enough for letterIdxMax characters!
|
||||||
|
@ -3,6 +3,7 @@ package v1
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -21,11 +22,11 @@ func (c *MgClient) GetRequest(url string, parameters []byte) ([]byte, int, error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PostRequest implements POST Request
|
// PostRequest implements POST Request
|
||||||
func (c *MgClient) PostRequest(url string, parameters []byte) ([]byte, int, error) {
|
func (c *MgClient) PostRequest(url string, parameters io.Reader) ([]byte, int, error) {
|
||||||
return makeRequest(
|
return makeRequest(
|
||||||
"POST",
|
"POST",
|
||||||
fmt.Sprintf("%s%s%s", c.URL, prefix, url),
|
fmt.Sprintf("%s%s%s", c.URL, prefix, url),
|
||||||
bytes.NewBuffer(parameters),
|
parameters,
|
||||||
c,
|
c,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -60,7 +61,7 @@ func (c *MgClient) DeleteRequest(url string, parameters []byte) ([]byte, int, er
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeRequest(reqType, url string, buf *bytes.Buffer, c *MgClient) ([]byte, int, error) {
|
func makeRequest(reqType, url string, buf io.Reader, c *MgClient) ([]byte, int, error) {
|
||||||
var res []byte
|
var res []byte
|
||||||
req, err := http.NewRequest(reqType, url, buf)
|
req, err := http.NewRequest(reqType, url, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -71,7 +72,7 @@ func makeRequest(reqType, url string, buf *bytes.Buffer, c *MgClient) ([]byte, i
|
|||||||
req.Header.Set("X-Bot-Token", c.Token)
|
req.Header.Set("X-Bot-Token", c.Token)
|
||||||
|
|
||||||
if c.Debug {
|
if c.Debug {
|
||||||
log.Printf("MG BOT API Request: %s %s %s %s", reqType, url, c.Token, buf.String())
|
log.Printf("MG BOT API Request: %s %s %s %+v", reqType, url, c.Token, buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, err := c.httpClient.Do(req)
|
resp, err := c.httpClient.Do(req)
|
||||||
|
36
v1/types.go
36
v1/types.go
@ -3,6 +3,7 @@ package v1
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -50,6 +51,8 @@ const (
|
|||||||
MsgTypeCommand string = "command"
|
MsgTypeCommand string = "command"
|
||||||
MsgTypeOrder string = "order"
|
MsgTypeOrder string = "order"
|
||||||
MsgTypeProduct string = "product"
|
MsgTypeProduct string = "product"
|
||||||
|
MsgTypeFile string = "file"
|
||||||
|
MsgTypeImage string = "image"
|
||||||
|
|
||||||
MsgOrderStatusCodeNew = "new"
|
MsgOrderStatusCodeNew = "new"
|
||||||
MsgOrderStatusCodeApproval = "approval"
|
MsgOrderStatusCodeApproval = "approval"
|
||||||
@ -162,6 +165,7 @@ type (
|
|||||||
Content string `url:"content,omitempty" json:"content"`
|
Content string `url:"content,omitempty" json:"content"`
|
||||||
Product *MessageProduct `url:"product,omitempty" json:"product"`
|
Product *MessageProduct `url:"product,omitempty" json:"product"`
|
||||||
Order *MessageOrder `url:"order,omitempty" json:"order"`
|
Order *MessageOrder `url:"order,omitempty" json:"order"`
|
||||||
|
Items []Item `url:"order,omitempty" json:"items"`
|
||||||
Scope string `url:"scope,omitempty" json:"scope"`
|
Scope string `url:"scope,omitempty" json:"scope"`
|
||||||
ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
|
ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
|
||||||
QuoteMessageId uint64 `url:"quote_message_id,omitempty" json:"quote_message_id"`
|
QuoteMessageId uint64 `url:"quote_message_id,omitempty" json:"quote_message_id"`
|
||||||
@ -189,6 +193,10 @@ type (
|
|||||||
Name string `url:"name,omitempty" json:"name"`
|
Name string `url:"name,omitempty" json:"name"`
|
||||||
Description string `url:"description,omitempty" json:"description"`
|
Description string `url:"description,omitempty" json:"description"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UploadFileByUrlRequest struct {
|
||||||
|
Url string `json:"url"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Response types
|
// Response types
|
||||||
@ -314,6 +322,24 @@ type (
|
|||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at,omitempty"`
|
UpdatedAt string `json:"updated_at,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FullFileResponse struct {
|
||||||
|
ID string `json:"id,omitempty"`
|
||||||
|
Type string `json:"type,omitempty"`
|
||||||
|
Size int `json:"size,omitempty"`
|
||||||
|
Url string `json:"url,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
UploadFileResponse struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Hash string `json:"hash"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Meta FileMeta `json:"meta"`
|
||||||
|
MimeType string `json:"mime_type"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Url *string `json:"source_url"`
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// WS event types
|
// WS event types
|
||||||
@ -499,6 +525,16 @@ type (
|
|||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
ClosedAt *string `json:"closed_at"`
|
ClosedAt *string `json:"closed_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileMeta struct {
|
||||||
|
Width *int `json:"width,omitempty"`
|
||||||
|
Height *int `json:"height,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
Item struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Caption string `json:"caption"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Channel settings
|
// Channel settings
|
||||||
|
Loading…
Reference in New Issue
Block a user