From d5f3b73c2527c2a7eaf0dcc0ccea86ad3995fd4e Mon Sep 17 00:00:00 2001
From: Vlasov <vlasov.vlasov2015@gmail.com>
Date: Mon, 25 Dec 2023 22:10:42 +0300
Subject: [PATCH] Added URL channel message suggestion

---
 v1/client_test.go |  2 +-
 v1/types.go       |  7 +++--
 v1/types_test.go  | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 85 insertions(+), 3 deletions(-)

diff --git a/v1/client_test.go b/v1/client_test.go
index 321cb10..fb06b40 100644
--- a/v1/client_test.go
+++ b/v1/client_test.go
@@ -499,7 +499,7 @@ func (t *MGClientTest) Test_TextMessages() {
 			ExternalID: "external_id",
 			Type:       MsgTypeText,
 			Text:       "hello!",
-			PageLink: "https://example.loca/catalog/1",
+			PageLink:   "https://example.loca/catalog/1",
 		},
 		Originator: OriginatorCustomer,
 		Customer: Customer{
diff --git a/v1/types.go b/v1/types.go
index da074d6..372fb72 100644
--- a/v1/types.go
+++ b/v1/types.go
@@ -169,6 +169,7 @@ type ChannelSettingsSuggestions struct {
 	Text  string `json:"text,omitempty"`
 	Phone string `json:"phone,omitempty"`
 	Email string `json:"email,omitempty"`
+	URL   string `json:"url,omitempty"`
 }
 
 type ChannelSettingsTemplate struct {
@@ -437,13 +438,15 @@ const (
 	SuggestionTypeText  SuggestionType = "text"
 	SuggestionTypeEmail SuggestionType = "email"
 	SuggestionTypePhone SuggestionType = "phone"
+	SuggestionTypeURL   SuggestionType = "url"
 )
 
 type SuggestionType string
 
 type Suggestion struct {
-	Type  SuggestionType `json:"type"`
-	Title string         `json:"title,omitempty"` // required for type=text and ignored for others
+	Type    SuggestionType `json:"type"`
+	Title   string         `json:"title,omitempty"`   // required for type=text and optional for others
+	Payload string         `json:"payload,omitempty"` // ignored for type=text
 }
 
 type TemplateInfo struct {
diff --git a/v1/types_test.go b/v1/types_test.go
index 80076dd..12d75cb 100644
--- a/v1/types_test.go
+++ b/v1/types_test.go
@@ -203,3 +203,82 @@ func TestTemplateInfoUnmarshal(t *testing.T) {
 	assert.Equal(t, []string{"BABA", "JABA"}, tmpl.Variables.Body)
 	assert.Equal(t, [][]string{{"button1"}, {}, {"button2"}}, tmpl.Variables.Buttons)
 }
+
+func TestUnmarshalMessageWebhook(t *testing.T) {
+	msgJSON := `{
+	  "type": "message_sent",
+	  "meta": {
+		"timestamp": 1703523308
+	  },
+	  "data": {
+		"external_user_id": "79998887766",
+		"external_chat_id": "",
+		"channel_id": 83,
+		"type": "text",
+		"content": "Thank you for your order\n\nYou have placed order No. 8061C in the amount of 17400. We have already started working on it and will soon notify you of a change in status.\n\nStay with us",
+		"quote_external_id": null,
+		"quote_content": null,
+		"in_app_id": 638,
+		"bot": {
+		  "id": 760,
+		  "name": "Bot system",
+		  "avatar": ""
+		},
+		"customer": {
+		  "first_name": "",
+		  "last_name": "",
+		  "avatar": ""
+		},
+		"template": {
+		  "code": "f87e678f_660b_461a_b60a_a6194e2e9094#thanks_for_order#ru",
+		  "args": [
+			"8061C",
+			"17400"
+		  ],
+		  "variables": {
+			"body": [
+			  "8061C",
+			  "17400"
+			],
+			"buttons": [
+			  [],
+			  [
+				"8061"
+			  ]
+			]
+		  }
+		},
+		"attachments": {
+		  "suggestions": [
+			{
+			  "type": "text",
+			  "title": "ОК"
+			},
+			{
+			  "type": "url",
+			  "title": "Our site",
+			  "payload": "https://site.com/8061"
+			}
+		  ]
+		}
+	  }
+	}`
+
+	var wh struct {
+		Data MessageWebhookData `json:"data"`
+	}
+	assert.NoError(t, json.Unmarshal([]byte(msgJSON), &wh))
+
+	assert.NotNil(t, wh.Data.Attachments)
+	assert.Len(t, wh.Data.Attachments.Suggestions, 2)
+
+	okButton := wh.Data.Attachments.Suggestions[0]
+	assert.Equal(t, SuggestionTypeText, okButton.Type)
+	assert.Equal(t, "ОК", okButton.Title)
+	assert.Empty(t, okButton.Payload)
+
+	urlButton := wh.Data.Attachments.Suggestions[1]
+	assert.Equal(t, SuggestionTypeURL, urlButton.Type)
+	assert.Equal(t, "Our site", urlButton.Title)
+	assert.Equal(t, "https://site.com/8061", urlButton.Payload)
+}