mirror of
https://github.com/retailcrm/mg-bot-api-client-go.git
synced 2025-04-11 04:50:58 +00:00
Compare commits
36 commits
Author | SHA1 | Date | |
---|---|---|---|
9e5fb7afec | |||
|
3b56a36b3b | ||
1ba7024ccc | |||
|
fe5c8e9676 | ||
e2205fb4d9 | |||
223e63b268 | |||
7cec2bb237 | |||
c338d2e19e | |||
a101bd502a | |||
021568afd8 | |||
f7e352a622 | |||
5466d2d1ad | |||
0e970386ce | |||
|
8b0193186b | ||
|
c7b7f73c4f | ||
|
22d56ef2dc | ||
|
f6affa2063 | ||
|
d5aa1a0794 | ||
|
bc9702741e | ||
|
46a262a5dc | ||
7b80d3d542 | |||
|
b0e374f88e | ||
8eb473d7d2 | |||
|
bbea93671e | ||
|
ca83218213 | ||
074f787d0f | |||
d01abbc1bb | |||
|
88eeda804b | ||
|
e090080325 | ||
|
3e9078ee86 | ||
|
de3eca3a55 | ||
|
73b06d5de4 | ||
3d84ddaee6 | |||
|
6090ceebcf | ||
506a6a1d61 | |||
|
272cdaa60c |
5 changed files with 380 additions and 144 deletions
18
.github/workflows/ci.yml
vendored
18
.github/workflows/ci.yml
vendored
|
@ -19,33 +19,33 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Set up latest Go 1.x version
|
- name: Set up Go 1.24
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: '1.17'
|
go-version: '1.24'
|
||||||
- name: Get dependencies
|
- name: Get dependencies
|
||||||
run: |
|
run: |
|
||||||
go mod tidy
|
go mod tidy
|
||||||
cp .env.dist .env
|
cp .env.dist .env
|
||||||
- name: Lint code with golangci-lint
|
- name: Lint code with golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v3
|
uses: golangci/golangci-lint-action@v6
|
||||||
with:
|
with:
|
||||||
version: v1.50.1
|
version: v1.62.2
|
||||||
only-new-issues: true
|
only-new-issues: true
|
||||||
tests:
|
tests:
|
||||||
name: Tests
|
name: Tests
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go-version: ['1.13', '1.14', '1.15', '1.16']
|
go-version: ['1.13', '1.14', '1.15', '1.16', '1.17', '1.18', '1.19', '1.20', '1.21', '1.22', '1.23', '1.24']
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go ${{ matrix.go-version }}
|
- name: Set up Go ${{ matrix.go-version }}
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go-version }}
|
go-version: ${{ matrix.go-version }}
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
- name: Get dependencies
|
- name: Get dependencies
|
||||||
run: |
|
run: |
|
||||||
go mod tidy
|
go mod tidy
|
||||||
|
|
|
@ -1,31 +1,15 @@
|
||||||
run:
|
run:
|
||||||
skip-dirs-use-default: true
|
|
||||||
allow-parallel-runners: true
|
allow-parallel-runners: true
|
||||||
|
modules-download-mode: readonly
|
||||||
|
|
||||||
output:
|
output:
|
||||||
format: colored-line-number
|
formats:
|
||||||
|
- format: colored-line-number
|
||||||
sort-results: true
|
sort-results: true
|
||||||
|
|
||||||
# Linters below do not support go1.18 yet because of generics.
|
|
||||||
# See https://github.com/golangci/golangci-lint/issues/2649
|
|
||||||
# - bodyclose
|
|
||||||
# - sqlclosecheck
|
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
- paralleltest
|
|
||||||
- tparallel
|
|
||||||
- asciicheck
|
|
||||||
- asasalint
|
|
||||||
- varnamelen
|
|
||||||
- reassign
|
|
||||||
- nilnil
|
|
||||||
- nilerr
|
|
||||||
- nakedret
|
|
||||||
- goprintffuncname
|
|
||||||
- typecheck
|
|
||||||
- errchkjson
|
|
||||||
- errcheck
|
- errcheck
|
||||||
- gosimple
|
- gosimple
|
||||||
- govet
|
- govet
|
||||||
|
@ -33,11 +17,12 @@ linters:
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- unused
|
- unused
|
||||||
- unparam
|
- unparam
|
||||||
|
- bodyclose
|
||||||
- dogsled
|
- dogsled
|
||||||
- dupl
|
- dupl
|
||||||
- errorlint
|
- errorlint
|
||||||
- exhaustive
|
- exhaustive
|
||||||
- exportloopref
|
- copyloopvar
|
||||||
- funlen
|
- funlen
|
||||||
- gocognit
|
- gocognit
|
||||||
- goconst
|
- goconst
|
||||||
|
@ -46,6 +31,7 @@ linters:
|
||||||
- godot
|
- godot
|
||||||
- goimports
|
- goimports
|
||||||
- revive
|
- revive
|
||||||
|
- mnd
|
||||||
- gosec
|
- gosec
|
||||||
- lll
|
- lll
|
||||||
- makezero
|
- makezero
|
||||||
|
@ -53,22 +39,21 @@ linters:
|
||||||
- nestif
|
- nestif
|
||||||
- prealloc
|
- prealloc
|
||||||
- predeclared
|
- predeclared
|
||||||
- exportloopref
|
- sqlclosecheck
|
||||||
- unconvert
|
- unconvert
|
||||||
- whitespace
|
- whitespace
|
||||||
|
- unused
|
||||||
|
- testifylint
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
govet:
|
govet:
|
||||||
check-shadowing: false
|
|
||||||
disable-all: true
|
disable-all: true
|
||||||
enable:
|
enable:
|
||||||
- assign
|
- assign
|
||||||
- atomic
|
- atomic
|
||||||
- atomicalign
|
|
||||||
- bools
|
- bools
|
||||||
- buildtag
|
- buildtag
|
||||||
- copylocks
|
- copylocks
|
||||||
- fieldalignment
|
|
||||||
- httpresponse
|
- httpresponse
|
||||||
- loopclosure
|
- loopclosure
|
||||||
- lostcancel
|
- lostcancel
|
||||||
|
@ -128,8 +113,6 @@ linters-settings:
|
||||||
- log.Printf
|
- log.Printf
|
||||||
- log.Println
|
- log.Println
|
||||||
- runtime/trace.Logf
|
- runtime/trace.Logf
|
||||||
unused:
|
|
||||||
check-exported: false
|
|
||||||
unparam:
|
unparam:
|
||||||
check-exported: false
|
check-exported: false
|
||||||
dogsled:
|
dogsled:
|
||||||
|
@ -138,8 +121,8 @@ linters-settings:
|
||||||
threshold: 200
|
threshold: 200
|
||||||
errorlint:
|
errorlint:
|
||||||
errorf: true
|
errorf: true
|
||||||
asserts: false
|
asserts: true
|
||||||
comparison: false
|
comparison: true
|
||||||
exhaustive:
|
exhaustive:
|
||||||
check-generated: false
|
check-generated: false
|
||||||
default-signifies-exhaustive: false
|
default-signifies-exhaustive: false
|
||||||
|
@ -161,25 +144,23 @@ linters-settings:
|
||||||
whitespace:
|
whitespace:
|
||||||
multi-if: false
|
multi-if: false
|
||||||
multi-func: false
|
multi-func: false
|
||||||
varnamelen:
|
|
||||||
max-distance: 10
|
|
||||||
ignore-map-index-ok: true
|
|
||||||
ignore-type-assert-ok: true
|
|
||||||
ignore-chan-recv-ok: true
|
|
||||||
ignore-decls:
|
|
||||||
- t *testing.T
|
|
||||||
- e error
|
|
||||||
- i int
|
|
||||||
issues:
|
issues:
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
- path: _test\.go
|
- path: _test\.go
|
||||||
linters:
|
linters:
|
||||||
|
- dupl
|
||||||
|
- mnd
|
||||||
- lll
|
- lll
|
||||||
|
- bodyclose
|
||||||
- errcheck
|
- errcheck
|
||||||
|
- sqlclosecheck
|
||||||
- misspell
|
- misspell
|
||||||
- ineffassign
|
- ineffassign
|
||||||
- whitespace
|
- whitespace
|
||||||
- makezero
|
- makezero
|
||||||
|
- maligned
|
||||||
|
- ifshort
|
||||||
- errcheck
|
- errcheck
|
||||||
- funlen
|
- funlen
|
||||||
- goconst
|
- goconst
|
||||||
|
@ -187,8 +168,6 @@ issues:
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- godot
|
- godot
|
||||||
- unused
|
- unused
|
||||||
- errchkjson
|
|
||||||
- varnamelen
|
|
||||||
exclude-use-default: true
|
exclude-use-default: true
|
||||||
exclude-case-sensitive: false
|
exclude-case-sensitive: false
|
||||||
max-issues-per-linter: 0
|
max-issues-per-linter: 0
|
||||||
|
@ -197,7 +176,4 @@ issues:
|
||||||
|
|
||||||
severity:
|
severity:
|
||||||
default-severity: error
|
default-severity: error
|
||||||
case-sensitive: false
|
case-sensitive: false
|
||||||
|
|
||||||
service:
|
|
||||||
golangci-lint-version: 1.50.x
|
|
67
v1/client.go
67
v1/client.go
|
@ -16,21 +16,21 @@ import (
|
||||||
|
|
||||||
type Option func(*MgClient)
|
type Option func(*MgClient)
|
||||||
|
|
||||||
// OptionHTTPClient set custom http.Client for MgClient
|
// OptionHTTPClient set custom http.Client for MgClient.
|
||||||
func OptionHTTPClient(client *http.Client) func(*MgClient) {
|
func OptionHTTPClient(client *http.Client) func(*MgClient) {
|
||||||
return func(c *MgClient) {
|
return func(c *MgClient) {
|
||||||
c.httpClient = client
|
c.httpClient = client
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OptionLogger sets the provided logger instance into the MgClient
|
// OptionLogger sets the provided logger instance into the MgClient.
|
||||||
func OptionLogger(logger BasicLogger) func(*MgClient) {
|
func OptionLogger(logger BasicLogger) func(*MgClient) {
|
||||||
return func(c *MgClient) {
|
return func(c *MgClient) {
|
||||||
c.logger = logger
|
c.logger = logger
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// OptionDebug enables debug mode for MgClient
|
// OptionDebug enables debug mode for MgClient.
|
||||||
func OptionDebug() func(*MgClient) {
|
func OptionDebug() func(*MgClient) {
|
||||||
return func(c *MgClient) {
|
return func(c *MgClient) {
|
||||||
c.Debug = true
|
c.Debug = true
|
||||||
|
@ -53,7 +53,7 @@ func New(url string, token string, opts ...Option) *MgClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithLogger sets the provided logger instance into the Client.
|
// WithLogger sets the provided logger instance into the Client.
|
||||||
// Deprecated: Use functional option OptionLogger instead
|
// Deprecated: Use functional option OptionLogger instead.
|
||||||
func (c *MgClient) WithLogger(logger BasicLogger) *MgClient {
|
func (c *MgClient) WithLogger(logger BasicLogger) *MgClient {
|
||||||
c.logger = logger
|
c.logger = logger
|
||||||
return c
|
return c
|
||||||
|
@ -912,8 +912,57 @@ func (c *MgClient) UploadFileByURL(request UploadFileByUrlRequest) (UploadFileRe
|
||||||
return resp, status, err
|
return resp, status, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateFileMetadata update file metadata
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// response, status, err := c.UpdateFileMetadata(UploadFileByUrlRequest{
|
||||||
|
// ID: "e038aa39-2338-4285-be86-e2a0bb424daa"
|
||||||
|
// Transcription: "demo transcription",
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// if err != nil {
|
||||||
|
// fmt.Printf("%v", err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// fmt.Printf("%s\n%s", response.ID, status)
|
||||||
|
func (c *MgClient) UpdateFileMetadata(request UpdateFileMetadataRequest) (UploadFileResponse, int, error) {
|
||||||
|
var resp UploadFileResponse
|
||||||
|
outgoing, err := json.Marshal(&request)
|
||||||
|
if err != nil {
|
||||||
|
return resp, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
data, status, err := c.PutRequest(fmt.Sprintf("/files/%s/meta", request.ID), outgoing)
|
||||||
|
if err != nil {
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if status != http.StatusOK {
|
||||||
|
return resp, status, c.Error(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
if e := json.Unmarshal(data, &resp); e != nil {
|
||||||
|
return resp, status, e
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, status, err
|
||||||
|
}
|
||||||
|
|
||||||
|
type wsParams struct {
|
||||||
|
options []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type WsParams interface {
|
||||||
|
apply(*wsParams)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c WsOption) apply(opts *wsParams) {
|
||||||
|
opts.options = append(opts.options, string(c))
|
||||||
|
}
|
||||||
|
|
||||||
// WsMeta let you receive url & headers to open web socket connection
|
// WsMeta let you receive url & headers to open web socket connection
|
||||||
func (c *MgClient) WsMeta(events []string) (string, http.Header, error) {
|
func (c *MgClient) WsMeta(events []string, urlParams ...WsParams) (string, http.Header, error) {
|
||||||
var url string
|
var url string
|
||||||
|
|
||||||
if len(events) < 1 {
|
if len(events) < 1 {
|
||||||
|
@ -923,6 +972,14 @@ func (c *MgClient) WsMeta(events []string) (string, http.Header, error) {
|
||||||
|
|
||||||
url = fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "wss", 1), prefix, "/ws?events=", strings.Join(events[:], ","))
|
url = fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "wss", 1), prefix, "/ws?events=", strings.Join(events[:], ","))
|
||||||
|
|
||||||
|
var params wsParams
|
||||||
|
for _, param := range urlParams {
|
||||||
|
param.apply(¶ms)
|
||||||
|
}
|
||||||
|
if len(params.options) > 0 {
|
||||||
|
url = fmt.Sprintf("%s&options=%s", url, strings.Join(params.options, ","))
|
||||||
|
}
|
||||||
|
|
||||||
if url == "" {
|
if url == "" {
|
||||||
err := errors.New("empty WS URL")
|
err := errors.New("empty WS URL")
|
||||||
return url, nil, err
|
return url, nil, err
|
||||||
|
|
|
@ -2,8 +2,12 @@ package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"compress/gzip"
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -69,7 +73,7 @@ func TestMgClient_Bots(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, bot := range data {
|
for _, bot := range data {
|
||||||
|
@ -148,7 +152,7 @@ func TestMgClient_Channels(t *testing.T) {
|
||||||
]`)
|
]`)
|
||||||
|
|
||||||
channels, status, err := c.Channels(ChannelsRequest{Active: 1})
|
channels, status, err := c.Channels(ChannelsRequest{Active: 1})
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, 200, status)
|
assert.Equal(t, 200, status)
|
||||||
assert.Len(t, channels, 1)
|
assert.Len(t, channels, 1)
|
||||||
|
|
||||||
|
@ -221,7 +225,7 @@ func TestMgClient_Users(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, user := range data {
|
for _, user := range data {
|
||||||
|
@ -231,9 +235,9 @@ func TestMgClient_Users(t *testing.T) {
|
||||||
assert.Equal(t, "Test", user.FirstName)
|
assert.Equal(t, "Test", user.FirstName)
|
||||||
assert.Equal(t, "Test", user.LastName)
|
assert.Equal(t, "Test", user.LastName)
|
||||||
assert.Equal(t, "2018-01-01T00:00:00.000000Z", user.CreatedAt)
|
assert.Equal(t, "2018-01-01T00:00:00.000000Z", user.CreatedAt)
|
||||||
assert.Equal(t, true, user.IsActive)
|
assert.True(t, user.IsActive)
|
||||||
assert.Equal(t, true, user.IsOnline)
|
assert.True(t, user.IsOnline)
|
||||||
assert.Equal(t, true, user.IsTechnicalAccount)
|
assert.True(t, user.IsTechnicalAccount)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +292,7 @@ func TestMgClient_Customers(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, customer := range data {
|
for _, customer := range data {
|
||||||
|
@ -309,16 +313,22 @@ func TestMgClient_Chats(t *testing.T) {
|
||||||
gock.New(mgURL).
|
gock.New(mgURL).
|
||||||
Get("/api/bot/v1/chats").
|
Get("/api/bot/v1/chats").
|
||||||
Reply(200).
|
Reply(200).
|
||||||
BodyString(`[{"id": 1,"customer": {"id": 1, "name": "Test"}, "created_at": "2018-01-01T00:00:00.000000Z"}]`)
|
BodyString(`[
|
||||||
|
{"id": 2,"customer": {"id": 2, "name": "Foo"}, "created_at": "2018-01-01T00:00:00.000000Z"},
|
||||||
|
{"id": 3,"customer": {"id": 3, "name": "Bar"}, "created_at": "2018-01-02T00:00:00.000000Z"}
|
||||||
|
]`)
|
||||||
|
|
||||||
req := ChatsRequest{ChannelType: ChannelTypeTelegram}
|
req := ChatsRequest{
|
||||||
|
ChannelType: ChannelTypeTelegram,
|
||||||
|
SinceID: 1,
|
||||||
|
}
|
||||||
|
|
||||||
data, status, err := c.Chats(req)
|
data, status, err := c.Chats(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, chat := range data {
|
for _, chat := range data {
|
||||||
|
@ -343,7 +353,7 @@ func TestMgClient_Members(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
for _, member := range data {
|
for _, member := range data {
|
||||||
assert.NotEmpty(t, member.ChatID)
|
assert.NotEmpty(t, member.ChatID)
|
||||||
|
@ -367,7 +377,7 @@ func TestMgClient_Dialogs(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, dialog := range data {
|
for _, dialog := range data {
|
||||||
|
@ -409,7 +419,7 @@ func TestMgClient_DialogUnassign(t *testing.T) {
|
||||||
|
|
||||||
resp, status, err := c.DialogUnassign(777)
|
resp, status, err := c.DialogUnassign(777)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusOK, status)
|
assert.Equal(t, http.StatusOK, status)
|
||||||
|
|
||||||
assert.Equal(t, int64(111), resp.PreviousResponsible.ID)
|
assert.Equal(t, int64(111), resp.PreviousResponsible.ID)
|
||||||
|
@ -494,7 +504,7 @@ func TestMgClient_DialogsTagsAdd(t *testing.T) {
|
||||||
|
|
||||||
status, err := c.DialogsTagsAdd(req)
|
status, err := c.DialogsTagsAdd(req)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusOK, status)
|
assert.Equal(t, http.StatusOK, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,7 +530,7 @@ func TestMgClient_DialogsTagsDelete(t *testing.T) {
|
||||||
|
|
||||||
status, err := c.DialogTagsDelete(req)
|
status, err := c.DialogTagsDelete(req)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusOK, status)
|
assert.Equal(t, http.StatusOK, status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +551,7 @@ func TestMgClient_Messages(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, message := range data {
|
for _, message := range data {
|
||||||
|
@ -549,6 +559,83 @@ func TestMgClient_Messages(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMgClient_MessagesDialog(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
c := client()
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
|
||||||
|
gock.New(mgURL).
|
||||||
|
Get("/api/bot/v1/messages").
|
||||||
|
Reply(200).
|
||||||
|
BodyString(`[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"time": "2024-11-14T20:48:21Z",
|
||||||
|
"type": "system",
|
||||||
|
"scope": "private",
|
||||||
|
"chat_id": 1,
|
||||||
|
"is_read": false,
|
||||||
|
"is_edit": false,
|
||||||
|
"status": "received",
|
||||||
|
"dialog": {
|
||||||
|
"id": 2054
|
||||||
|
},
|
||||||
|
"action": "dialog_closed",
|
||||||
|
"channel_id": 71,
|
||||||
|
"created_at": "2024-11-14T20:48:21.907566Z",
|
||||||
|
"updated_at": "2024-11-14T20:48:21.907566Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"time": "2024-11-14T19:58:42Z",
|
||||||
|
"type": "text",
|
||||||
|
"scope": "public",
|
||||||
|
"chat_id": 1,
|
||||||
|
"is_read": false,
|
||||||
|
"is_edit": false,
|
||||||
|
"status": "failed",
|
||||||
|
"from": {
|
||||||
|
"id": 1,
|
||||||
|
"external_id": "1",
|
||||||
|
"type": "user",
|
||||||
|
"avatar": "http://avatars-test.jpeg",
|
||||||
|
"name": "John Smith",
|
||||||
|
"first_name": "John",
|
||||||
|
"last_name": "Smith",
|
||||||
|
"available": true
|
||||||
|
},
|
||||||
|
"dialog": {
|
||||||
|
"id": 2054
|
||||||
|
},
|
||||||
|
"error": {
|
||||||
|
"code": "malformed_response"
|
||||||
|
},
|
||||||
|
"content": "Message from user John Smith",
|
||||||
|
"quote": null,
|
||||||
|
"channel_id": 71,
|
||||||
|
"created_at": "2024-11-14T19:58:42.933025Z",
|
||||||
|
"updated_at": "2024-11-14T19:58:45.01619Z"
|
||||||
|
}
|
||||||
|
]`)
|
||||||
|
|
||||||
|
req := MessagesRequest{}
|
||||||
|
|
||||||
|
data, status, err := c.Messages(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%d %v", status, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Len(t, data, 2)
|
||||||
|
|
||||||
|
for _, m := range data {
|
||||||
|
assert.NotNil(t, m.Message.Dialog)
|
||||||
|
assert.Equal(t, uint64(2054), m.Message.Dialog.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestMgClient_MessageSendText(t *testing.T) {
|
func TestMgClient_MessageSendText(t *testing.T) {
|
||||||
c := client()
|
c := client()
|
||||||
|
|
||||||
|
@ -573,7 +660,7 @@ func TestMgClient_MessageSendText(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data.MessageID)
|
assert.NotEmpty(t, data.MessageID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -611,7 +698,7 @@ func TestMgClient_MessageSendTextWithSuggestions(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data.MessageID)
|
assert.NotEmpty(t, data.MessageID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,7 +739,7 @@ func TestMgClient_MessageSendProduct(t *testing.T) {
|
||||||
t.Errorf("%v", err)
|
t.Errorf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Logf("%v", msg)
|
t.Logf("%v", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,7 +799,7 @@ func TestMgClient_MessageSendOrder(t *testing.T) {
|
||||||
t.Errorf("%v", err)
|
t.Errorf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Logf("%v", msg)
|
t.Logf("%v", msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +868,7 @@ func TestMgClient_Info(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMgClient_Commands(t *testing.T) {
|
func TestMgClient_Commands(t *testing.T) {
|
||||||
|
@ -801,7 +888,7 @@ func TestMgClient_Commands(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, data)
|
assert.NotEmpty(t, data)
|
||||||
|
|
||||||
for _, command := range data {
|
for _, command := range data {
|
||||||
|
@ -829,7 +916,7 @@ func TestMgClient_CommandEditDelete(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.NotEmpty(t, n.ID)
|
assert.NotEmpty(t, n.ID)
|
||||||
|
|
||||||
gock.New(mgURL).
|
gock.New(mgURL).
|
||||||
|
@ -842,10 +929,28 @@ func TestMgClient_CommandEditDelete(t *testing.T) {
|
||||||
t.Errorf("%d %v", status, err)
|
t.Errorf("%d %v", status, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
t.Logf("%v", d)
|
t.Logf("%v", d)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMgClient_WsMeta_With_Options(t *testing.T) {
|
||||||
|
c := client()
|
||||||
|
events := []string{"user_updated", "user_join_chat"}
|
||||||
|
params := []WsParams{WsOptionIncludeMassCommunication}
|
||||||
|
|
||||||
|
url, headers, err := c.WsMeta(events, params...)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resURL := "wss://api.example.com/api/bot/v1/ws?events=user_updated,user_join_chat&options=include_mass_communication"
|
||||||
|
resToken := c.Token
|
||||||
|
|
||||||
|
assert.Equal(t, resURL, url)
|
||||||
|
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
|
||||||
|
}
|
||||||
|
|
||||||
func TestMgClient_WsMeta(t *testing.T) {
|
func TestMgClient_WsMeta(t *testing.T) {
|
||||||
c := client()
|
c := client()
|
||||||
events := []string{"user_updated", "user_join_chat"}
|
events := []string{"user_updated", "user_join_chat"}
|
||||||
|
@ -855,23 +960,56 @@ func TestMgClient_WsMeta(t *testing.T) {
|
||||||
t.Errorf("%v", err)
|
t.Errorf("%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
resUrl := fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "wss", 1), prefix, "/ws?events=", strings.Join(events[:], ","))
|
resURL := fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "wss", 1), prefix, "/ws?events=", strings.Join(events, ","))
|
||||||
resToken := c.Token
|
resToken := c.Token
|
||||||
|
|
||||||
assert.Equal(t, resUrl, url)
|
assert.Equal(t, resURL, url)
|
||||||
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
|
assert.Equal(t, resToken, headers["X-Bot-Token"][0])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMgClient_UploadFile(t *testing.T) {
|
func TestMgClient_UploadFile(t *testing.T) {
|
||||||
c := client()
|
c := client()
|
||||||
|
|
||||||
|
defer gock.Off()
|
||||||
|
gock.New("https://via.placeholder.com").
|
||||||
|
Get("/300").
|
||||||
|
Reply(http.StatusOK).
|
||||||
|
SetHeader("Content-Type", "image/jpeg").
|
||||||
|
Body(func() io.Reader {
|
||||||
|
res, err := base64.StdEncoding.DecodeString(`
|
||||||
|
H4sIAAAAAAACA/t/4/8DBgEvN083BkZGBgZGIGT4f5vBmYGVmYWFhZkVSLCysrKx83CwAwE/Nzcn
|
||||||
|
jyC/kJAgv6CgsJiMuLCIlKigoISihJSsrLy8vLC4koqSnIqMnLwcyBBGoFZ2NnY+Dg4+ORFBETmS
|
||||||
|
wf8DDIIcDAoMCsyMSgxMgozMgoz/jzDIA93JyggGDFDAyMTMAnQlBycXN1DBVgEGJkZmZiag+4Ee
|
||||||
|
AMrWAuUZWARZhRQNHdmEAxPZlQpFjBonLuRQdtp4UDTo4gcV46SiJk4uMXEJSSlVNXUNTS0TUzNz
|
||||||
|
C0srZxdXN3cPT6/gkNCw8IjIqOSU1LT0jMys4pLSsvKKyqrmlta29o7OrkmTp0ydNn3GzFmLFi9Z
|
||||||
|
umz5ipWrNm3esnXb9h07dx06fOToseMnTp66dPnK1WvXb9y89fDR4ydPnz1/8fLVx0+fv3z99v3H
|
||||||
|
z18gfzEyMDPCAFZ/CQL9xQSMFhZ2kL8YmcpBCgRZWBUN2YQcA9kTC4WVjBo5RJwmLtx4kFPZOOiD
|
||||||
|
aFLRRS4xFZOHqh9BXgP7jDiPNZHlM7jHEP66xcDDzAiMPGZBBnuGH/fuKWs3sItefBlWa7FqV+h8
|
||||||
|
P+01l9b8KnQQ27Labk545NLIL49WZwLl1m322vzyKEPFu6npl7temwAlQ3O1zi8XvQaSXMBtBdcZ
|
||||||
|
itDYYP//JgDowAia0AIAAA==`)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%v", err)
|
||||||
|
t.FailNow()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
unpacker, err := gzip.NewReader(bytes.NewReader(res))
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%v", err)
|
||||||
|
t.FailNow()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return unpacker
|
||||||
|
}())
|
||||||
|
|
||||||
resp, err := http.Get("https://via.placeholder.com/300")
|
resp, err := http.Get("https://via.placeholder.com/300")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%v", err)
|
t.Errorf("%v", err)
|
||||||
|
t.FailNow()
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
defer gock.Off()
|
|
||||||
|
|
||||||
gock.New(mgURL).
|
gock.New(mgURL).
|
||||||
Post("/api/bot/v1/files/upload").
|
Post("/api/bot/v1/files/upload").
|
||||||
|
@ -909,7 +1047,7 @@ func TestMgClient_UploadFileByUrl(t *testing.T) {
|
||||||
|
|
||||||
t.Logf("File %+v is upload", uploadFileResponse.ID)
|
t.Logf("File %+v is upload", uploadFileResponse.ID)
|
||||||
|
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func RandStringBytesMaskImprSrc(n int) string {
|
func RandStringBytesMaskImprSrc(n int) string {
|
||||||
|
@ -972,9 +1110,9 @@ func TestMgClient_SuccessChatsByCustomerId(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, statusCode, err := apiClient.Chats(chatsRequest)
|
resp, statusCode, err := apiClient.Chats(chatsRequest)
|
||||||
assert.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, http.StatusOK, statusCode)
|
assert.Equal(t, http.StatusOK, statusCode)
|
||||||
assert.Equal(t, 1, len(resp))
|
assert.Len(t, resp, 1)
|
||||||
assert.Equal(t, uint64(9000), resp[0].ID)
|
assert.Equal(t, uint64(9000), resp[0].ID)
|
||||||
assert.Equal(t, uint64(8000), resp[0].Channel.ID)
|
assert.Equal(t, uint64(8000), resp[0].Channel.ID)
|
||||||
assert.Equal(t, customerID, resp[0].Customer.ID)
|
assert.Equal(t, customerID, resp[0].Customer.ID)
|
||||||
|
|
179
v1/types.go
179
v1/types.go
|
@ -43,6 +43,8 @@ const (
|
||||||
WsEventSettingsUpdated string = "settings_updated"
|
WsEventSettingsUpdated string = "settings_updated"
|
||||||
WsEventChatsDeleted string = "chats_deleted"
|
WsEventChatsDeleted string = "chats_deleted"
|
||||||
|
|
||||||
|
WsOptionIncludeMassCommunication WsOption = "include_mass_communication"
|
||||||
|
|
||||||
ChannelFeatureNone string = "none"
|
ChannelFeatureNone string = "none"
|
||||||
ChannelFeatureReceive string = "receive"
|
ChannelFeatureReceive string = "receive"
|
||||||
ChannelFeatureSend string = "send"
|
ChannelFeatureSend string = "send"
|
||||||
|
@ -50,6 +52,7 @@ const (
|
||||||
|
|
||||||
BotRoleDistributor string = "distributor"
|
BotRoleDistributor string = "distributor"
|
||||||
BotRoleResponsible string = "responsible"
|
BotRoleResponsible string = "responsible"
|
||||||
|
BotRoleHidden string = "hidden"
|
||||||
|
|
||||||
MsgTypeText string = "text"
|
MsgTypeText string = "text"
|
||||||
MsgTypeSystem string = "system"
|
MsgTypeSystem string = "system"
|
||||||
|
@ -89,6 +92,10 @@ const (
|
||||||
ColorOrange = "orange"
|
ColorOrange = "orange"
|
||||||
ColorGray = "gray"
|
ColorGray = "gray"
|
||||||
ColorGrayishBlue = "grayish-blue"
|
ColorGrayishBlue = "grayish-blue"
|
||||||
|
|
||||||
|
WaitingLevelNone = "none"
|
||||||
|
WaitingLevelWarning = "warning"
|
||||||
|
WaitingLevelDanger = "danger"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MgClient type
|
// MgClient type
|
||||||
|
@ -142,13 +149,16 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatsRequest struct {
|
ChatsRequest struct {
|
||||||
ID uint64 `url:"id,omitempty"`
|
ID uint64 `url:"id,omitempty"`
|
||||||
ChannelID uint64 `url:"channel_id,omitempty" json:"channel_id"`
|
ChannelID uint64 `url:"channel_id,omitempty" json:"channel_id"`
|
||||||
ChannelType string `url:"channel_type,omitempty" json:"channel_type"`
|
ChannelType string `url:"channel_type,omitempty" json:"channel_type"`
|
||||||
CustomerID uint64 `url:"customer_id,omitempty" json:"customer_id"`
|
CustomerID uint64 `url:"customer_id,omitempty" json:"customer_id"`
|
||||||
Since string `url:"since,omitempty"`
|
CustomerExternalID string `url:"customer_external_id,omitempty" json:"customer_external_id"`
|
||||||
Until string `url:"until,omitempty"`
|
Since string `url:"since,omitempty"`
|
||||||
Limit int `url:"limit,omitempty"`
|
Until string `url:"until,omitempty"`
|
||||||
|
Limit int `url:"limit,omitempty"`
|
||||||
|
SinceID int `url:"since_id,omitempty"`
|
||||||
|
IncludeMassCommunication uint8 `url:"include_mass_communication,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
MembersRequest struct {
|
MembersRequest struct {
|
||||||
|
@ -161,16 +171,17 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogsRequest struct {
|
DialogsRequest struct {
|
||||||
ID uint64 `url:"id,omitempty"`
|
ID uint64 `url:"id,omitempty"`
|
||||||
ChatID string `url:"chat_id,omitempty" json:"chat_id"`
|
ChatID string `url:"chat_id,omitempty" json:"chat_id"`
|
||||||
UserID string `url:"user_id,omitempty" json:"user_id"`
|
UserID string `url:"user_id,omitempty" json:"user_id"`
|
||||||
BotID string `url:"bot_id,omitempty" json:"bot_id"`
|
BotID string `url:"bot_id,omitempty" json:"bot_id"`
|
||||||
Assign uint8 `url:"assign,omitempty"`
|
Assign uint8 `url:"assign,omitempty"`
|
||||||
Active uint8 `url:"active,omitempty"`
|
Active uint8 `url:"active,omitempty"`
|
||||||
Since string `url:"since,omitempty"`
|
Since string `url:"since,omitempty"`
|
||||||
SinceID int `url:"since_id,omitempty"`
|
SinceID int `url:"since_id,omitempty"`
|
||||||
Until string `url:"until,omitempty"`
|
Until string `url:"until,omitempty"`
|
||||||
Limit int `url:"limit,omitempty"`
|
Limit int `url:"limit,omitempty"`
|
||||||
|
IncludeMassCommunication uint8 `url:"include_mass_communication,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogAssignRequest struct {
|
DialogAssignRequest struct {
|
||||||
|
@ -199,19 +210,20 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
MessagesRequest struct {
|
MessagesRequest struct {
|
||||||
ID []int `url:"id,omitempty"`
|
ID []int `url:"id,omitempty"`
|
||||||
ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
|
ChatID uint64 `url:"chat_id,omitempty" json:"chat_id"`
|
||||||
DialogID uint64 `url:"dialog_id,omitempty" json:"dialog_id"`
|
DialogID uint64 `url:"dialog_id,omitempty" json:"dialog_id"`
|
||||||
UserID uint64 `url:"user_id,omitempty" json:"user_id"`
|
UserID uint64 `url:"user_id,omitempty" json:"user_id"`
|
||||||
CustomerID uint64 `url:"customer_id,omitempty" json:"customer_id"`
|
CustomerID uint64 `url:"customer_id,omitempty" json:"customer_id"`
|
||||||
BotID uint64 `url:"bot_id,omitempty" json:"bot_id"`
|
BotID uint64 `url:"bot_id,omitempty" json:"bot_id"`
|
||||||
ChannelID uint64 `url:"channel_id,omitempty" json:"channel_id"`
|
ChannelID uint64 `url:"channel_id,omitempty" json:"channel_id"`
|
||||||
ChannelType string `url:"channel_type,omitempty" json:"channel_type"`
|
ChannelType string `url:"channel_type,omitempty" json:"channel_type"`
|
||||||
Scope string `url:"scope,omitempty"`
|
Scope string `url:"scope,omitempty"`
|
||||||
Type string `url:"type,omitempty"`
|
Type string `url:"type,omitempty"`
|
||||||
Since string `url:"since,omitempty"`
|
Since string `url:"since,omitempty"`
|
||||||
Until string `url:"until,omitempty"`
|
Until string `url:"until,omitempty"`
|
||||||
Limit int `url:"limit,omitempty"`
|
Limit int `url:"limit,omitempty"`
|
||||||
|
IncludeMassCommunication uint8 `url:"include_mass_communication,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageSendRequest struct {
|
MessageSendRequest struct {
|
||||||
|
@ -262,6 +274,13 @@ type (
|
||||||
UploadFileByUrlRequest struct {
|
UploadFileByUrlRequest struct {
|
||||||
Url string `json:"url"`
|
Url string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateFileMetadataRequest struct {
|
||||||
|
ID string `json:"-"`
|
||||||
|
Transcription string `json:"transcription,omitempty"`
|
||||||
|
// Current status of transcription process. Available values: "in_progress", "ready", "error"
|
||||||
|
TranscriptionStatus string `json:"transcription_status,omitempty"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// Response types
|
// Response types
|
||||||
|
@ -328,16 +347,18 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatResponseItem struct {
|
ChatResponseItem struct {
|
||||||
ID uint64 `json:"id"`
|
ID uint64 `json:"id"`
|
||||||
Avatar string `json:"avatar"`
|
Avatar string `json:"avatar"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Channel Channel `json:"channel,omitempty"`
|
Channel Channel `json:"channel,omitempty"`
|
||||||
Customer UserRef `json:"customer"`
|
Customer UserRef `json:"customer"`
|
||||||
AuthorID uint64 `json:"author_id"`
|
AuthorID uint64 `json:"author_id"`
|
||||||
LastMessage Message `json:"last_message"`
|
LastMessage Message `json:"last_message"`
|
||||||
LastActivity string `json:"last_activity"`
|
LastUserMessage MessageID `json:"last_user_message"`
|
||||||
CreatedAt string `json:"created_at"`
|
LastActivity string `json:"last_activity"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
LastDialog Dialog `json:"last_dialog"`
|
||||||
|
CreatedAt string `json:"created_at"`
|
||||||
|
UpdatedAt string `json:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberResponseItem struct {
|
MemberResponseItem struct {
|
||||||
|
@ -362,6 +383,7 @@ type (
|
||||||
IsAssigned bool `json:"is_assigned"`
|
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"`
|
||||||
|
Utm *Utm `json:"utm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
DialogAssignResponse struct {
|
DialogAssignResponse struct {
|
||||||
|
@ -429,6 +451,11 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WS options.
|
||||||
|
type (
|
||||||
|
WsOption string
|
||||||
|
)
|
||||||
|
|
||||||
// Single entity types
|
// Single entity types
|
||||||
type (
|
type (
|
||||||
Message struct {
|
Message struct {
|
||||||
|
@ -444,11 +471,16 @@ type (
|
||||||
From *UserRef `json:"from"`
|
From *UserRef `json:"from"`
|
||||||
Product *MessageProduct `json:"product,omitempty"`
|
Product *MessageProduct `json:"product,omitempty"`
|
||||||
Order *MessageOrder `json:"order,omitempty"`
|
Order *MessageOrder `json:"order,omitempty"`
|
||||||
|
Dialog *MessageDialog `json:"dialog,omitempty"`
|
||||||
*TextMessage
|
*TextMessage
|
||||||
*SystemMessage
|
*SystemMessage
|
||||||
*AttachmentList
|
*AttachmentList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageID struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
TextMessage struct {
|
TextMessage struct {
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
Quote *QuoteMessage `json:"quote"`
|
Quote *QuoteMessage `json:"quote"`
|
||||||
|
@ -456,16 +488,22 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
SystemMessage struct {
|
SystemMessage struct {
|
||||||
Action string `json:"action"`
|
Action string `json:"action"`
|
||||||
|
// Deprecated: Use Message.Dialog.ID instead.
|
||||||
Dialog *SystemMessageDialog `json:"dialog,omitempty"`
|
Dialog *SystemMessageDialog `json:"dialog,omitempty"`
|
||||||
User *UserRef `json:"user,omitempty"`
|
User *UserRef `json:"user,omitempty"`
|
||||||
Responsible *UserRef `json:"responsible,omitempty"`
|
Responsible *UserRef `json:"responsible,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use MessageDialog instead.
|
||||||
SystemMessageDialog struct {
|
SystemMessageDialog struct {
|
||||||
ID uint64 `json:"id"`
|
ID uint64 `json:"id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessageDialog struct {
|
||||||
|
ID uint64 `json:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
QuoteMessage struct {
|
QuoteMessage struct {
|
||||||
ID uint64 `json:"id"`
|
ID uint64 `json:"id"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
@ -479,13 +517,21 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
Attachment struct {
|
Attachment struct {
|
||||||
ID string `json:"id"`
|
File
|
||||||
Mime string `json:"type"`
|
|
||||||
Caption string `json:"caption"`
|
Caption string `json:"caption"`
|
||||||
Size uint64 `json:"size"`
|
}
|
||||||
PreviewURL *string `json:"preview_url,omitempty"`
|
|
||||||
Height *uint64 `json:"height,omitempty"`
|
File struct {
|
||||||
Width *uint64 `json:"width,omitempty"`
|
PreviewURL *string `json:"preview_url,omitempty"`
|
||||||
|
Height *uint64 `json:"height,omitempty"`
|
||||||
|
Width *uint64 `json:"width,omitempty"`
|
||||||
|
Transcription string `json:"transcription,omitempty"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Mime string `json:"type"`
|
||||||
|
Type string `json:"kind"`
|
||||||
|
Duration int `json:"duration,omitempty"`
|
||||||
|
Size uint64 `json:"size"`
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageProduct struct {
|
MessageProduct struct {
|
||||||
|
@ -563,6 +609,7 @@ type (
|
||||||
IsAdmin bool `json:"is_admin"`
|
IsAdmin bool `json:"is_admin"`
|
||||||
Available bool `json:"available"`
|
Available bool `json:"available"`
|
||||||
IsTechnicalAccount bool `json:"is_technical_account"`
|
IsTechnicalAccount bool `json:"is_technical_account"`
|
||||||
|
IsSystem bool `json:"is_system"`
|
||||||
}
|
}
|
||||||
|
|
||||||
Channel struct {
|
Channel struct {
|
||||||
|
@ -594,15 +641,22 @@ type (
|
||||||
}
|
}
|
||||||
|
|
||||||
Chat struct {
|
Chat struct {
|
||||||
ID uint64 `json:"id"`
|
ID uint64 `json:"id"`
|
||||||
Avatar string `json:"avatar"`
|
Avatar string `json:"avatar"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Channel *Channel `json:"channel,omitempty"`
|
Channel *Channel `json:"channel,omitempty"`
|
||||||
Members []Member `json:"members"`
|
Members []Member `json:"members"`
|
||||||
Customer *UserRef `json:"customer"`
|
Customer *UserRef `json:"customer"`
|
||||||
AuthorID uint64 `json:"author_id"`
|
AuthorID uint64 `json:"author_id"`
|
||||||
LastMessage *Message `json:"last_message"`
|
LastMessage *Message `json:"last_message"`
|
||||||
LastActivity string `json:"last_activity"`
|
LastUserMessage *MessageID `json:"last_user_message"`
|
||||||
|
LastActivity string `json:"last_activity"`
|
||||||
|
}
|
||||||
|
|
||||||
|
WaitingChat struct {
|
||||||
|
Chat
|
||||||
|
|
||||||
|
WaitingLevel string `json:"waiting_level"`
|
||||||
}
|
}
|
||||||
|
|
||||||
Member struct {
|
Member struct {
|
||||||
|
@ -619,6 +673,7 @@ type (
|
||||||
Responsible *Responsible `json:"responsible"`
|
Responsible *Responsible `json:"responsible"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
ClosedAt *string `json:"closed_at"`
|
ClosedAt *string `json:"closed_at"`
|
||||||
|
Utm *Utm `json:"utm,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
FileMeta struct {
|
FileMeta struct {
|
||||||
|
@ -723,10 +778,12 @@ type (
|
||||||
Message *Message `json:"message"`
|
Message *Message `json:"message"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use WsEventWaitingChatCreatedData instead.
|
||||||
WsEventChatCreatedData struct {
|
WsEventChatCreatedData struct {
|
||||||
Chat *Chat `json:"chat"`
|
Chat *Chat `json:"chat"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deprecated: Use WsEventWaitingChatUpdatedData instead.
|
||||||
WsEventChatUpdatedData struct {
|
WsEventChatUpdatedData struct {
|
||||||
Chat *Chat `json:"chat"`
|
Chat *Chat `json:"chat"`
|
||||||
}
|
}
|
||||||
|
@ -785,4 +842,12 @@ type (
|
||||||
WsEventChannelUpdatedData struct {
|
WsEventChannelUpdatedData struct {
|
||||||
Channel *ChannelResponseItem `json:"channel"`
|
Channel *ChannelResponseItem `json:"channel"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WsEventWaitingChatCreatedData struct {
|
||||||
|
Chat *WaitingChat `json:"chat"`
|
||||||
|
}
|
||||||
|
|
||||||
|
WsEventWaitingChatUpdatedData struct {
|
||||||
|
Chat *WaitingChat `json:"chat"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Reference in a new issue