Mock data in tests (#76)
* mock all data in tests * update test matrix config
This commit is contained in:
parent
b5df3a70bc
commit
1306d648f6
6
.github/workflows/ci.yml
vendored
6
.github/workflows/ci.yml
vendored
@ -10,9 +10,6 @@ on:
|
||||
|
||||
env:
|
||||
GO111MODULE: on
|
||||
MG_URL: ${{ secrets.MG_URL }}
|
||||
MG_TOKEN: ${{ secrets.MG_TOKEN }}
|
||||
MG_CHANNEL: ${{ secrets.MG_CHANNEL }}
|
||||
|
||||
jobs:
|
||||
golangci:
|
||||
@ -31,9 +28,8 @@ jobs:
|
||||
name: Tests
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
max-parallel: 1
|
||||
matrix:
|
||||
go-version: ['1.11', '1.12', '1.13', '1.14', '1.15']
|
||||
go-version: ['1.11', '1.12', '1.13', '1.14', '1.15', '1.16', '1.17']
|
||||
steps:
|
||||
- name: Set up Go ${{ matrix.go-version }}
|
||||
uses: actions/setup-go@v2
|
||||
|
1
go.mod
1
go.mod
@ -5,4 +5,5 @@ go 1.11
|
||||
require (
|
||||
github.com/google/go-querystring v1.0.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
gopkg.in/h2non/gock.v1 v1.1.2
|
||||
)
|
||||
|
7
go.sum
7
go.sum
@ -2,13 +2,18 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
|
24
v1/client.go
24
v1/client.go
@ -7,18 +7,19 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
// New initialize client
|
||||
// New initialize client.
|
||||
func New(url string, token string) *MgClient {
|
||||
return NewWithClient(url, token, &http.Client{Timeout: time.Minute})
|
||||
}
|
||||
|
||||
// NewWithClient initializes client with provided http client
|
||||
// NewWithClient initializes client with provided http client.
|
||||
func NewWithClient(url string, token string, client *http.Client) *MgClient {
|
||||
return &MgClient{
|
||||
URL: url,
|
||||
@ -59,7 +60,7 @@ func (c *MgClient) TransportTemplates() ([]Template, int, error) {
|
||||
return resp, status, err
|
||||
}
|
||||
|
||||
// ActivateTransportChannel implements template activation
|
||||
// ActivateTemplate implements template activation
|
||||
//
|
||||
// Example:
|
||||
// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6")
|
||||
@ -140,7 +141,8 @@ func (c *MgClient) UpdateTemplate(request Template) (int, error) {
|
||||
return 0, errors.New("`ChannelID` and `Code` cannot be blank")
|
||||
}
|
||||
|
||||
data, status, err := c.PutRequest(fmt.Sprintf("/channels/%d/templates/%s", request.ChannelID, request.Code), outgoing)
|
||||
data, status, err := c.PutRequest(
|
||||
fmt.Sprintf("/channels/%d/templates/%s", request.ChannelID, url.PathEscape(request.Code)), outgoing)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
@ -165,7 +167,7 @@ func (c *MgClient) UpdateTemplate(request Template) (int, error) {
|
||||
// }
|
||||
func (c *MgClient) DeactivateTemplate(channelID uint64, templateCode string) (int, error) {
|
||||
data, status, err := c.DeleteRequest(
|
||||
fmt.Sprintf("/channels/%d/templates/%s", channelID, templateCode), []byte{})
|
||||
fmt.Sprintf("/channels/%d/templates/%s", channelID, url.PathEscape(templateCode)), []byte{})
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
@ -313,7 +315,7 @@ func (c *MgClient) UpdateTransportChannel(request Channel) (UpdateResponse, int,
|
||||
var resp UpdateResponse
|
||||
outgoing, _ := json.Marshal(&request)
|
||||
|
||||
data, status, err := c.PutRequest(fmt.Sprintf("/channels/%d", request.ID), []byte(outgoing))
|
||||
data, status, err := c.PutRequest(fmt.Sprintf("/channels/%d", request.ID), outgoing)
|
||||
if err != nil {
|
||||
return resp, status, err
|
||||
}
|
||||
@ -442,7 +444,7 @@ func (c *MgClient) UpdateMessages(request EditMessageRequest) (MessagesResponse,
|
||||
var resp MessagesResponse
|
||||
outgoing, _ := json.Marshal(&request)
|
||||
|
||||
data, status, err := c.PutRequest("/messages", []byte(outgoing))
|
||||
data, status, err := c.PutRequest("/messages", outgoing)
|
||||
if err != nil {
|
||||
return resp, status, err
|
||||
}
|
||||
@ -554,7 +556,7 @@ func (c *MgClient) DeleteMessage(request DeleteData) (*MessagesResponse, int, er
|
||||
|
||||
data, status, err := c.DeleteRequest(
|
||||
"/messages",
|
||||
[]byte(outgoing),
|
||||
outgoing,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, status, err
|
||||
@ -605,7 +607,7 @@ func (c *MgClient) GetFile(request string) (FullFileResponse, int, error) {
|
||||
return resp, status, err
|
||||
}
|
||||
|
||||
// UploadFile upload file
|
||||
// UploadFile upload file.
|
||||
func (c *MgClient) UploadFile(request io.Reader) (UploadFileResponse, int, error) {
|
||||
var resp UploadFileResponse
|
||||
|
||||
@ -625,7 +627,7 @@ func (c *MgClient) UploadFile(request io.Reader) (UploadFileResponse, int, error
|
||||
return resp, status, err
|
||||
}
|
||||
|
||||
// UploadFileByURL upload file by url
|
||||
// UploadFileByURL upload file by url.
|
||||
func (c *MgClient) UploadFileByURL(request UploadFileByUrlRequest) (UploadFileResponse, int, error) {
|
||||
var resp UploadFileResponse
|
||||
outgoing, _ := json.Marshal(&request)
|
||||
@ -658,7 +660,7 @@ func (c *MgClient) Error(info []byte) error {
|
||||
return errors.New(values[0].(string))
|
||||
}
|
||||
|
||||
// MakeTimestamp returns current unix timestamp
|
||||
// MakeTimestamp returns current unix timestamp.
|
||||
func MakeTimestamp() int64 {
|
||||
return time.Now().UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond))
|
||||
}
|
||||
|
@ -5,105 +5,113 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"gopkg.in/h2non/gock.v1"
|
||||
)
|
||||
|
||||
var (
|
||||
mgURL = os.Getenv("MG_URL")
|
||||
mgToken = os.Getenv("MG_TOKEN")
|
||||
channelID, _ = strconv.ParseUint(os.Getenv("MG_CHANNEL"), 10, 64)
|
||||
ext = strconv.FormatInt(time.Now().UTC().UnixNano(), 10)
|
||||
tplCode = fmt.Sprintf("testTemplate_%d", time.Now().UnixNano())
|
||||
tplChannel uint64 = 0
|
||||
)
|
||||
type MGClientTest struct {
|
||||
suite.Suite
|
||||
}
|
||||
|
||||
func client() *MgClient {
|
||||
c := New(mgURL, mgToken)
|
||||
func TestMGClient(t *testing.T) {
|
||||
suite.Run(t, new(MGClientTest))
|
||||
}
|
||||
|
||||
func (t *MGClientTest) client() *MgClient {
|
||||
c := New("https://mg-test.retailcrm.pro", "mg_token")
|
||||
c.Debug = true
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func templateChannel(t *testing.T) uint64 {
|
||||
if tplChannel == 0 {
|
||||
c := client()
|
||||
resp, _, err := c.ActivateTransportChannel(Channel{
|
||||
Type: "telegram",
|
||||
Name: "@test_channel_templates",
|
||||
func (t *MGClientTest) gock() *gock.Request {
|
||||
return gock.New("https://mg-test.retailcrm.pro").MatchHeader("x-transport-token", "mg_token")
|
||||
}
|
||||
|
||||
func (t *MGClientTest) transportURL(path string) string {
|
||||
return "/api/transport/v1/" + strings.TrimLeft(path, "/")
|
||||
}
|
||||
|
||||
func (t *MGClientTest) Test_TransportChannels() {
|
||||
c := t.client()
|
||||
chName := "WhatsApp Channel"
|
||||
createdAt := "2021-11-22T08:20:46.479979Z"
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Get(t.transportURL("channels")).
|
||||
Reply(http.StatusOK).
|
||||
JSON([]ChannelListItem{{
|
||||
ID: 1,
|
||||
ExternalID: "external_id",
|
||||
Type: "whatsapp",
|
||||
Name: &chName,
|
||||
Settings: ChannelSettings{
|
||||
Status: Status{
|
||||
Delivered: ChannelFeatureBoth,
|
||||
Read: ChannelFeatureBoth,
|
||||
Delivered: ChannelFeatureNone,
|
||||
Read: ChannelFeatureSend,
|
||||
},
|
||||
Text: ChannelSettingsText{
|
||||
Creating: ChannelFeatureBoth,
|
||||
Editing: ChannelFeatureBoth,
|
||||
Quoting: ChannelFeatureBoth,
|
||||
Deleting: ChannelFeatureBoth,
|
||||
MaxCharsCount: 5000,
|
||||
Deleting: ChannelFeatureReceive,
|
||||
MaxCharsCount: 4096,
|
||||
},
|
||||
Product: Product{
|
||||
Creating: ChannelFeatureBoth,
|
||||
Editing: ChannelFeatureBoth,
|
||||
Deleting: ChannelFeatureBoth,
|
||||
Creating: ChannelFeatureReceive,
|
||||
Editing: ChannelFeatureReceive,
|
||||
},
|
||||
Order: Order{
|
||||
Creating: ChannelFeatureBoth,
|
||||
Editing: ChannelFeatureBoth,
|
||||
Deleting: ChannelFeatureBoth,
|
||||
Creating: ChannelFeatureReceive,
|
||||
Editing: ChannelFeatureReceive,
|
||||
},
|
||||
File: ChannelSettingsFilesBase{
|
||||
Creating: ChannelFeatureBoth,
|
||||
Editing: ChannelFeatureBoth,
|
||||
Quoting: ChannelFeatureBoth,
|
||||
Deleting: ChannelFeatureBoth,
|
||||
Max: 1000000,
|
||||
CommentMaxCharsCount: 128,
|
||||
Deleting: ChannelFeatureReceive,
|
||||
Max: 1,
|
||||
},
|
||||
Image: ChannelSettingsFilesBase{
|
||||
Creating: ChannelFeatureBoth,
|
||||
Editing: ChannelFeatureBoth,
|
||||
Quoting: ChannelFeatureBoth,
|
||||
Deleting: ChannelFeatureBoth,
|
||||
Deleting: ChannelFeatureReceive,
|
||||
Max: 1, // nolint:gomnd
|
||||
},
|
||||
Suggestions: ChannelSettingsSuggestions{
|
||||
Text: ChannelFeatureBoth,
|
||||
Phone: ChannelFeatureBoth,
|
||||
Email: ChannelFeatureBoth,
|
||||
},
|
||||
CustomerExternalID: ChannelFeatureCustomerExternalIDPhone,
|
||||
SendingPolicy: SendingPolicy{
|
||||
NewCustomer: ChannelFeatureSendingPolicyTemplate,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
tplChannel = resp.ChannelID
|
||||
}
|
||||
|
||||
return tplChannel
|
||||
}
|
||||
|
||||
func TestMgClient_TransportChannels(t *testing.T) {
|
||||
c := client()
|
||||
CreatedAt: createdAt,
|
||||
UpdatedAt: &createdAt,
|
||||
ActivatedAt: createdAt,
|
||||
DeactivatedAt: nil,
|
||||
IsActive: true,
|
||||
}})
|
||||
|
||||
data, status, err := c.TransportChannels(Channels{Active: true})
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%d %v", status, err)
|
||||
}
|
||||
|
||||
t.Logf("Channels found: %v", len(data))
|
||||
t.Assert().Len(data, 1)
|
||||
}
|
||||
|
||||
func TestMgClient_ActivateTransportChannel(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_ActivateTransportChannel() {
|
||||
c := t.client()
|
||||
ch := Channel{
|
||||
ID: channelID,
|
||||
ID: 1,
|
||||
Type: "telegram",
|
||||
Name: "@my_shopping_bot",
|
||||
Settings: ChannelSettings{
|
||||
@ -135,17 +143,27 @@ func TestMgClient_ActivateTransportChannel(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Post(t.transportURL("channels")).
|
||||
Reply(http.StatusCreated).
|
||||
JSON(ActivateResponse{
|
||||
ChannelID: 1,
|
||||
ExternalID: "external_id_1",
|
||||
ActivatedAt: time.Now(),
|
||||
})
|
||||
|
||||
data, status, err := c.ActivateTransportChannel(ch)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusCreated, status)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%d %v", status, err)
|
||||
}
|
||||
|
||||
t.Logf("Activate selected channel: %v", data.ChannelID)
|
||||
t.Assert().Equal(uint64(1), data.ChannelID)
|
||||
t.Assert().Equal("external_id_1", data.ExternalID)
|
||||
t.Assert().NotEmpty(data.ActivatedAt.String())
|
||||
}
|
||||
|
||||
func TestMgClient_ActivateNewTransportChannel(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_ActivateNewTransportChannel() {
|
||||
c := t.client()
|
||||
ch := Channel{
|
||||
Type: "telegram",
|
||||
Name: "@my_shopping_bot",
|
||||
@ -177,31 +195,44 @@ func TestMgClient_ActivateNewTransportChannel(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
|
||||
t.gock().
|
||||
Post(t.transportURL("channels")).
|
||||
Reply(http.StatusCreated).
|
||||
JSON(ActivateResponse{
|
||||
ChannelID: 1,
|
||||
ExternalID: "external_id_1",
|
||||
ActivatedAt: time.Now(),
|
||||
})
|
||||
|
||||
t.gock().
|
||||
Delete(t.transportURL("channels/1")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(DeleteResponse{
|
||||
ChannelID: 1,
|
||||
DeactivatedAt: time.Now(),
|
||||
})
|
||||
|
||||
data, status, err := c.ActivateTransportChannel(ch)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusCreated, status)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%d %v", status, err)
|
||||
}
|
||||
|
||||
t.Logf("New channel ID %v", data.ChannelID)
|
||||
t.Assert().Equal(uint64(1), data.ChannelID)
|
||||
t.Assert().Equal("external_id_1", data.ExternalID)
|
||||
t.Assert().NotEmpty(data.ActivatedAt.String())
|
||||
|
||||
deleteData, status, err := c.DeactivateTransportChannel(data.ChannelID)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%d %v", status, err)
|
||||
}
|
||||
|
||||
if deleteData.DeactivatedAt.String() == "" {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Deactivate new channel with ID %v", deleteData.ChannelID)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().NotEmpty(deleteData.DeactivatedAt.String())
|
||||
t.Assert().Equal(uint64(1), deleteData.ChannelID)
|
||||
}
|
||||
|
||||
func TestMgClient_UpdateTransportChannel(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_UpdateTransportChannel() {
|
||||
c := t.client()
|
||||
ch := Channel{
|
||||
ID: channelID,
|
||||
ID: 1,
|
||||
Name: "@my_shopping_bot_2",
|
||||
Settings: ChannelSettings{
|
||||
Status: Status{
|
||||
@ -231,44 +262,79 @@ func TestMgClient_UpdateTransportChannel(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Put(t.transportURL("channels/1")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(UpdateResponse{
|
||||
ChannelID: uint64(1),
|
||||
ExternalID: "external_id_1",
|
||||
UpdatedAt: time.Now(),
|
||||
})
|
||||
|
||||
data, status, err := c.UpdateTransportChannel(ch)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Update selected channel: %v", data.ChannelID)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().Equal(uint64(1), data.ChannelID)
|
||||
t.Assert().Equal("external_id_1", data.ExternalID)
|
||||
t.Assert().NotEmpty(data.UpdatedAt.String())
|
||||
}
|
||||
|
||||
func TestMgClient_TransportTemplates(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_TransportTemplates() {
|
||||
c := t.client()
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Get(t.transportURL("templates")).
|
||||
Reply(http.StatusOK).
|
||||
JSON([]Template{{
|
||||
Code: "tpl_code",
|
||||
ChannelID: 1,
|
||||
Name: "Test Template",
|
||||
Enabled: true,
|
||||
Type: TemplateTypeText,
|
||||
Template: []TemplateItem{
|
||||
{
|
||||
Type: TemplateItemTypeText,
|
||||
Text: "Hello, ",
|
||||
},
|
||||
{
|
||||
Type: TemplateItemTypeVar,
|
||||
VarType: TemplateVarFirstName,
|
||||
},
|
||||
{
|
||||
Type: TemplateItemTypeText,
|
||||
Text: "! We're glad to see you back in our store.",
|
||||
},
|
||||
},
|
||||
}})
|
||||
|
||||
data, status, err := c.TransportTemplates()
|
||||
assert.NoError(t, err, fmt.Sprintf("%d %s", status, err))
|
||||
|
||||
t.Logf("Templates found: %#v", len(data))
|
||||
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().Len(data, 1)
|
||||
|
||||
for _, item := range data {
|
||||
for _, tpl := range item.Template {
|
||||
if tpl.Type == TemplateItemTypeText {
|
||||
assert.Empty(t, tpl.VarType)
|
||||
t.Assert().Empty(tpl.VarType)
|
||||
} else {
|
||||
assert.Empty(t, tpl.Text)
|
||||
assert.NotEmpty(t, tpl.VarType)
|
||||
t.Assert().Empty(tpl.Text)
|
||||
t.Assert().NotEmpty(tpl.VarType)
|
||||
|
||||
if _, ok := templateVarAssoc[tpl.VarType]; !ok {
|
||||
t.Errorf("unknown TemplateVar type %s", tpl.VarType)
|
||||
t.T().Errorf("unknown TemplateVar type %s", tpl.VarType)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMgClient_ActivateTemplate(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_ActivateTemplate() {
|
||||
c := t.client()
|
||||
req := ActivateTemplateRequest{
|
||||
Code: tplCode,
|
||||
Name: tplCode,
|
||||
Code: "tplCode",
|
||||
Name: "tplCode",
|
||||
Type: TemplateTypeText,
|
||||
Template: []TemplateItem{
|
||||
{
|
||||
@ -286,17 +352,22 @@ func TestMgClient_ActivateTemplate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
status, err := c.ActivateTemplate(templateChannel(t), req)
|
||||
assert.NoError(t, err, fmt.Sprintf("%d %s", status, err))
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Post("/channels/1/templates").
|
||||
Reply(http.StatusCreated).
|
||||
JSON(map[string]interface{}{})
|
||||
|
||||
t.Logf("Activated template with code `%s`", req.Code)
|
||||
status, err := c.ActivateTemplate(1, req)
|
||||
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
||||
t.Assert().Equal(http.StatusCreated, status)
|
||||
}
|
||||
|
||||
func TestMgClient_UpdateTemplate(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_UpdateTemplate() {
|
||||
c := t.client()
|
||||
tpl := Template{
|
||||
Code: tplCode,
|
||||
ChannelID: templateChannel(t),
|
||||
Code: "encodable#code",
|
||||
ChannelID: 1,
|
||||
Name: "updated name",
|
||||
Enabled: true,
|
||||
Type: TemplateTypeText,
|
||||
@ -316,21 +387,36 @@ func TestMgClient_UpdateTemplate(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
|
||||
t.gock().
|
||||
Filter(func(r *http.Request) bool {
|
||||
return r.Method == http.MethodPut &&
|
||||
r.URL.Path == "/api/transport/v1/channels/1/templates/encodable#code"
|
||||
}).
|
||||
Reply(http.StatusOK).
|
||||
JSON(map[string]interface{}{})
|
||||
|
||||
t.gock().
|
||||
Get(t.transportURL("templates")).
|
||||
Reply(http.StatusOK).
|
||||
JSON([]Template{tpl})
|
||||
|
||||
status, err := c.UpdateTemplate(tpl)
|
||||
assert.NoError(t, err, fmt.Sprintf("%d %s", status, err))
|
||||
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
||||
|
||||
templates, status, err := c.TransportTemplates()
|
||||
assert.NoError(t, err, fmt.Sprintf("%d %s", status, err))
|
||||
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
||||
|
||||
for _, template := range templates {
|
||||
if template.Code == tpl.Code {
|
||||
assert.Equal(t, tpl.Name, template.Name)
|
||||
t.Assert().Equal(tpl.Name, template.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMgClient_UpdateTemplateFail(t *testing.T) {
|
||||
c := client()
|
||||
func (t *MGClientTest) Test_UpdateTemplateFail() {
|
||||
c := t.client()
|
||||
tpl := Template{
|
||||
Name: "updated name",
|
||||
Enabled: true,
|
||||
@ -351,23 +437,39 @@ func TestMgClient_UpdateTemplateFail(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Reply(http.StatusBadRequest).
|
||||
JSON(map[string][]string{
|
||||
"errors": {"Some weird error message..."},
|
||||
})
|
||||
|
||||
status, err := c.UpdateTemplate(tpl)
|
||||
assert.Error(t, err, fmt.Sprintf("%d %s", status, err))
|
||||
t.Assert().Error(err, fmt.Sprintf("%d %s", status, err))
|
||||
}
|
||||
|
||||
func TestMgClient_DeactivateTemplate(t *testing.T) {
|
||||
c := client()
|
||||
status, err := c.DeactivateTemplate(templateChannel(t), tplCode)
|
||||
assert.NoError(t, err, fmt.Sprintf("%d %s", status, err))
|
||||
func (t *MGClientTest) Test_DeactivateTemplate() {
|
||||
c := t.client()
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Filter(func(r *http.Request) bool {
|
||||
return r.Method == http.MethodDelete &&
|
||||
r.URL.Path == t.transportURL("channels/1/templates/test_template#code")
|
||||
}).
|
||||
Reply(http.StatusOK).
|
||||
JSON(map[string]interface{}{})
|
||||
|
||||
status, err := c.DeactivateTemplate(1, "test_template#code")
|
||||
t.Assert().NoError(err, fmt.Sprintf("%d %s", status, err))
|
||||
}
|
||||
|
||||
func TestMgClient_TextMessages(t *testing.T) {
|
||||
c := client()
|
||||
t.Logf("%v", ext)
|
||||
func (t *MGClientTest) Test_TextMessages() {
|
||||
c := t.client()
|
||||
|
||||
snd := SendData{
|
||||
Message: Message{
|
||||
ExternalID: ext,
|
||||
ExternalID: "external_id",
|
||||
Type: MsgTypeText,
|
||||
Text: "hello!",
|
||||
},
|
||||
@ -377,38 +479,61 @@ func TestMgClient_TextMessages(t *testing.T) {
|
||||
Nickname: "octopus",
|
||||
Firstname: "Joe",
|
||||
},
|
||||
Channel: channelID,
|
||||
Channel: 1,
|
||||
ExternalChatID: "24798237492374",
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Post(t.transportURL("messages")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(MessagesResponse{
|
||||
MessageID: 1,
|
||||
Time: time.Now(),
|
||||
})
|
||||
|
||||
data, status, err := c.Messages(snd)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if data.Time.String() == "" {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message %v is sent", data.MessageID)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().NotEmpty(data.Time.String())
|
||||
t.Assert().Equal(1, data.MessageID)
|
||||
}
|
||||
|
||||
func TestMgClient_ImageMessages(t *testing.T) {
|
||||
c := client()
|
||||
t.Logf("%v", ext)
|
||||
func (t *MGClientTest) Test_ImageMessages() {
|
||||
c := t.client()
|
||||
|
||||
defer gock.Off()
|
||||
|
||||
t.gock().
|
||||
Post(t.transportURL("files/upload_by_url")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(UploadFileResponse{
|
||||
ID: "1",
|
||||
Hash: "1",
|
||||
Type: "image/png",
|
||||
MimeType: "",
|
||||
Size: 1024,
|
||||
CreatedAt: time.Now(),
|
||||
})
|
||||
|
||||
t.gock().
|
||||
Post(t.transportURL("messages")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(MessagesResponse{
|
||||
MessageID: 1,
|
||||
Time: time.Now(),
|
||||
})
|
||||
|
||||
uploadFileResponse, st, err := c.UploadFileByURL(UploadFileByUrlRequest{
|
||||
Url: "https://via.placeholder.com/1",
|
||||
})
|
||||
|
||||
if st != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, st)
|
||||
t.Assert().Equal("1", uploadFileResponse.ID)
|
||||
|
||||
snd := SendData{
|
||||
Message: Message{
|
||||
ExternalID: ext + "file",
|
||||
ExternalID: "file",
|
||||
Type: MsgTypeImage,
|
||||
Items: []Item{{ID: uploadFileResponse.ID}},
|
||||
},
|
||||
@ -418,135 +543,138 @@ func TestMgClient_ImageMessages(t *testing.T) {
|
||||
Nickname: "octopus",
|
||||
Firstname: "Joe",
|
||||
},
|
||||
Channel: channelID,
|
||||
Channel: 1,
|
||||
ExternalChatID: "24798237492374",
|
||||
}
|
||||
|
||||
data, status, err := c.Messages(snd)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if data.Time.String() == "" {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message %v is sent", data.MessageID)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().NotEmpty(data.Time.String())
|
||||
t.Assert().Equal(1, data.MessageID)
|
||||
}
|
||||
|
||||
func TestMgClient_UpdateMessages(t *testing.T) {
|
||||
c := client()
|
||||
t.Logf("%v", ext)
|
||||
func (t *MGClientTest) Test_UpdateMessages() {
|
||||
c := t.client()
|
||||
|
||||
sndU := EditMessageRequest{
|
||||
EditMessageRequestMessage{
|
||||
ExternalID: ext,
|
||||
ExternalID: "editing",
|
||||
Text: "hello hello!",
|
||||
},
|
||||
channelID,
|
||||
1,
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Put(t.transportURL("messages")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(MessagesResponse{
|
||||
MessageID: 1,
|
||||
Time: time.Now(),
|
||||
})
|
||||
|
||||
dataU, status, err := c.UpdateMessages(sndU)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if dataU.Time.String() == "" {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message %v updated", dataU.MessageID)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().NotEmpty(dataU.Time.String())
|
||||
t.Assert().Equal(1, dataU.MessageID)
|
||||
}
|
||||
|
||||
func TestMgClient_MarkMessageReadAndDelete(t *testing.T) {
|
||||
c := client()
|
||||
t.Logf("%v", ext)
|
||||
func (t *MGClientTest) Test_MarkMessageReadAndDelete() {
|
||||
c := t.client()
|
||||
|
||||
snd := MarkMessageReadRequest{
|
||||
MarkMessageReadRequestMessage{
|
||||
ExternalID: ext,
|
||||
ExternalID: "external_1",
|
||||
},
|
||||
channelID,
|
||||
1,
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Post(t.transportURL("messages/read")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(MarkMessageReadResponse{})
|
||||
|
||||
t.gock().
|
||||
Delete(t.transportURL("messages")).
|
||||
JSON(DeleteData{
|
||||
Message: Message{
|
||||
ExternalID: "deleted",
|
||||
},
|
||||
Channel: 1,
|
||||
}).
|
||||
Reply(http.StatusOK).
|
||||
JSON(MessagesResponse{
|
||||
MessageID: 2,
|
||||
Time: time.Now(),
|
||||
})
|
||||
|
||||
_, status, err := c.MarkMessageRead(snd)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message ext marked as read")
|
||||
|
||||
sndD := DeleteData{
|
||||
previousChatMessage, status, err := c.DeleteMessage(DeleteData{
|
||||
Message{
|
||||
ExternalID: ext,
|
||||
ExternalID: "deleted",
|
||||
},
|
||||
channelID,
|
||||
}
|
||||
|
||||
previousChatMessage, status, err := c.DeleteMessage(sndD)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message %v deleted", ext)
|
||||
if previousChatMessage != nil {
|
||||
t.Logf("Previous chat message %+v", *previousChatMessage)
|
||||
}
|
||||
|
||||
sndD = DeleteData{
|
||||
Message{
|
||||
ExternalID: ext + "file",
|
||||
},
|
||||
channelID,
|
||||
}
|
||||
|
||||
previousChatMessage, status, err = c.DeleteMessage(sndD)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message %v deleted", ext+"file")
|
||||
if previousChatMessage != nil {
|
||||
t.Logf("Previous chat message %+v", *previousChatMessage)
|
||||
}
|
||||
1,
|
||||
})
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().Equal(2, previousChatMessage.MessageID)
|
||||
}
|
||||
|
||||
func TestMgClient_DeactivateTransportChannel(t *testing.T) {
|
||||
c := client()
|
||||
deleteData, status, err := c.DeactivateTransportChannel(channelID)
|
||||
func (t *MGClientTest) Test_DeactivateTransportChannel() {
|
||||
c := t.client()
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("%d %v", status, err)
|
||||
}
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Delete(t.transportURL("channels/1")).
|
||||
Reply(http.StatusOK).
|
||||
JSON(DeleteResponse{
|
||||
ChannelID: 1,
|
||||
DeactivatedAt: time.Now(),
|
||||
})
|
||||
|
||||
if deleteData.DeactivatedAt.String() == "" {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Deactivate selected channel: %v", deleteData.ChannelID)
|
||||
deleteData, status, err := c.DeactivateTransportChannel(1)
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
t.Assert().NotEmpty(deleteData.DeactivatedAt.String())
|
||||
t.Assert().Equal(uint64(1), deleteData.ChannelID)
|
||||
}
|
||||
|
||||
func TestMgClient_UploadFile(t *testing.T) {
|
||||
c := client()
|
||||
t.Logf("%v", ext)
|
||||
func (t *MGClientTest) Test_UploadFile() {
|
||||
c := t.client()
|
||||
|
||||
// 1x1 png picture
|
||||
img := "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEX/TQBcNTh/AAAAAXRSTlPM0jRW/QAAAApJREFUeJxjYgAAAAYAAzY3fKgAAAAASUVORK5CYII="
|
||||
binary, err := base64.StdEncoding.DecodeString(img)
|
||||
if err != nil {
|
||||
t.Errorf("cannot convert base64 to binary: %s", err)
|
||||
t.T().Errorf("cannot convert base64 to binary: %s", err)
|
||||
}
|
||||
|
||||
resp := UploadFileResponse{
|
||||
ID: "1",
|
||||
Hash: "1",
|
||||
Type: "image/png",
|
||||
MimeType: "",
|
||||
Size: 1024,
|
||||
CreatedAt: time.Now(),
|
||||
}
|
||||
|
||||
defer gock.Off()
|
||||
t.gock().
|
||||
Post(t.transportURL("files/upload")).
|
||||
Body(bytes.NewReader(binary)).
|
||||
Reply(http.StatusOK).
|
||||
JSON(resp)
|
||||
|
||||
data, status, err := c.UploadFile(bytes.NewReader(binary))
|
||||
t.Require().NoError(err)
|
||||
t.Assert().Equal(http.StatusOK, status)
|
||||
|
||||
if status != http.StatusOK {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
t.Logf("Message %+v is sent", data)
|
||||
resp.CreatedAt = data.CreatedAt
|
||||
t.Assert().Equal(resp, data)
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
|
||||
var prefix = "/api/transport/v1"
|
||||
|
||||
// GetRequest implements GET Request
|
||||
// GetRequest implements GET Request.
|
||||
func (c *MgClient) GetRequest(url string, parameters []byte) ([]byte, int, error) {
|
||||
return makeRequest(
|
||||
"GET",
|
||||
@ -22,7 +22,7 @@ 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 io.Reader) ([]byte, int, error) {
|
||||
return makeRequest(
|
||||
"POST",
|
||||
@ -32,7 +32,7 @@ func (c *MgClient) PostRequest(url string, parameters io.Reader) ([]byte, int, e
|
||||
)
|
||||
}
|
||||
|
||||
// PutRequest implements PUT Request
|
||||
// PutRequest implements PUT Request.
|
||||
func (c *MgClient) PutRequest(url string, parameters []byte) ([]byte, int, error) {
|
||||
return makeRequest(
|
||||
"PUT",
|
||||
@ -42,7 +42,7 @@ func (c *MgClient) PutRequest(url string, parameters []byte) ([]byte, int, error
|
||||
)
|
||||
}
|
||||
|
||||
// DeleteRequest implements DELETE Request
|
||||
// DeleteRequest implements DELETE Request.
|
||||
func (c *MgClient) DeleteRequest(url string, parameters []byte) ([]byte, int, error) {
|
||||
return makeRequest(
|
||||
"DELETE",
|
||||
@ -63,7 +63,7 @@ func makeRequest(reqType, url string, buf io.Reader, c *MgClient) ([]byte, int,
|
||||
req.Header.Set("X-Transport-Token", c.Token)
|
||||
|
||||
if c.Debug {
|
||||
if strings.Index(url, "/files/upload") != -1 {
|
||||
if strings.Contains(url, "/files/upload") {
|
||||
log.Printf("MG TRANSPORT API Request: %s %s %s [file data]", reqType, url, c.Token)
|
||||
} else {
|
||||
log.Printf("MG TRANSPORT API Request: %s %s %s %v", reqType, url, c.Token, buf)
|
||||
|
@ -10,24 +10,24 @@ import (
|
||||
const TemplateTypeText = "text"
|
||||
|
||||
const (
|
||||
// TemplateItemTypeText is a type for text chunk in template
|
||||
// TemplateItemTypeText is a type for text chunk in template.
|
||||
TemplateItemTypeText uint8 = iota
|
||||
// TemplateItemTypeVar is a type for variable in template
|
||||
// TemplateItemTypeVar is a type for variable in template.
|
||||
TemplateItemTypeVar
|
||||
)
|
||||
|
||||
const (
|
||||
// TemplateVarCustom is a custom variable type
|
||||
// TemplateVarCustom is a custom variable type.
|
||||
TemplateVarCustom = "custom"
|
||||
// TemplateVarName is a name variable type
|
||||
// TemplateVarName is a name variable type.
|
||||
TemplateVarName = "name"
|
||||
// TemplateVarFirstName is a first name variable type
|
||||
// TemplateVarFirstName is a first name variable type.
|
||||
TemplateVarFirstName = "first_name"
|
||||
// TemplateVarLastName is a last name variable type
|
||||
// TemplateVarLastName is a last name variable type.
|
||||
TemplateVarLastName = "last_name"
|
||||
)
|
||||
|
||||
// templateVarAssoc for checking variable validity, only for internal use
|
||||
// templateVarAssoc for checking variable validity, only for internal use.
|
||||
var templateVarAssoc = map[string]interface{}{
|
||||
TemplateVarCustom: nil,
|
||||
TemplateVarName: nil,
|
||||
@ -35,7 +35,7 @@ var templateVarAssoc = map[string]interface{}{
|
||||
TemplateVarLastName: nil,
|
||||
}
|
||||
|
||||
// Template struct
|
||||
// Template struct.
|
||||
type Template struct {
|
||||
Code string `json:"code"`
|
||||
ChannelID uint64 `json:"channel_id,omitempty"`
|
||||
@ -45,14 +45,14 @@ type Template struct {
|
||||
Template []TemplateItem `json:"template"`
|
||||
}
|
||||
|
||||
// TemplateItem is a part of template
|
||||
// TemplateItem is a part of template.
|
||||
type TemplateItem struct {
|
||||
Type uint8
|
||||
Text string
|
||||
VarType string
|
||||
}
|
||||
|
||||
// MarshalJSON controls how TemplateItem will be marshaled into JSON
|
||||
// MarshalJSON controls how TemplateItem will be marshaled into JSON.
|
||||
func (t TemplateItem) MarshalJSON() ([]byte, error) {
|
||||
switch t.Type {
|
||||
case TemplateItemTypeText:
|
||||
@ -71,7 +71,7 @@ func (t TemplateItem) MarshalJSON() ([]byte, error) {
|
||||
return nil, errors.New("unknown TemplateItem type")
|
||||
}
|
||||
|
||||
// UnmarshalJSON will correctly unmarshal TemplateItem
|
||||
// UnmarshalJSON will correctly unmarshal TemplateItem.
|
||||
func (t *TemplateItem) UnmarshalJSON(b []byte) error {
|
||||
var obj interface{}
|
||||
err := json.Unmarshal(b, &obj)
|
||||
|
162
v1/types.go
162
v1/types.go
@ -7,62 +7,62 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//noinspection ALL
|
||||
// noinspection ALL.
|
||||
const (
|
||||
// ChannelFeatureNone channel can not implement feature
|
||||
// ChannelFeatureNone channel can not implement feature.
|
||||
ChannelFeatureNone string = "none"
|
||||
// ChannelFeatureReceive channel implement feature on receive
|
||||
// ChannelFeatureReceive channel implement feature on receive.
|
||||
ChannelFeatureReceive string = "receive"
|
||||
// ChannelFeatureSend channel implement feature on send
|
||||
// ChannelFeatureSend channel implement feature on send.
|
||||
ChannelFeatureSend string = "send"
|
||||
// ChannelFeatureBoth channel implement feature on both directions
|
||||
// ChannelFeatureBoth channel implement feature on both directions.
|
||||
ChannelFeatureBoth string = "both"
|
||||
// ChannelFeatureAny channel implement feature on any
|
||||
// ChannelFeatureAny channel implement feature on any.
|
||||
ChannelFeatureAny string = "any"
|
||||
// ChannelFeatureSendingPolicyNo channel can not implement feature
|
||||
// ChannelFeatureSendingPolicyNo channel can not implement feature.
|
||||
ChannelFeatureSendingPolicyNo string = "no"
|
||||
// ChannelFeatureSendingPolicyTemplate channel can implement template
|
||||
// ChannelFeatureSendingPolicyTemplate channel can implement template.
|
||||
ChannelFeatureSendingPolicyTemplate string = "template"
|
||||
// ChannelFeatureCustomerExternalIDPhone customer externalId is phone
|
||||
// ChannelFeatureCustomerExternalIDPhone customer externalId is phone.
|
||||
ChannelFeatureCustomerExternalIDPhone string = "phone"
|
||||
|
||||
// MsgTypeText text message
|
||||
// MsgTypeText text message.
|
||||
MsgTypeText string = "text"
|
||||
// MsgTypeSystem system message
|
||||
// MsgTypeSystem system message.
|
||||
MsgTypeSystem string = "system"
|
||||
// MsgTypeCommand command (for bots)
|
||||
// MsgTypeCommand command (for bots).
|
||||
MsgTypeCommand string = "command"
|
||||
// MsgTypeOrder order card
|
||||
// MsgTypeOrder order card.
|
||||
MsgTypeOrder string = "order"
|
||||
// MsgTypeProduct product card
|
||||
// MsgTypeProduct product card.
|
||||
MsgTypeProduct string = "product"
|
||||
// MsgTypeFile file card
|
||||
// MsgTypeFile file card.
|
||||
MsgTypeFile string = "file"
|
||||
// MsgTypeImage image card
|
||||
// MsgTypeImage image card.
|
||||
MsgTypeImage string = "image"
|
||||
// MsgTypeAudio audio
|
||||
// MsgTypeAudio audio.
|
||||
MsgTypeAudio string = "audio"
|
||||
|
||||
// MsgOrderStatusCodeNew order status group new
|
||||
// MsgOrderStatusCodeNew order status group new.
|
||||
MsgOrderStatusCodeNew = "new"
|
||||
// MsgOrderStatusCodeApproval order status group approval
|
||||
// MsgOrderStatusCodeApproval order status group approval.
|
||||
MsgOrderStatusCodeApproval = "approval"
|
||||
// MsgOrderStatusCodeAssembling order status group assembling
|
||||
// MsgOrderStatusCodeAssembling order status group assembling.
|
||||
MsgOrderStatusCodeAssembling = "assembling"
|
||||
// MsgOrderStatusCodeDelivery order status group delivery
|
||||
// MsgOrderStatusCodeDelivery order status group delivery.
|
||||
MsgOrderStatusCodeDelivery = "delivery"
|
||||
// MsgOrderStatusCodeComplete order status group complete
|
||||
// MsgOrderStatusCodeComplete order status group complete.
|
||||
MsgOrderStatusCodeComplete = "complete"
|
||||
// MsgOrderStatusCodeCancel order status group cancel
|
||||
// MsgOrderStatusCodeCancel order status group cancel.
|
||||
MsgOrderStatusCodeCancel = "cancel"
|
||||
|
||||
FileSizeLimit = 20 * 1024 * 1024
|
||||
)
|
||||
|
||||
const (
|
||||
// OriginatorCustomer means message was created by customer
|
||||
// OriginatorCustomer means message was created by customer.
|
||||
OriginatorCustomer Originator = iota + 1
|
||||
// OriginatorChannel means message was created by channel, for example via messenger mobile application
|
||||
// OriginatorChannel means message was created by channel, for example via messenger mobile application.
|
||||
OriginatorChannel
|
||||
)
|
||||
|
||||
@ -70,13 +70,13 @@ type ErrorType string
|
||||
|
||||
const (
|
||||
GeneralError ErrorType = "general"
|
||||
CustomerNotExistsError = "customer_not_exists"
|
||||
ReplyTimedOutError = "reply_timed_out"
|
||||
SpamSuspicionError = "spam_suspicion"
|
||||
AccessRestrictedError = "access_restricted"
|
||||
CustomerNotExistsError ErrorType = "customer_not_exists"
|
||||
ReplyTimedOutError ErrorType = "reply_timed_out"
|
||||
SpamSuspicionError ErrorType = "spam_suspicion"
|
||||
AccessRestrictedError ErrorType = "access_restricted"
|
||||
)
|
||||
|
||||
// MgClient type
|
||||
// MgClient type.
|
||||
type MgClient struct {
|
||||
URL string `json:"url"`
|
||||
Token string `json:"token"`
|
||||
@ -84,17 +84,17 @@ type MgClient struct {
|
||||
httpClient *http.Client `json:"-"`
|
||||
}
|
||||
|
||||
// Channel type
|
||||
// Channel type.
|
||||
type Channel struct {
|
||||
ID uint64 `json:"id,omitempty"`
|
||||
ExternalID string `json:"external_id,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
AvatarUrl string `json:"avatar_url,omitempty"`
|
||||
Settings ChannelSettings `json:"settings,omitempty,brackets"`
|
||||
Settings ChannelSettings `json:"settings,omitempty"`
|
||||
}
|
||||
|
||||
// ChannelSettings struct
|
||||
// ChannelSettings struct.
|
||||
type ChannelSettings struct {
|
||||
Status Status `json:"status"`
|
||||
Text ChannelSettingsText `json:"text"`
|
||||
@ -107,27 +107,27 @@ type ChannelSettings struct {
|
||||
Suggestions ChannelSettingsSuggestions `json:"suggestions,omitempty"`
|
||||
}
|
||||
|
||||
// Product type
|
||||
// Product type.
|
||||
type Product struct {
|
||||
Creating string `json:"creating,omitempty"`
|
||||
Editing string `json:"editing,omitempty"`
|
||||
Deleting string `json:"deleting,omitempty"`
|
||||
}
|
||||
|
||||
// Order type
|
||||
// Order type.
|
||||
type Order struct {
|
||||
Creating string `json:"creating,omitempty"`
|
||||
Editing string `json:"editing,omitempty"`
|
||||
Deleting string `json:"deleting,omitempty"`
|
||||
}
|
||||
|
||||
// Status struct
|
||||
// Status struct.
|
||||
type Status struct {
|
||||
Delivered string `json:"delivered,omitempty"`
|
||||
Read string `json:"read,omitempty"`
|
||||
}
|
||||
|
||||
// ChannelSettingsText struct
|
||||
// ChannelSettingsText struct.
|
||||
type ChannelSettingsText struct {
|
||||
Creating string `json:"creating,omitempty"`
|
||||
Editing string `json:"editing,omitempty"`
|
||||
@ -136,7 +136,7 @@ type ChannelSettingsText struct {
|
||||
MaxCharsCount uint16 `json:"max_chars_count,omitempty"`
|
||||
}
|
||||
|
||||
// ChannelSettingsFilesBase struct
|
||||
// ChannelSettingsFilesBase struct.
|
||||
type ChannelSettingsFilesBase struct {
|
||||
Creating string `json:"creating,omitempty"`
|
||||
Editing string `json:"editing,omitempty"`
|
||||
@ -158,7 +158,7 @@ type ChannelSettingsSuggestions struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
}
|
||||
|
||||
// FullFileResponse uploaded file data
|
||||
// FullFileResponse uploaded file data.
|
||||
type FullFileResponse struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
@ -166,7 +166,7 @@ type FullFileResponse struct {
|
||||
Url string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// UploadFileResponse uploaded file data
|
||||
// UploadFileResponse uploaded file data.
|
||||
type UploadFileResponse struct {
|
||||
ID string `json:"id"`
|
||||
Hash string `json:"hash"`
|
||||
@ -178,38 +178,38 @@ type UploadFileResponse struct {
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// FileMeta file metadata
|
||||
// FileMeta file metadata.
|
||||
type FileMeta struct {
|
||||
Width *int `json:"width,omitempty"`
|
||||
Height *int `json:"height,omitempty"`
|
||||
}
|
||||
|
||||
// UploadFileByUrlRequest file url to upload
|
||||
// UploadFileByUrlRequest file url to upload.
|
||||
type UploadFileByUrlRequest struct {
|
||||
Url string `json:"url"`
|
||||
}
|
||||
|
||||
// ActivateResponse channel activation response
|
||||
// ActivateResponse channel activation response.
|
||||
type ActivateResponse struct {
|
||||
ChannelID uint64 `json:"id"`
|
||||
ExternalID string `json:"external_id"`
|
||||
ActivatedAt time.Time `json:"activated_at"`
|
||||
}
|
||||
|
||||
// UpdateResponse channel update response
|
||||
// UpdateResponse channel update response.
|
||||
type UpdateResponse struct {
|
||||
ChannelID uint64 `json:"id"`
|
||||
ExternalID string `json:"external_id"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// DeleteResponse channel deactivation response
|
||||
// DeleteResponse channel deactivation response.
|
||||
type DeleteResponse struct {
|
||||
ChannelID uint64 `json:"id"`
|
||||
DeactivatedAt time.Time `json:"deactivated_at"`
|
||||
}
|
||||
|
||||
// ChannelListItem response struct
|
||||
// ChannelListItem response struct.
|
||||
type ChannelListItem struct {
|
||||
ID uint64 `json:"id"`
|
||||
ExternalID string `json:"external_id"`
|
||||
@ -223,7 +223,7 @@ type ChannelListItem struct {
|
||||
IsActive bool `json:"is_active"`
|
||||
}
|
||||
|
||||
// Channels request type
|
||||
// Channels request type.
|
||||
type Channels struct {
|
||||
ID int `url:"id,omitempty" json:"id,omitempty"`
|
||||
Types []string `url:"types,omitempty" json:"types,omitempty"`
|
||||
@ -235,7 +235,7 @@ type Channels struct {
|
||||
Limit int `url:"limit,omitempty" json:"limit,omitempty"`
|
||||
}
|
||||
|
||||
// Customer struct
|
||||
// Customer struct.
|
||||
type Customer struct {
|
||||
ExternalID string `json:"external_id"`
|
||||
Nickname string `json:"nickname"`
|
||||
@ -249,7 +249,7 @@ type Customer struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
}
|
||||
|
||||
// Message struct
|
||||
// Message struct.
|
||||
type Message struct {
|
||||
ExternalID string `json:"external_id"`
|
||||
Type string `json:"type,omitempty"`
|
||||
@ -258,26 +258,26 @@ type Message struct {
|
||||
Items []Item `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// SendMessage struct
|
||||
// SendMessage struct.
|
||||
type SendMessage struct {
|
||||
Message
|
||||
SentAt time.Time `json:"sent_at,omitempty"`
|
||||
}
|
||||
|
||||
// EditMessageRequest type
|
||||
// EditMessageRequest type.
|
||||
type EditMessageRequest struct {
|
||||
Message EditMessageRequestMessage `json:"message"`
|
||||
Channel uint64 `json:"channel"`
|
||||
}
|
||||
|
||||
// EditMessageRequestMessage type
|
||||
// EditMessageRequestMessage type.
|
||||
type EditMessageRequestMessage struct {
|
||||
ExternalID string `json:"external_id"`
|
||||
Text string `json:"text"`
|
||||
EditedAt int64 `json:"edited_at"`
|
||||
}
|
||||
|
||||
// SendData struct
|
||||
// SendData struct.
|
||||
type SendData struct {
|
||||
Message Message `json:"message"`
|
||||
Originator Originator `json:"originator,omitempty"`
|
||||
@ -288,51 +288,51 @@ type SendData struct {
|
||||
ReplyDeadline *time.Time `json:"reply_deadline,omitempty"`
|
||||
}
|
||||
|
||||
// Item struct
|
||||
// Item struct.
|
||||
type Item struct {
|
||||
ID string `json:"id"`
|
||||
Caption string `json:"caption"`
|
||||
}
|
||||
|
||||
// SendMessageRequestQuote type
|
||||
// SendMessageRequestQuote type.
|
||||
type SendMessageRequestQuote struct {
|
||||
ExternalID string `json:"external_id"`
|
||||
}
|
||||
|
||||
// MarkMessageReadResponse type
|
||||
// MarkMessageReadResponse type.
|
||||
type MarkMessageReadResponse struct{}
|
||||
|
||||
// MarkMessageReadRequest type
|
||||
// MarkMessageReadRequest type.
|
||||
type MarkMessageReadRequest struct {
|
||||
Message MarkMessageReadRequestMessage `json:"message"`
|
||||
ChannelID uint64 `json:"channel_id"`
|
||||
}
|
||||
|
||||
// MarkMessageReadRequestMessage type
|
||||
// MarkMessageReadRequestMessage type.
|
||||
type MarkMessageReadRequestMessage struct {
|
||||
ExternalID string `json:"external_id"`
|
||||
}
|
||||
|
||||
// AckMessageRequest type
|
||||
// AckMessageRequest type.
|
||||
type AckMessageRequest struct {
|
||||
ExternalMessageID string `json:"external_message_id"`
|
||||
Channel uint64 `json:"channel"`
|
||||
Error *MessageSentError `json:"error,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteData struct
|
||||
// DeleteData struct.
|
||||
type DeleteData struct {
|
||||
Message Message `json:"message"`
|
||||
Channel uint64 `json:"channel"`
|
||||
}
|
||||
|
||||
// MessagesResponse message event response
|
||||
// MessagesResponse message event response.
|
||||
type MessagesResponse struct {
|
||||
MessageID int `json:"message_id,omitempty"`
|
||||
Time time.Time `json:"time,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookRequest type
|
||||
// WebhookRequest type.
|
||||
type WebhookRequest struct {
|
||||
Type string `json:"type"`
|
||||
Meta TransportRequestMeta `json:"meta"`
|
||||
@ -340,20 +340,20 @@ type WebhookRequest struct {
|
||||
}
|
||||
|
||||
// WebhookMessageSentResponse type
|
||||
// Consider using this structure while processing webhook request
|
||||
// Consider using this structure while processing webhook request.
|
||||
type WebhookMessageSentResponse struct {
|
||||
ExternalMessageID string `json:"external_message_id"`
|
||||
Error *MessageSentError `json:"error,omitempty"`
|
||||
Async bool `json:"async"`
|
||||
}
|
||||
|
||||
// MessageSentError type
|
||||
// MessageSentError type.
|
||||
type MessageSentError struct {
|
||||
Code ErrorType `json:"code"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// WebhookData request data
|
||||
// WebhookData request data.
|
||||
type WebhookData struct {
|
||||
ExternalUserID string `json:"external_user_id"`
|
||||
ExternalMessageID string `json:"external_message_id,omitempty"`
|
||||
@ -394,7 +394,7 @@ type TemplateInfo struct {
|
||||
Args []string `json:"args,omitempty"`
|
||||
}
|
||||
|
||||
// FileItem struct
|
||||
// FileItem struct.
|
||||
type FileItem struct {
|
||||
ID string `json:"id"`
|
||||
Size int `json:"size"`
|
||||
@ -403,20 +403,20 @@ type FileItem struct {
|
||||
Width *int `json:"width,omitempty"`
|
||||
}
|
||||
|
||||
// MessageDataUser user data from webhook
|
||||
// MessageDataUser user data from webhook.
|
||||
type MessageDataUser struct {
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
||||
// MessageDataBot bot data from webhook
|
||||
// MessageDataBot bot data from webhook.
|
||||
type MessageDataBot struct {
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
}
|
||||
|
||||
// MessageDataProduct product data from webhook
|
||||
// MessageDataProduct product data from webhook.
|
||||
type MessageDataProduct struct {
|
||||
ID uint64 `json:"id"`
|
||||
Name string `json:"name"`
|
||||
@ -429,7 +429,7 @@ type MessageDataProduct struct {
|
||||
Quantity *MessageDataOrderQuantity `json:"quantity,omitempty"`
|
||||
}
|
||||
|
||||
// MessageDataOrder order data from webhook
|
||||
// MessageDataOrder order data from webhook.
|
||||
type MessageDataOrder struct {
|
||||
Number string `json:"number"`
|
||||
Url string `json:"url,omitempty"`
|
||||
@ -442,13 +442,13 @@ type MessageDataOrder struct {
|
||||
Items []MessageDataOrderItem `json:"items,omitempty"`
|
||||
}
|
||||
|
||||
// MessageDataOrderStatus type
|
||||
// MessageDataOrderStatus type.
|
||||
type MessageDataOrderStatus struct {
|
||||
Code string `json:"code,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// MessageDataOrderItem type
|
||||
// MessageDataOrderItem type.
|
||||
type MessageDataOrderItem struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
@ -457,32 +457,32 @@ type MessageDataOrderItem struct {
|
||||
Price *MessageDataOrderCost `json:"price,omitempty"`
|
||||
}
|
||||
|
||||
// MessageDataOrderCost type
|
||||
// MessageDataOrderCost type.
|
||||
type MessageDataOrderCost struct {
|
||||
Value float32 `json:"value,omitempty"`
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
|
||||
// MessageDataOrderQuantity type
|
||||
// MessageDataOrderQuantity type.
|
||||
type MessageDataOrderQuantity struct {
|
||||
Value float32 `json:"value"`
|
||||
Unit string `json:"unit"`
|
||||
}
|
||||
|
||||
// MessageDataOrderPayment type
|
||||
// MessageDataOrderPayment type.
|
||||
type MessageDataOrderPayment struct {
|
||||
Name string `json:"name"`
|
||||
Status *MessageDataOrderPaymentStatus `json:"status"`
|
||||
Amount *MessageDataOrderCost `json:"amount"`
|
||||
}
|
||||
|
||||
// MessageDataOrderPaymentStatus type
|
||||
// MessageDataOrderPaymentStatus type.
|
||||
type MessageDataOrderPaymentStatus struct {
|
||||
Name string `json:"name"`
|
||||
Payed bool `json:"payed"`
|
||||
Paid bool `json:"paid"`
|
||||
}
|
||||
|
||||
// MessageDataOrderDelivery type
|
||||
// MessageDataOrderDelivery type.
|
||||
type MessageDataOrderDelivery struct {
|
||||
Name string `json:"name"`
|
||||
Price *MessageDataOrderCost `json:"price"`
|
||||
@ -490,7 +490,7 @@ type MessageDataOrderDelivery struct {
|
||||
Comment string `json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
// TransportRequestMeta request metadata
|
||||
// TransportRequestMeta request metadata.
|
||||
type TransportRequestMeta struct {
|
||||
ID uint64 `json:"id"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
@ -505,10 +505,10 @@ type ActivateTemplateRequest struct {
|
||||
|
||||
var ErrInvalidOriginator = errors.New("invalid originator")
|
||||
|
||||
// Originator of message
|
||||
// Originator of message.
|
||||
type Originator byte
|
||||
|
||||
// MarshalText marshals originator to text
|
||||
// MarshalText marshals originator to text.
|
||||
func (o Originator) MarshalText() ([]byte, error) {
|
||||
switch o {
|
||||
case OriginatorCustomer:
|
||||
|
@ -1,3 +1,4 @@
|
||||
//go:build !go1.14
|
||||
// +build !go1.14
|
||||
|
||||
package v1
|
||||
|
@ -1,3 +1,4 @@
|
||||
//go:build go1.14
|
||||
// +build go1.14
|
||||
|
||||
package v1
|
||||
|
Loading…
Reference in New Issue
Block a user