diff --git a/README.md b/README.md index fb2cfcf..ea71cd8 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,61 @@ func main() { fmt.Printf("%v", data.MessageID) } ``` + +## Websocket Example + +```golang +package main + +import ( + "encoding/json" + "log" + "strings" + + "github.com/gorilla/websocket" + "github.com/retailcrm/mg-bot-api-client-go/v1" +) + +func main() { + var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") + + url, headers, err := client.WsMeta([]string{"message_new"}) + if err != nil { + log.Fatal("wsMeta:", err) + } + + wsConn, _, err := websocket.DefaultDialer.Dial(url, headers) + if err != nil { + log.Fatal("dial:", err) + } + + for { + var wsEvent v1.WsEvent + err = wsConn.ReadJSON(&wsEvent) + if err != nil { + log.Fatal("ReadJSON:", err) + } + + var eventData v1.WsEventMessageNewData + err = json.Unmarshal(wsEvent.Data, &eventData) + if err != nil { + log.Fatal("Unmarshal:", err) + } + + if !strings.HasPrefix(eventData.Message.Content, "Hello") { + continue + } + + message := v1.MessageSendRequest{ + Scope: "public", + Content: "Bonjour!", + ChatID: eventData.Message.ChatID, + } + + _, status, err := client.MessageSend(message) + if err != nil { + log.Fatalf("%d %v", status, err) + } + } +} +``` \ No newline at end of file diff --git a/v1/client.go b/v1/client.go index ee338e6..8503371 100644 --- a/v1/client.go +++ b/v1/client.go @@ -669,7 +669,7 @@ func (c *MgClient) WsMeta(events []string) (string, http.Header, error) { return url, nil, err } - url = fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "ws", 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[:], ",")) if url == "" { err := errors.New("empty WS URL") diff --git a/v1/client_test.go b/v1/client_test.go index c646122..0e61583 100644 --- a/v1/client_test.go +++ b/v1/client_test.go @@ -326,7 +326,7 @@ func TestMgClient_WsMeta(t *testing.T) { t.Errorf("%v", err) } - resUrl := fmt.Sprintf("%s%s%s%s", strings.Replace(c.URL, "https", "ws", 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 assert.Equal(t, resUrl, url) diff --git a/v1/types.go b/v1/types.go index b6b6657..55cf7a9 100644 --- a/v1/types.go +++ b/v1/types.go @@ -1,6 +1,7 @@ package v1 import ( + "encoding/json" "net/http" ) @@ -285,10 +286,10 @@ type ( // WS event types type ( WsEvent struct { - Type string `json:"type"` - Meta EventMeta `json:"meta"` - AppID uint `json:"app_id"` - Data interface{} `json:"data"` + Type string `json:"type"` + Meta EventMeta `json:"meta"` + AppID uint `json:"app_id"` + Data json.RawMessage `json:"data"` } EventMeta struct { @@ -370,6 +371,33 @@ type ( CreatedAt string UpdatedAt string } + + Chat struct { + ID uint64 `json:"id"` + Avatar string `json:"avatar"` + Name string `json:"name"` + Channel *Channel `json:"channel,omitempty"` + Members []Member `json:"members"` + Customer *UserRef `json:"customer"` + AuthorID uint64 `json:"author_id"` + LastMessage *Message `json:"last_message"` + LastActivity string `json:"last_activity"` + } + + Member struct { + IsAuthor bool `json:"is_author"` + State string `json:"state"` + User *UserRef `json:"user"` + } + + Dialog struct { + ID uint64 `json:"id"` + BeginMessageID *uint64 `json:"begin_message_id"` + EndingMessageID *uint64 `json:"ending_message_id"` + Chat *Chat `json:"chat"` + CreatedAt string `json:"created_at"` + ClosedAt *string `json:"closed_at"` + } ) // Channel settings @@ -392,3 +420,58 @@ type ( Text ChannelSettingsText `json:"text"` } ) + +// Events +type ( + WsEventMessageNewData struct { + Message *Message `json:"message"` + } + + WsEventMessageUpdatedData struct { + Message *Message `json:"message"` + } + + WsEventMessageDeletedData struct { + Message *Message `json:"message"` + } + + WsEventChatCreatedData struct { + Chat *Chat `json:"chat"` + } + + WsEventChatUpdatedData struct { + Chat *Chat `json:"chat"` + } + + WsEventDialogOpenedData struct { + Dialog *Dialog `json:"dialog"` + } + + WsEventDialogClosedData struct { + Dialog *Dialog `json:"dialog"` + } + + WsEventUserLeaveData struct { + Reason string `json:"reason"` + Chat struct { + ID uint64 `json:"id"` + } `json:"chat"` + User struct { + ID uint64 `json:"id"` + } `json:"user"` + } + + WsEventUserUpdatedData struct { + *UserRef + } + + WsEventDialogAssignData struct { + Dialog *Dialog `json:"dialog"` + Chat *Chat `json:"chat"` + } + + EventUserJoinedChatData struct { + Chat *Chat `json:"chat"` + User *UserRef `json:"user"` + } +)