add file upload and download methods

This commit is contained in:
DmitryZagorulko 2018-12-26 17:38:41 +03:00
parent 31cdf97775
commit d427667b29
4 changed files with 204 additions and 8 deletions

View File

@ -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

View File

@ -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!

View File

@ -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)

View File

@ -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