From fa349ed1ca86e275bb0c3149f8e975df45974a8f Mon Sep 17 00:00:00 2001 From: Alex Lushpai Date: Wed, 3 Oct 2018 09:48:07 +0300 Subject: [PATCH] add mark message read feature, change struct used for messagedit, refactoring --- v1/client.go | 85 +++++++++++++++++++++++++++++++++++------------ v1/client_test.go | 52 ++++++++++++++++------------- v1/request.go | 33 ++++-------------- v1/types.go | 85 +++++++++++++++++++++++++++++++++++------------ 4 files changed, 163 insertions(+), 92 deletions(-) diff --git a/v1/client.go b/v1/client.go index 746448b..01a934a 100644 --- a/v1/client.go +++ b/v1/client.go @@ -24,7 +24,7 @@ func New(url string, token string) *MgClient { // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // // data, status, err := client.TransportChannels{Channels{Active: true}} // @@ -35,15 +35,16 @@ func New(url string, token string) *MgClient { // fmt.Printf("Status: %v, Channels found: %v", status, len(data)) func (c *MgClient) TransportChannels(request Channels) ([]ChannelListItem, int, error) { var resp []ChannelListItem + var b []byte outgoing, _ := query.Values(request) - data, status, err := c.GetRequest(fmt.Sprintf("/channels?%s", outgoing.Encode())) + data, status, err := c.GetRequest(fmt.Sprintf("/channels?%s", outgoing.Encode()), b) if err != nil { return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { - return resp, status, err + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e } if status > http.StatusCreated || status < http.StatusOK { @@ -57,7 +58,7 @@ func (c *MgClient) TransportChannels(request Channels) ([]ChannelListItem, int, // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // // request := ActivateRequest{ // Type: "telegram", @@ -101,8 +102,8 @@ func (c *MgClient) ActivateTransportChannel(request Channel) (ActivateResponse, return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { - return resp, status, err + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e } if status > http.StatusCreated || status < http.StatusOK { @@ -116,7 +117,7 @@ func (c *MgClient) ActivateTransportChannel(request Channel) (ActivateResponse, // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // // request := ActivateRequest{ // ID: 3053450384, @@ -161,8 +162,8 @@ func (c *MgClient) UpdateTransportChannel(request Channel) (UpdateResponse, int, return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { - return resp, status, err + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e } if status != http.StatusOK { @@ -176,7 +177,7 @@ func (c *MgClient) UpdateTransportChannel(request Channel) (UpdateResponse, int, // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // // data, status, err := client.DeactivateTransportChannel(3053450384) // @@ -197,8 +198,8 @@ func (c *MgClient) DeactivateTransportChannel(id uint64) (DeleteResponse, int, e return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { - return resp, status, err + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e } if status != http.StatusOK { @@ -212,7 +213,7 @@ func (c *MgClient) DeactivateTransportChannel(id uint64) (DeleteResponse, int, e // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // msg := SendData{ // SendMessage{ // Message{ @@ -246,8 +247,8 @@ func (c *MgClient) Messages(request SendData) (MessagesResponse, int, error) { return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { - return resp, status, err + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e } if status != http.StatusOK { @@ -261,7 +262,7 @@ func (c *MgClient) Messages(request SendData) (MessagesResponse, int, error) { // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // msg := UpdateData{ // UpdateMessage{ // Message{ @@ -281,7 +282,7 @@ func (c *MgClient) Messages(request SendData) (MessagesResponse, int, error) { // } // // fmt.Printf("%s\n", data.MessageID) -func (c *MgClient) UpdateMessages(request UpdateData) (MessagesResponse, int, error) { +func (c *MgClient) UpdateMessages(request EditMessageRequest) (MessagesResponse, int, error) { var resp MessagesResponse outgoing, _ := json.Marshal(&request) @@ -290,10 +291,49 @@ func (c *MgClient) UpdateMessages(request UpdateData) (MessagesResponse, int, er return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e + } + + if status != http.StatusOK { + return resp, status, c.Error(data) + } + + return resp, status, err +} + +// MarkMessageRead send message read event to MG +// +// Example: +// +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") +// msg := MarkMessageReadRequest{ +// Message{ +// ExternalID: "274628", +// }, +// 10, +// } +// +// data, status, err := client.MarkMessageRead(msg) +// +// if err != nil { +// fmt.Printf("%v", err) +// } +// +// fmt.Printf("%v %v\n", status, data) +func (c *MgClient) MarkMessageRead(request MarkMessageReadRequest) (MarkMessageReadResponse, int, error) { + var resp MarkMessageReadResponse + outgoing, _ := json.Marshal(&request) + + data, status, err := c.PostRequest("/messages/read", []byte(outgoing)) + if err != nil { return resp, status, err } + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e + } + if status != http.StatusOK { return resp, status, c.Error(data) } @@ -305,7 +345,7 @@ func (c *MgClient) UpdateMessages(request UpdateData) (MessagesResponse, int, er // // Example: // -// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d49bcba99be73bff503ea6") +// var client = v1.New("https://token.url", "cb8ccf05e38a47543ad8477d4999be73bff503ea6") // // msg := DeleteData{ // Message{ @@ -333,8 +373,8 @@ func (c *MgClient) DeleteMessage(request DeleteData) (MessagesResponse, int, err return resp, status, err } - if err := json.Unmarshal(data, &resp); err != nil { - return resp, status, err + if e := json.Unmarshal(data, &resp); e != nil { + return resp, status, e } if status != http.StatusOK { @@ -356,6 +396,7 @@ func (c *MgClient) Error(info []byte) error { return errors.New(values[0].(string)) } +// MakeTimestamp returns current unix timestamp func MakeTimestamp() int64 { return time.Now().UnixNano() / (int64(time.Millisecond) / int64(time.Nanosecond)) } diff --git a/v1/client_test.go b/v1/client_test.go index e74418f..c3510d9 100644 --- a/v1/client_test.go +++ b/v1/client_test.go @@ -111,7 +111,7 @@ func TestMgClient_ActivateNewTransportChannel(t *testing.T) { t.Errorf("%d %v", status, err) } - if deleteData.DectivatedAt.String() == "" { + if deleteData.DeactivatedAt.String() == "" { t.Errorf("%v", err) } @@ -188,57 +188,63 @@ func TestMgClient_Messages(t *testing.T) { } func TestMgClient_UpdateMessages(t *testing.T) { - t.Skip() c := client() t.Logf("%v", ext) - snd := UpdateData{ - UpdateMessage{ - Message{ - ExternalID: ext, - Type: "text", - Text: "hello hello!", - }, - MakeTimestamp(), + sndU := EditMessageRequest{ + EditMessageRequestMessage{ + ExternalID: ext, + Text: "hello hello!", }, channelId, } - data, status, err := c.UpdateMessages(snd) + dataU, status, err := c.UpdateMessages(sndU) if status != http.StatusOK { t.Errorf("%v", err) } - if data.Time.String() == "" { + if dataU.Time.String() == "" { t.Errorf("%v", err) } - t.Logf("Message %v updated", data.MessageID) + t.Logf("Message %v updated", dataU.MessageID) } -func TestMgClient_DeleteMessage(t *testing.T) { - t.Skip() +func TestMgClient_MarkMessageReadAndDelete(t *testing.T) { c := client() t.Logf("%v", ext) - snd := DeleteData{ + snd := MarkMessageReadRequest{ + MarkMessageReadRequestMessage{ + ExternalID: ext, + }, + channelId, + } + + _, status, err := c.MarkMessageRead(snd) + + if status != http.StatusOK { + t.Errorf("%v", err) + } + + t.Logf("Message ext marked as read") + + sndD := DeleteData{ Message{ ExternalID: ext, }, channelId, } - data, status, err := c.DeleteMessage(snd) + data, status, err := c.DeleteMessage(sndD) + if status != http.StatusOK { t.Errorf("%v", err) } - if data.Time.String() == "" { - t.Errorf("%v", err) - } - - t.Logf("Message %v updated", data.MessageID) + t.Logf("Message %v deleted", data.MessageID) } func TestMgClient_DeactivateTransportChannel(t *testing.T) { @@ -249,7 +255,7 @@ func TestMgClient_DeactivateTransportChannel(t *testing.T) { t.Errorf("%d %v", status, err) } - if deleteData.DectivatedAt.String() == "" { + if deleteData.DeactivatedAt.String() == "" { t.Errorf("%v", err) } diff --git a/v1/request.go b/v1/request.go index 76f4c11..9bf8c4d 100644 --- a/v1/request.go +++ b/v1/request.go @@ -11,32 +11,13 @@ import ( var prefix = "/api/transport/v1" // GetRequest implements GET Request -func (c *MgClient) GetRequest(urlWithParameters string) ([]byte, int, error) { - var res []byte - - req, err := http.NewRequest("GET", fmt.Sprintf("%s%s%s", c.URL, prefix, urlWithParameters), nil) - if err != nil { - return res, 0, err - } - - req.Header.Set("X-Transport-Token", c.Token) - - resp, err := c.httpClient.Do(req) - if err != nil { - return res, 0, err - } - - if resp.StatusCode >= http.StatusInternalServerError { - err = fmt.Errorf("HTTP request error. Status code: %d.\n", resp.StatusCode) - return res, resp.StatusCode, err - } - - res, err = buildRawResponse(resp) - if err != nil { - return res, resp.StatusCode, err - } - - return res, resp.StatusCode, err +func (c *MgClient) GetRequest(url string, parameters []byte) ([]byte, int, error) { + return makeRequest( + "GET", + fmt.Sprintf("%s%s%s", c.URL, prefix, url), + bytes.NewBuffer(parameters), + c, + ) } // PostRequest implements POST Request diff --git a/v1/types.go b/v1/types.go index 5558afa..c909d98 100644 --- a/v1/types.go +++ b/v1/types.go @@ -5,6 +5,7 @@ import ( "time" ) +//noinspection ALL const ( // ChannelFeatureNone channel can not implement feature ChannelFeatureNone string = "none" @@ -15,24 +16,41 @@ const ( // ChannelFeatureBoth channel implement feature on both directions ChannelFeatureBoth string = "both" - MsgTypeText string = "text" - MsgTypeSystem string = "system" + // MsgTypeText text message + MsgTypeText string = "text" + // MsgTypeSystem system message + MsgTypeSystem string = "system" + // MsgTypeCommand command (for bots) MsgTypeCommand string = "command" - MsgTypeOrder string = "order" + // MsgTypeOrder order card + MsgTypeOrder string = "order" + // MsgTypeProduct product card MsgTypeProduct string = "product" - MsgOrderStatusCodeNew = "new" - MsgOrderStatusCodeApproval = "approval" + // MsgOrderStatusCodeNew order status group new + MsgOrderStatusCodeNew = "new" + // MsgOrderStatusCodeApproval order status group approval + MsgOrderStatusCodeApproval = "approval" + // MsgOrderStatusCodeAssembling order status group assembling MsgOrderStatusCodeAssembling = "assembling" - MsgOrderStatusCodeDelivery = "delivery" - MsgOrderStatusCodeComplete = "complete" - MsgOrderStatusCodeCancel = "cancel" + // MsgOrderStatusCodeDelivery order status group delivery + MsgOrderStatusCodeDelivery = "delivery" + // MsgOrderStatusCodeComplete order status group complete + MsgOrderStatusCodeComplete = "complete" + // MsgOrderStatusCodeCancel order status group cancel + MsgOrderStatusCodeCancel = "cancel" + // MsgCurrencyRub currency code for russian ruble MsgCurrencyRub = "rub" + // MsgCurrencyUah currency code for ukrainian hryvnia MsgCurrencyUah = "uah" + // MsgCurrencyByr currency code for belorussian ruble MsgCurrencyByr = "byr" + // MsgCurrencyKzt currency code for kazakh tenge MsgCurrencyKzt = "kzt" + // MsgCurrencyUsd currency code for us dollar MsgCurrencyUsd = "usd" + // MsgCurrencyEur currency code for euro MsgCurrencyEur = "eur" ) @@ -61,12 +79,14 @@ type ChannelSettings struct { Order Order `json:"order"` } +// Product type type Product struct { Creating string `json:"creating"` Editing string `json:"editing"` Deleting string `json:"deleting"` } +// Order type type Order struct { Creating string `json:"creating"` Editing string `json:"editing"` @@ -101,8 +121,8 @@ type UpdateResponse struct { // DeleteResponse channel deactivation response type DeleteResponse struct { - ChannelID uint64 `json:"id"` - DectivatedAt time.Time `json:"deactivated_at"` + ChannelID uint64 `json:"id"` + DeactivatedAt time.Time `json:"deactivated_at"` } // ChannelListItem response struct @@ -157,10 +177,17 @@ type SendMessage struct { SentAt time.Time `json:"sent_at,omitempty"` } -// UpdateMessage struct -type UpdateMessage struct { - Message - EditedAt int64 `json:"edited_at,omitempty"` +// EditMessageRequest type +type EditMessageRequest struct { + Message EditMessageRequestMessage `json:"message"` + Channel uint64 `json:"channel"` +} + +// EditMessageRequestMessage type +type EditMessageRequestMessage struct { + ExternalID string `json:"external_id"` + Text string `json:"text"` + EditedAt int64 `json:"edited_at"` } // SendData struct @@ -172,14 +199,23 @@ type SendData struct { Quote *SendMessageRequestQuote `json:"quote,omitempty"` } +// SendMessageRequestQuote type type SendMessageRequestQuote struct { ExternalID string `json:"external_id"` } -// UpdateData struct -type UpdateData struct { - Message UpdateMessage `json:"message"` - Channel uint64 `json:"channel"` +// MarkMessageReadResponse type +type MarkMessageReadResponse struct{} + +// MarkMessageReadRequest type +type MarkMessageReadRequest struct { + Message MarkMessageReadRequestMessage `json:"message"` + ChannelID uint64 `json:"channel_id"` +} + +// MarkMessageReadRequestMessage type +type MarkMessageReadRequestMessage struct { + ExternalID string `json:"external_id"` } // DeleteData struct @@ -190,11 +226,11 @@ type DeleteData struct { // MessagesResponse message event response type MessagesResponse struct { - MessageID int `json:"message_id"` - Time time.Time `json:"time"` + MessageID int `json:"message_id,omitempty"` + Time time.Time `json:"time,omitempty"` } -// Webhook request +// WebhookRequest type type WebhookRequest struct { Type string `json:"type"` Meta TransportRequestMeta `json:"meta"` @@ -253,11 +289,13 @@ type MessageDataOrder struct { Items []MessageDataOrderItem `json:"items,omitempty"` } +// MessageDataOrderStatus type type MessageDataOrderStatus struct { Code string `json:"code,omitempty"` Name string `json:"name,omitempty"` } +// MessageDataOrderItem type type MessageDataOrderItem struct { Name string `json:"name,omitempty"` Url string `json:"url,omitempty"` @@ -266,27 +304,32 @@ type MessageDataOrderItem struct { Price *MessageDataOrderCost `json:"price,omitempty"` } +// MessageDataOrderCost type type MessageDataOrderCost struct { Value float32 `json:"value,omitempty"` Currency string `json:"currency"` } +// MessageDataOrderQuantity type type MessageDataOrderQuantity struct { Value float32 `json:"value"` Unit string `json:"unit"` } +// MessageDataOrderPayment type type MessageDataOrderPayment struct { Name string `json:"name"` Status *MessageDataOrderPaymentStatus `json:"status"` Amount *MessageDataOrderCost `json:"amount"` } +// MessageDataOrderPaymentStatus type type MessageDataOrderPaymentStatus struct { Name string `json:"name"` Payed bool `json:"payed"` } +// MessageDataOrderDelivery type type MessageDataOrderDelivery struct { Name string `json:"name"` Price *MessageDataOrderCost `json:"price"`