add initial set of methods

This commit is contained in:
Alex Lushpai 2018-08-29 02:44:06 +03:00
parent 663c1f999c
commit 6dcd9b5668
7 changed files with 998 additions and 274 deletions

1
.gitignore vendored
View File

@ -25,5 +25,6 @@ _testmain.go
# IDE's files # IDE's files
.idea .idea
*.iml *.iml
.env
# Project ignores # Project ignores

View File

@ -1,9 +1,11 @@
language: go language: go
go: go:
- '1.8'
- '1.9' - '1.9'
- '1.10' - '1.10'
- '1.11'
before_install: before_install:
- go get -v github.com/google/go-querystring/query - go get -v github.com/google/go-querystring/query
- go get -v github.com/h2non/gock - go get -v github.com/stretchr/testify/assert
- go get -v github.com/joho/godotenv
script: go test -v ./... script: go test -v ./...

View File

@ -1,2 +1,45 @@
# mg-bot-api-client-go [![Build Status](https://img.shields.io/travis/retailcrm/mg-bot-api-client-go/master.svg?style=flat-square)](https://travis-ci.org/retailcrm/mg-bot-api-client-go)
Go client for MG Bot API [![GitHub release](https://img.shields.io/github/release/retailcrm/mg-bot-api-client-go.svg?style=flat-square)](https://github.com/retailcrm/mg-bot-api-client-go/releases)
[![GoLang version](https://img.shields.io/badge/GoLang-1.9%2C%201.10%2C%201.11-blue.svg?style=flat-square)](https://golang.org/dl/)
# retailCRM Message Gateway Bot API Go client
## Install
```bash
go get -u -v github.com/retailcrm/mg-bot-api-client-go
```
## Usage
```golang
package main
import (
"fmt"
"net/http"
"github.com/retailcrm/mg-bot-api-client-go/v1"
)
func main() {
var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6")
message := MessageSendRequest{
Scope: "public",
Content: "test",
ChatID: 12,
}
data, status, err := c.MessageSend(message)
if err != nil {
t.Errorf("%d %v", status, err)
}
fmt.Printf("%v", data.MessageID)
}
```
## Documentation
* [GoDoc](https://godoc.org/github.com/retailcrm/mg-bot-api-client-go)

View File

@ -19,8 +19,27 @@ func New(url string, token string) *MgClient {
} }
} }
func (c *MgClient) Bots(request BotsRequest) (BotsResponse, int, error) { // Bots get all available bots
var resp BotsResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Bots()
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, bot := range data {
// fmt.Printf("%v %v\n", bot.Name, bot.CreatedAt)
// }
func (c *MgClient) Bots(request BotsRequest) ([]BotsResponseItem, int, error) {
var resp []BotsResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -40,8 +59,27 @@ func (c *MgClient) Bots(request BotsRequest) (BotsResponse, int, error) {
return resp, status, err return resp, status, err
} }
func (c *MgClient) Channels(request ChannelsRequest) (ChannelsResponse, int, error) { // Channels get all available channels
var resp ChannelsResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Channels()
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, channel := range data {
// fmt.Printf("%v %v\n", channel.Type, channel.CreatedAt)
// }
func (c *MgClient) Channels(request ChannelsRequest) ([]ChannelResponseItem, int, error) {
var resp []ChannelResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -61,12 +99,31 @@ func (c *MgClient) Channels(request ChannelsRequest) (ChannelsResponse, int, err
return resp, status, err return resp, status, err
} }
func (c *MgClient) Managers(request ManagersRequest) (ManagersResponse, int, error) { // Users get all available users
var resp ManagersResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Users(UsersRequest:{Active:1})
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, user := range data {
// fmt.Printf("%v %v\n", user.FirstName, user.IsOnline)
// }
func (c *MgClient) Users(request UsersRequest) ([]UsersResponseItem, int, error) {
var resp []UsersResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
data, status, err := c.GetRequest(fmt.Sprintf("/managers?%s", outgoing.Encode()), b) data, status, err := c.GetRequest(fmt.Sprintf("/users?%s", outgoing.Encode()), b)
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }
@ -82,8 +139,27 @@ func (c *MgClient) Managers(request ManagersRequest) (ManagersResponse, int, err
return resp, status, err return resp, status, err
} }
func (c *MgClient) Customers(request CustomersRequest) (CustomersResponse, int, error) { // Customers get all available customers
var resp CustomersResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Customers()
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, customer := range data {
// fmt.Printf("%v %v\n", customer.FirstName, customer.Avatar)
// }
func (c *MgClient) Customers(request CustomersRequest) ([]CustomersResponseItem, int, error) {
var resp []CustomersResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -103,8 +179,27 @@ func (c *MgClient) Customers(request CustomersRequest) (CustomersResponse, int,
return resp, status, err return resp, status, err
} }
func (c *MgClient) Chats(request ChatsRequest) (ChatsResponse, int, error) { // Chats get all available chats
var resp ChatsResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Chats(ChatsRequest{ChannelType:ChannelTypeWhatsapp})
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, chat := range data {
// fmt.Printf("%v %v\n", chat.Customer, chat.LastMessage)
// }
func (c *MgClient) Chats(request ChatsRequest) ([]ChatResponseItem, int, error) {
var resp []ChatResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -124,8 +219,27 @@ func (c *MgClient) Chats(request ChatsRequest) (ChatsResponse, int, error) {
return resp, status, err return resp, status, err
} }
func (c *MgClient) Members(request MembersRequest) (MembersResponse, int, error) { // Members get all available chat members
var resp MembersResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Members(MembersRequest{State:ChatMemberStateActive})
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, member := range data {
// fmt.Printf("%v\n", member.CreatedAt)
// }
func (c *MgClient) Members(request MembersRequest) ([]MemberResponseItem, int, error) {
var resp []MemberResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -145,8 +259,27 @@ func (c *MgClient) Members(request MembersRequest) (MembersResponse, int, error)
return resp, status, err return resp, status, err
} }
func (c *MgClient) Dialogs(request DialogsRequest) (DialogsResponse, int, error) { // Dialogs get all available dialogs
var resp DialogsResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Dialogs(DialogsRequest{Active:1})
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, dialog := range data {
// fmt.Printf("%v %v\n", dialog.ChatID, dialog.CreatedAt)
// }
func (c *MgClient) Dialogs(request DialogsRequest) ([]DialogResponseItem, int, error) {
var resp []DialogResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -170,7 +303,7 @@ func (c *MgClient) DialogAssign(request DialogAssignRequest) (DialogAssignRespon
var resp DialogAssignResponse var resp DialogAssignResponse
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.PostRequest(fmt.Sprintf("/dialogs/%s/assign", request.ID), []byte(outgoing)) data, status, err := c.PatchRequest(fmt.Sprintf("/dialogs/%d/assign", request.DialogID), []byte(outgoing))
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }
@ -186,11 +319,26 @@ func (c *MgClient) DialogAssign(request DialogAssignRequest) (DialogAssignRespon
return resp, status, err return resp, status, err
} }
func (c *MgClient) DialogClose(request DialogCloseRequest) (DialogCloseResponse, int, error) { // DialogClose close selected dialog
var resp DialogCloseResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// _, status, err := client.DialogClose(123)
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
func (c *MgClient) DialogClose(request uint64) (map[string]interface{}, int, error) {
var resp map[string]interface{}
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.PostRequest(fmt.Sprintf("/dialogs/%s/close", request.ID), []byte(outgoing)) data, status, err := c.DeleteRequest(fmt.Sprintf("/dialogs/%d/close", request), []byte(outgoing))
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }
@ -206,8 +354,27 @@ func (c *MgClient) DialogClose(request DialogCloseRequest) (DialogCloseResponse,
return resp, status, err return resp, status, err
} }
func (c *MgClient) Messages(request MessagesRequest) (MessagesResponse, int, error) { // Messages get all available messages
var resp MessagesResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Messages(MessagesRequest{ManagerID:5})
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, message := range data {
// fmt.Printf("%v %v %v\n", message.ChatID, message.CreatedAt, message.CustomerID)
// }
func (c *MgClient) Messages(request MessagesRequest) ([]MessagesResponseItem, int, error) {
var resp []MessagesResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -227,8 +394,29 @@ func (c *MgClient) Messages(request MessagesRequest) (MessagesResponse, int, err
return resp, status, err return resp, status, err
} }
func (c *MgClient) MessageSend(request MessageSendRequest) (MessageResponse, int, error) { // MessageSend send message
var resp MessageResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.MessageSend(MessageSendRequest{
// Scope: "public",
// Content: "test",
// ChatID: i,
// })
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// fmt.Printf("%v \n", data.MessageID, data.Time)
func (c *MgClient) MessageSend(request MessageSendRequest) (MessageSendResponse, int, error) {
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", []byte(outgoing))
@ -247,11 +435,29 @@ func (c *MgClient) MessageSend(request MessageSendRequest) (MessageResponse, int
return resp, status, err return resp, status, err
} }
func (c *MgClient) MessageEdit(request MessageEditRequest) (MessageResponse, int, error) { // MessageEdit update selected message
var resp MessageResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// _, status, err := client.MessageEdit(MessageEditRequest{
// ID: 123,
// Content: "test",
// })
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
func (c *MgClient) MessageEdit(request MessageEditRequest) (map[string]interface{}, int, error) {
var resp map[string]interface{}
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.PatchRequest(fmt.Sprintf("/messages/%s", request.ID), []byte(outgoing)) data, status, err := c.PatchRequest(fmt.Sprintf("/messages/%d", request.ID), []byte(outgoing))
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }
@ -267,11 +473,26 @@ func (c *MgClient) MessageEdit(request MessageEditRequest) (MessageResponse, int
return resp, status, err return resp, status, err
} }
func (c *MgClient) MessageDelete(request MessageDeleteRequest) (MessageResponse, int, error) { // MessageDelete delete selected message
var resp MessageResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// _, status, err := client.MessageDelete(123)
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
func (c *MgClient) MessageDelete(request uint64) (map[string]interface{}, int, error) {
var resp map[string]interface{}
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.DeleteRequest(fmt.Sprintf("/messages/%s", request.ID), []byte(outgoing)) data, status, err := c.DeleteRequest(fmt.Sprintf("/messages/%d", request), []byte(outgoing))
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }
@ -287,11 +508,26 @@ func (c *MgClient) MessageDelete(request MessageDeleteRequest) (MessageResponse,
return resp, status, err return resp, status, err
} }
func (c *MgClient) Info(request InfoRequest) (InfoResponse, int, error) { // Info updates bot information
var resp InfoResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// _, status, err := client.Info(InfoRequest{Name: "AWESOME", Avatar: "https://example.com/logo.svg"})
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
func (c *MgClient) Info(request InfoRequest) (map[string]interface{}, int, error) {
var resp map[string]interface{}
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.PatchRequest("/messages/info", []byte(outgoing)) data, status, err := c.PatchRequest("/my/info", []byte(outgoing))
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }
@ -307,8 +543,27 @@ func (c *MgClient) Info(request InfoRequest) (InfoResponse, int, error) {
return resp, status, err return resp, status, err
} }
func (c *MgClient) Commands(request CommandsRequest) (CommandsResponse, int, error) { // Commands get all available commands for bot
var resp CommandsResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.Commands()
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// for _, command := range data {
// fmt.Printf("%v %v\n", command.Name, command.Description)
// }
func (c *MgClient) Commands(request CommandsRequest) ([]CommandsResponseItem, int, error) {
var resp []CommandsResponseItem
var b []byte var b []byte
outgoing, _ := query.Values(request) outgoing, _ := query.Values(request)
@ -328,8 +583,29 @@ func (c *MgClient) Commands(request CommandsRequest) (CommandsResponse, int, err
return resp, status, err return resp, status, err
} }
func (c *MgClient) CommandEdit(request CommandEditRequest) (CommandEditResponse, int, error) { // CommandEdit create or change command for bot
var resp CommandEditResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// data, status, err := client.CommandEdit(CommandEditRequest{
// BotID: 1,
// Name: "show_payment_types",
// Description: "Get available payment types",
// })
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
//
// fmt.Printf("%v %v\n", data.Name, data.Description)
func (c *MgClient) CommandEdit(request CommandEditRequest) (CommandsResponseItem, int, error) {
var resp CommandsResponseItem
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.PutRequest(fmt.Sprintf("/my/commands/%s", request.Name), []byte(outgoing)) data, status, err := c.PutRequest(fmt.Sprintf("/my/commands/%s", request.Name), []byte(outgoing))
@ -348,11 +624,26 @@ func (c *MgClient) CommandEdit(request CommandEditRequest) (CommandEditResponse,
return resp, status, err return resp, status, err
} }
func (c *MgClient) CommandDelete(request CommandDeleteRequest) (CommandDeleteResponse, int, error) { // CommandDelete delete selected command for bot
var resp CommandDeleteResponse //
// Example:
//
// var client = v1.New("https://demo.url", "09jIJ")
//
// _, status, err := client.CommandDelete(show_payment_types)
//
// if err != nil {
// fmt.Printf("%v", err)
// }
//
// if status >= http.StatusBadRequest {
// fmt.Printf("%v", err)
// }
func (c *MgClient) CommandDelete(request string) (map[string]interface{}, int, error) {
var resp map[string]interface{}
outgoing, _ := json.Marshal(&request) outgoing, _ := json.Marshal(&request)
data, status, err := c.DeleteRequest(fmt.Sprintf("/my/commands/%s", request.Name), []byte(outgoing)) data, status, err := c.DeleteRequest(fmt.Sprintf("/my/commands/%s", request), []byte(outgoing))
if err != nil { if err != nil {
return resp, status, err return resp, status, err
} }

View File

@ -1,14 +1,318 @@
package v1 package v1
import ( import (
"log"
"net/http"
"os" "os"
"strconv"
"testing"
"github.com/joho/godotenv"
"github.com/stretchr/testify/assert"
) )
func TestMain(m *testing.M) {
if os.Getenv("DEVELOPER_NODE") == "1" {
err := godotenv.Load("../.env")
if err != nil {
log.Fatal("Error loading .env file")
}
os.Exit(m.Run())
}
}
var ( var (
mgURL = os.Getenv("MG_URL") mgURL = os.Getenv("MG_URL")
mgToken = os.Getenv("MG_TOKEN") mgToken = os.Getenv("MG_BOT_TOKEN")
) )
func client() *MgClient { func client() *MgClient {
return New(mgURL, mgToken) return New(mgURL, mgToken)
} }
func TestMgClient_Bots(t *testing.T) {
c := client()
req := BotsRequest{Active: 1}
data, status, err := c.Bots(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, bot := range data {
assert.NotEmpty(t, bot.CreatedAt)
}
}
func TestMgClient_Channels(t *testing.T) {
c := client()
req := ChannelsRequest{Active: 1}
data, status, err := c.Channels(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, channel := range data {
assert.NotEmpty(t, channel.Type)
}
}
func TestMgClient_Users(t *testing.T) {
c := client()
req := UsersRequest{Active: 1}
data, status, err := c.Users(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, user := range data {
assert.NotEmpty(t, user.FirstName)
}
}
func TestMgClient_Customers(t *testing.T) {
c := client()
req := CustomersRequest{}
data, status, err := c.Customers(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, customer := range data {
assert.NotEmpty(t, customer.ChannelId)
}
}
func TestMgClient_Chats(t *testing.T) {
c := client()
req := ChatsRequest{ChannelType: ChannelTypeTelegram}
data, status, err := c.Chats(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, chat := range data {
assert.NotEmpty(t, chat.Customer.Name)
}
}
func TestMgClient_Members(t *testing.T) {
c := client()
req := MembersRequest{State: ChatMemberStateLeaved}
data, status, err := c.Members(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, member := range data {
assert.NotEmpty(t, member.ChatID)
}
}
func TestMgClient_Dialogs(t *testing.T) {
c := client()
req := DialogsRequest{Active: 0}
data, status, err := c.Dialogs(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, dialog := range data {
assert.NotEmpty(t, dialog.ChatID)
}
}
func TestMgClient_DialogAssign(t *testing.T) {
c := client()
i, err := strconv.ParseUint(os.Getenv("MG_BOT_DIALOG"), 10, 64)
m, err := strconv.ParseUint(os.Getenv("MG_BOT_USER"), 10, 64)
req := DialogAssignRequest{DialogID: i, ManagerID: m}
_, status, err := c.DialogAssign(req)
assert.Error(t, err)
assert.Equal(t, http.StatusBadRequest, status)
}
func TestMgClient_DialogClose(t *testing.T) {
c := client()
i, err := strconv.ParseUint(os.Getenv("MG_BOT_DIALOG"), 10, 64)
_, status, err := c.DialogClose(i)
assert.Error(t, err)
assert.Equal(t, http.StatusBadRequest, status)
}
func TestMgClient_Messages(t *testing.T) {
c := client()
req := MessagesRequest{ChannelType: ChannelTypeTelegram, Scope: MessageScopePublic}
data, status, err := c.Messages(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, message := range data {
assert.NotEmpty(t, message.Content)
}
}
func TestMgClient_MessageSend(t *testing.T) {
c := client()
i, err := strconv.ParseUint(os.Getenv("MG_BOT_CHAT"), 10, 64)
message := MessageSendRequest{
Scope: "public",
Content: "test",
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 TestMgClient_MessageEdit(t *testing.T) {
c := client()
i, err := strconv.ParseUint(os.Getenv("MG_BOT_CHAT"), 10, 64)
message := MessageSendRequest{
Scope: "public",
Content: "test",
ChatID: i,
}
s, status, err := c.MessageSend(message)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, s.MessageID)
edit := MessageEditRequest{
ID: s.MessageID,
Content: "test",
}
e, status, err := c.MessageEdit(edit)
if err != nil {
t.Errorf("%d %v", status, err)
}
t.Logf("Message edit: %v", e)
}
func TestMgClient_MessageDelete(t *testing.T) {
c := client()
i, err := strconv.ParseUint(os.Getenv("MG_BOT_CHAT"), 10, 64)
message := MessageSendRequest{
Scope: "public",
Content: "test",
ChatID: i,
}
s, status, err := c.MessageSend(message)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, s.MessageID)
d, status, err := c.MessageDelete(s.MessageID)
if err != nil {
t.Errorf("%d %v", status, err)
}
t.Logf("Message delete: %v", d)
}
func TestMgClient_Info(t *testing.T) {
c := client()
req := InfoRequest{Name: "AWESOME", Avatar: os.Getenv("MG_BOT_LOGO")}
_, status, err := c.Info(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
}
func TestMgClient_Commands(t *testing.T) {
c := client()
req := CommandsRequest{}
data, status, err := c.Commands(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, data)
for _, command := range data {
assert.NotEmpty(t, command.Description)
}
}
func TestMgClient_CommandEditDelete(t *testing.T) {
c := client()
i, err := strconv.ParseUint(os.Getenv("MG_BOT_ID"), 10, 64)
req := CommandEditRequest{
BotID: i,
Name: "show_payment_types",
Description: "Get available payment types",
}
n, status, err := c.CommandEdit(req)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
assert.NotEmpty(t, n.ID)
d, status, err := c.CommandDelete(n.Name)
if err != nil {
t.Errorf("%d %v", status, err)
}
assert.NoError(t, err)
t.Logf("%v", d)
}

View File

@ -8,7 +8,7 @@ import (
"net/http" "net/http"
) )
var prefix = "/api/v1" var prefix = "/api/bot/v1"
// GetRequest implements GET Request // GetRequest implements GET Request
func (c *MgClient) GetRequest(url string, parameters []byte) ([]byte, int, error) { func (c *MgClient) GetRequest(url string, parameters []byte) ([]byte, int, error) {

View File

@ -4,6 +4,37 @@ import (
"net/http" "net/http"
) )
const (
ChannelTypeTelegram string = "telegram"
ChannelTypeFacebook string = "fbmessenger"
ChannelTypeViber string = "viber"
ChannelTypeWhatsapp string = "whatsapp"
ChannelTypeSkype string = "skype"
ChannelTypeVk string = "vk"
ChannelTypeInstagram string = "instagram"
ChannelTypeConsultant string = "consultant"
ChannelTypeCustom string = "custom"
ChatMemberStateActive string = "active"
ChatMemberStateKicked string = "kicked"
ChatMemberStateLeaved string = "leaved"
MessageScopePublic string = "public"
MessageScopePrivate string = "private"
BotEventMessageNew string = "message_new"
BotEventMessageUpdated string = "message_updated"
BotEventMessageDeleted string = "message_deleted"
BotEventDialogOpened string = "dialog_opened"
BotEventDialogClosed string = "dialog_closed"
BotEventDialogAssing string = "dialog_assign"
BotEventChatCreated string = "chat_created"
BotEventChatUpdated string = "chat_updated"
BotEventUserJoined string = "user_joined_chat"
BotEventUserLeave string = "user_left_chat"
BotEventUserUpdated string = "user_updated"
)
// MgClient type // MgClient type
type MgClient struct { type MgClient struct {
URL string `json:"url"` URL string `json:"url"`
@ -12,264 +43,316 @@ type MgClient struct {
httpClient *http.Client httpClient *http.Client
} }
type BotsRequest struct { // Request types
ID uint64 type (
Self string BotsRequest struct {
Active string ID uint64 `url:"id,omitempty"`
Since string Self bool `url:"self,omitempty"`
Until string Active uint8 `url:"active,omitempty"`
} Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
}
type ChannelsRequest struct { ChannelsRequest struct {
ID uint64 ID uint64 `url:"id,omitempty"`
Types string Types string `url:"types,omitempty"`
Active string Active uint8 `url:"active,omitempty"`
Since string Since string `url:"since,omitempty"`
Until string Until string `url:"until,omitempty"`
} }
type ManagersRequest struct { UsersRequest struct {
ID uint64 ID uint64 `url:"id,omitempty"`
ExternalID string `json:"external_id"` ExternalID string `url:"external_id,omitempty" json:"external_id"`
Online string Online uint8 `url:"online,omitempty"`
Active string Active uint8 `url:"active,omitempty"`
Since string Since string `url:"since,omitempty"`
Until string Until string `url:"until,omitempty"`
} }
type CustomersRequest struct { CustomersRequest struct {
ID uint64 ID uint64 `url:"id,omitempty"`
ExternalID string `json:"external_id"` ExternalID string `url:"external_id,omitempty" json:"external_id"`
Since string Since string `url:"since,omitempty"`
Until string Until string `url:"until,omitempty"`
} }
type ChatsRequest struct { ChatsRequest struct {
ID uint64 ID uint64 `url:"id,omitempty"`
ChannelID string `json:"channel_id"` ChannelID uint64 `url:"channel_id,omitempty" json:"channel_id"`
ChannelType string `json:"channel_type"` ChannelType string `url:"channel_type,omitempty" json:"channel_type"`
Since string Since string `url:"since,omitempty"`
Until string Until string `url:"until,omitempty"`
} }
type MembersRequest struct { MembersRequest struct {
ChatID string `json:"chat_id"` ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
ManagerID string `json:"manager_id"` ManagerID string `url:"manager_id,omitempty" json:"manager_id"`
CustomerID string `json:"customer_id"` CustomerID string `url:"customer_id,omitempty" json:"customer_id"`
Status string State string `url:"state,omitempty"`
Since string Since string `url:"since,omitempty"`
Until string Until string `url:"until,omitempty"`
} }
type DialogsRequest struct { DialogsRequest struct {
ID uint64 ID uint64 `url:"id,omitempty"`
ChatID string `json:"chat_id"` ChatID string `url:"chat_id,omitempty" json:"chat_id"`
ManagerID string `json:"manager_id"` ManagerID string `url:"manager_id,omitempty" json:"manager_id"`
BotID string `json:"bot_id"` BotID string `url:"bot_id,omitempty" json:"bot_id"`
Active string Assigned uint8 `url:"assigned,omitempty"`
Assigned string Active uint8 `url:"active,omitempty"`
Since string Since string `url:"since,omitempty"`
Until string Until string `url:"until,omitempty"`
} }
type MessagesRequest struct { DialogAssignRequest struct {
ID uint64 DialogID uint64 `url:"dialog_id,omitempty" json:"dialog_id"`
ChatID string `json:"chat_id"` ManagerID uint64 `url:"manager_id,omitempty" json:"manager_id"`
DialogID string `json:"dialog_id"` BotID uint64 `url:"bot_id,omitempty" json:"bot_id"`
ManagerID string `json:"manager_id"` }
CustomerID string `json:"customer_id"`
BotID string `json:"bot_id"`
ChannelID string `json:"channel_id"`
ChannelType string `json:"channel_type"`
Scope string
Since string
Until string
}
type MessageSendRequest struct { MessagesRequest struct {
Content string `json:"content"` ID uint64 `url:"id,omitempty"`
Scope uint8 `json:"scope"` ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
ChatID uint64 `json:"chat_id"` DialogID uint64 `url:"dialog_id,omitempty" json:"dialog_id"`
QuoteMessageId uint64 `json:"omitempty,quote_message_id"` ManagerID uint64 `url:"manager_id,omitempty" json:"manager_id"`
} CustomerID uint64 `url:"customer_id,omitempty" json:"customer_id"`
BotID uint64 `url:"bot_id,omitempty" json:"bot_id"`
ChannelID uint64 `url:"channel_id,omitempty" json:"channel_id"`
ChannelType string `url:"channel_type,omitempty" json:"channel_type"`
Scope string `url:"scope,omitempty"`
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
}
type MessageEditRequest struct { MessageSendRequest struct {
ID uint64 Content string `url:"content,omitempty" json:"content"`
Content string `json:"content"` Scope string `url:"scope,omitempty" json:"scope"`
} ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
QuoteMessageId uint64 `url:"quote_message_id,omitempty" json:"quote_message_id"`
}
type CommandsRequest struct { MessageEditRequest struct {
ID string ID uint64 `url:"id,omitempty"`
Name string Content string `url:"content,omitempty" json:"content"`
Since string }
Until string
}
type BotsResponse struct { InfoRequest struct {
Bots []BotListItem Name string `url:"name,omitempty" json:"name"`
} Avatar string `url:"avatar_url,omitempty" json:"avatar_url"`
Events []string `url:"events,omitempty" json:"events,brackets"`
}
type BotListItem struct { CommandsRequest struct {
ID uint64 `url:"id,omitempty"`
Name string `url:"name,omitempty"`
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
}
CommandEditRequest struct {
BotID uint64 `url:"bot_id,omitempty" json:"bot_id"`
Name string `url:"name,omitempty" json:"name"`
Description string `url:"description,omitempty" json:"description"`
}
)
// Response types
type (
BotsResponseItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Description string `json:"description"` Description string `json:"description,omitempty"`
Events []string `json:"events,omitempty,brackets"` Events []string `json:"events,omitempty,brackets"`
ClientID string `json:"client_id"` ClientID string `json:"client_id,omitempty"`
AvatarUrl string `json:"avatar_url"` AvatarUrl string `json:"avatar_url,omitempty"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at,omitempty"`
UpdatedAt *string `json:"updated_at"` UpdatedAt string `json:"updated_at,omitempty"`
DeactivatedAt *string `json:"deactivated_at"` DeactivatedAt string `json:"deactivated_at,omitempty"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
IsSelf bool `json:"is_self"` IsSelf bool `json:"is_self"`
} }
type ChannelsResponse struct { ChannelResponseItem struct {
Channels []ChannelListItem
}
type ChannelListItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Type string `json:"type"` Type string `json:"type"`
Events []string `json:"events,omitempty,brackets"` Events []string `json:"events,omitempty,brackets"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt *string `json:"updated_at"` UpdatedAt string `json:"updated_at"`
ActivatedAt string `json:"activated_at"` ActivatedAt string `json:"activated_at"`
DeactivatedAt *string `json:"deactivated_at"` DeactivatedAt string `json:"deactivated_at"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
} }
type ManagersResponse struct { UsersResponseItem struct {
Managers []ManagersListItem
}
type ManagersListItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
ExternalID *string `json:"external_id,omitempty"` ExternalID string `json:"external_id,omitempty"`
Username *string `json:"username,omitempty"` Username string `json:"username,omitempty"`
FirstName *string `json:"first_name,omitempty"` FirstName string `json:"first_name,omitempty"`
LastName *string `json:"last_name,omitempty"` LastName string `json:"last_name,omitempty"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt *string `json:"updated_at,omitempty"` UpdatedAt string `json:"updated_at,omitempty"`
RevokedAt *string `json:"revoked_at,omitempty"` RevokedAt string `json:"revoked_at,omitempty"`
IsOnline bool `json:"is_online"` IsOnline bool `json:"is_online"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
Avatar *string `json:"avatar_url,omitempty"` Avatar string `json:"avatar_url,omitempty"`
} }
type CustomersResponse struct { CustomersResponseItem struct {
Customers []CustomersListItem
}
type CustomersListItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
ExternalID *string `json:"external_id,omitempty"` ExternalID string `json:"external_id,omitempty"`
ChannelId *uint64 `json:"channel_id,omitempty"` ChannelId uint64 `json:"channel_id,omitempty"`
Username *string `json:"username,omitempty"` Username string `json:"username,omitempty"`
FirstName *string `json:"first_name,omitempty"` FirstName string `json:"first_name,omitempty"`
LastName *string `json:"last_name,omitempty"` LastName string `json:"last_name,omitempty"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt *string `json:"updated_at,omitempty"` UpdatedAt string `json:"updated_at,omitempty"`
RevokedAt *string `json:"revoked_at,omitempty"` RevokedAt string `json:"revoked_at,omitempty"`
Avatar *string `json:"avatar_url,omitempty"` Avatar string `json:"avatar_url,omitempty"`
ProfileURL *string `json:"profile_url,omitempty"` ProfileURL string `json:"profile_url,omitempty"`
Country *string `json:"country,omitempty"` Country string `json:"country,omitempty"`
Language *string `json:"language,omitempty"` Language string `json:"language,omitempty"`
Phone *string `json:"phone,omitempty"` Phone string `json:"phone,omitempty"`
} }
type ChatsResponse struct { ChatResponseItem struct {
Chats []ChatListItem
}
type ChatListItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Avatar string `json:"avatar"`
Name string `json:"name"`
Channel Channel `json:"channel,omitempty"`
Customer UserRef `json:"customer"`
AuthorID uint64 `json:"author_id"`
LastMessage Message `json:"last_message"`
LastActivity string `json:"last_activity"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"` UpdatedAt string `json:"updated_at"`
Channel *string `json:"channel,omitempty"` }
ChannelId *uint64 `json:"channel_id,omitempty"`
}
type MembersResponse struct { MemberResponseItem struct {
Members []MemberListItem
}
type MemberListItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt *string `json:"updated_at,omitempty"` UpdatedAt string `json:"updated_at,omitempty"`
IsAuthor bool `json:"is_author"` IsAuthor bool `json:"is_author"`
State string `json:"state"` State string `json:"state"`
ChatID uint64 `json:"chat_id"` ChatID uint64 `json:"chat_id"`
UserID uint64 `json:"user_id"` UserID uint64 `json:"user_id"`
} }
type DialogsResponse struct { DialogResponseItem struct {
Dialogs []DialogListItem
}
type DialogListItem struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
ChatID uint64 `json:"chat_id"` ChatID uint64 `json:"chat_id"`
BotID *uint64 `json:"bot_id,omitempty"` BeginMessageID uint64 `json:"begin_message_id,omitempty"`
BeginMessageID *uint64 `json:"begin_message_id,omitempty"` EndingMessageID uint64 `json:"ending_message_id,omitempty"`
EndingMessageID *uint64 `json:"ending_message_id,omitempty"` BotID uint64 `json:"bot_id,omitempty"`
CreatedAt string `json:"created_at"` CreatedAt string `json:"created_at"`
UpdatedAt *string `json:"updated_at,omitempty"` UpdatedAt string `json:"updated_at,omitempty"`
ClosedAt *string `json:"closed_at,omitempty"` ClosedAt string `json:"closed_at,omitempty"`
IsAssign bool `json:"is_assign"` IsAssigned bool `json:"is_assigned"`
Responsible *Responsible `json:"responsible,omitempty"` Responsible Responsible `json:"responsible,omitempty"`
IsActive bool `json:"is_active"` IsActive bool `json:"is_active"`
} }
type MessagesResponse struct { DialogAssignResponse struct {
Messages []MessagesListItem Responsible Responsible `json:"responsible"`
} PreviousResponsible Responsible `json:"previous_responsible,omitempty"`
LeftManagerID uint64 `json:"left_manager_id,omitempty"`
IsReAssign bool `json:"is_reassign"`
}
type MessagesListItem struct { MessagesResponseItem struct {
Message
ChannelID uint64 `json:"channel_id,omitempty"`
ChannelSentAt string `json:"channel_sent_at,omitempty"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at"`
}
MessageSendResponse struct {
MessageID uint64 `json:"message_id"`
Time string `json:"time"`
}
CommandsResponseItem struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
CreatedAt string `json:"created_at"`
UpdatedAt string `json:"updated_at,omitempty"`
}
)
// Single entity types
type (
Message struct {
ID uint64 `json:"id"`
Time string `json:"time"`
Type string `json:"type"`
ChatID uint64 `json:"chat_id"`
IsRead bool `json:"is_read"`
Status string `json:"status"`
TextMessage
SystemMessage
}
TextMessage struct {
Scope string `json:"scope"`
Content string `json:"content"`
From UserRef `json:"from"`
Quote QuoteMessage `json:"quote"`
IsEdit bool `json:"is_edit"`
Actions []string `json:"actions"`
}
SystemMessage struct {
Action string `json:"action"`
Dialog SystemMessageDialog `json:"dialog,omitempty"`
User UserRef `json:"user,omitempty"`
}
SystemMessageDialog struct {
ID uint64 `json:"id"`
}
QuoteMessage struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Content string `json:"content"` Content string `json:"content"`
CreatedAt string `json:"created_at"` Time string `json:"time"`
UpdatedAt *string `json:"updated_at"` From UserRef `json:"from"`
Scope uint8 `json:"scope"` }
ChatID uint64 `json:"chat_id"`
Sender Sender `json:"sender"`
ChannelID *uint64 `json:"channel_id,omitempty"`
ChannelSentAt *string `json:"channel_sent_at,omitempty"`
QuoteMessageId *uint64 `json:"quote_message_id,omitempty"`
EditedAt *string `json:"edited_at,omitempty"`
DeletedAt *string `json:"deleted_at,omitempty"`
}
type MessageResponse struct { UserRef struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Time string `json:"content"` Avatar string `json:"avatar"`
}
type UpdateBotRequest struct {
Name string `json:"name,omitempty"`
Avatar *string `json:"avatar_url"`
Events []string `json:"events,omitempty,brackets"`
}
type Responsible struct {
Type string `json:"type"` Type string `json:"type"`
Name string `json:"name"`
Phone string `json:"phone,omitempty"`
Email string `json:"email,omitempty"`
}
Channel struct {
ID uint64 `json:"id"`
TransportID uint64 `json:"transport_id"`
Type string `json:"type"`
Supports ChannelSupports `json:"supports"`
}
ChannelSupports struct {
Messages []string `json:"messages"`
Statuses []string `json:"statuses"`
}
Responsible struct {
ID int64 `json:"id"` ID int64 `json:"id"`
AssignAt string `json:"assign_at"` Type string `json:"type"`
} AssignAt string `json:"assigned_at"`
}
type DialogResponsibleRequest struct { Command struct {
ManagerID int64 `json:"manager_id"` ID uint64
BotID int64 `json:"bot_id"` BotID uint64
} Name string
Description string
type AssignResponse struct { CreatedAt string
Responsible Responsible `json:"responsible"` UpdatedAt string
IsReAssign bool `json:"is_reassign"` }
PreviousResponsible *Responsible `json:"previous_responsible,omitempty"` )
LeftManagerID *uint64 `json:"left_manager_id,omitempty"`
}
type Sender struct {
ID int64
Type string
}