Repository: slack-go/slack
Pull request #693 (2020-04-05 16:19:22)

Add support for replacing and deleting original message with `ResponseURL`
I added new msg options for replacing and deleting original message with `ResponseURL`.




Patch:
diff --git a/chat.go b/chat.go
index 1281b15..c5b524c 100644
--- a/chat.go
+++ b/chat.go
@@ -261,14 +261,16 @@ const (
 )
 
 type sendConfig struct {
-	apiurl       string
-	options      []MsgOption
-	mode         sendMode
-	endpoint     string
-	values       url.Values
-	attachments  []Attachment
-	blocks       Blocks
-	responseType string
+	apiurl          string
+	options         []MsgOption
+	mode            sendMode
+	endpoint        string
+	values          url.Values
+	attachments     []Attachment
+	blocks          Blocks
+	responseType    string
+	replaceOriginal bool
+	deleteOriginal  bool
 }
 
 func (t sendConfig) BuildRequest(token, channelID string) (req *http.Request, _ func(*chatResponseFull) responseParser, err error) {
@@ -279,11 +281,13 @@ func (t sendConfig) BuildRequest(token, channelID string) (req *http.Request, _
 	switch t.mode {
 	case chatResponse:
 		return responseURLSender{
-			endpoint:     t.endpoint,
-			values:       t.values,
-			attachments:  t.attachments,
-			blocks:       t.blocks,
-			responseType: t.responseType,
+			endpoint:        t.endpoint,
+			values:          t.values,
+			attachments:     t.attachments,
+			blocks:          t.blocks,
+			responseType:    t.responseType,
+			replaceOriginal: t.replaceOriginal,
+			deleteOriginal:  t.deleteOriginal,
 		}.BuildRequest()
 	default:
 		return formSender{endpoint: t.endpoint, values: t.values}.BuildRequest()
@@ -303,20 +307,24 @@ func (t formSender) BuildRequest() (*http.Request, func(*chatResponseFull) respo
 }
 
 type responseURLSender struct {
-	endpoint     string
-	values       url.Values
-	attachments  []Attachment
-	blocks       Blocks
-	responseType string
+	endpoint        string
+	values          url.Values
+	attachments     []Attachment
+	blocks          Blocks
+	responseType    string
+	replaceOriginal bool
+	deleteOriginal  bool
 }
 
 func (t responseURLSender) BuildRequest() (*http.Request, func(*chatResponseFull) responseParser, error) {
 	req, err := jsonReq(t.endpoint, Msg{
-		Text:         t.values.Get("text"),
-		Timestamp:    t.values.Get("ts"),
-		Attachments:  t.attachments,
-		Blocks:       t.blocks,
-		ResponseType: t.responseType,
+		Text:            t.values.Get("text"),
+		Timestamp:       t.values.Get("ts"),
+		Attachments:     t.attachments,
+		Blocks:          t.blocks,
+		ResponseType:    t.responseType,
+		ReplaceOriginal: t.replaceOriginal,
+		DeleteOriginal:  t.deleteOriginal,
 	})
 	return req, func(resp *chatResponseFull) responseParser {
 		return newContentTypeParser(resp)
@@ -405,6 +413,26 @@ func MsgOptionResponseURL(url string, responseType string) MsgOption {
 	}
 }
 
+// MsgOptionReplaceOriginal replaces original message with response url
+func MsgOptionReplaceOriginal(responseURL string) MsgOption {
+	return func(config *sendConfig) error {
+		config.mode = chatResponse
+		config.endpoint = responseURL
+		config.replaceOriginal = true
+		return nil
+	}
+}
+
+// MsgOptionDeleteOriginal deletes original message with response url
+func MsgOptionDeleteOriginal(responseURL string) MsgOption {
+	return func(config *sendConfig) error {
+		config.mode = chatResponse
+		config.endpoint = responseURL
+		config.deleteOriginal = true
+		return nil
+	}
+}
+
 // MsgOptionAsUser whether or not to send the message as the user.
 func MsgOptionAsUser(b bool) MsgOption {
 	return func(config *sendConfig) error {


Test patch:
diff --git a/chat_test.go b/chat_test.go
index 9783a56..450cae7 100644
--- a/chat_test.go
+++ b/chat_test.go
@@ -165,3 +165,57 @@ func TestPostMessageWithBlocksWhenMsgOptionResponseURLApplied(t *testing.T) {
 
 	_, _, _ = api.PostMessage("CXXX", MsgOptionBlocks(expectedBlocks...), MsgOptionText("text", false), MsgOptionResponseURL(responseURL, ResponseTypeInChannel))
 }
+
+func TestPostMessageWhenMsgOptionReplaceOriginalApplied(t *testing.T) {
+	http.DefaultServeMux = new(http.ServeMux)
+	http.HandleFunc("/response-url", func(rw http.ResponseWriter, r *http.Request) {
+		body, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("unexpected error: %v", err)
+			return
+		}
+		var msg Msg
+		if err := json.Unmarshal(body, &msg); err != nil {
+			t.Errorf("unexpected error: %v", err)
+			return
+		}
+		if msg.ReplaceOriginal != true {
+			t.Errorf("expected: true, got: %v", msg.ReplaceOriginal)
+			return
+		}
+	})
+
+	once.Do(startServer)
+	api := New(validToken, OptionAPIURL("http://"+serverAddr+"/"))
+
+	responseURL := api.endpoint + "response-url"
+
+	_, _, _ = api.PostMessage("CXXX", MsgOptionText("text", false), MsgOptionReplaceOriginal(responseURL))
+}
+
+func TestPostMessageWhenMsgOptionDeleteOriginalApplied(t *testing.T) {
+	http.DefaultServeMux = new(http.ServeMux)
+	http.HandleFunc("/response-url", func(rw http.ResponseWriter, r *http.Request) {
+		body, err := ioutil.ReadAll(r.Body)
+		if err != nil {
+			t.Errorf("unexpected error: %v", err)
+			return
+		}
+		var msg Msg
+		if err := json.Unmarshal(body, &msg); err != nil {
+			t.Errorf("unexpected error: %v", err)
+			return
+		}
+		if msg.DeleteOriginal != true {
+			t.Errorf("expected: true, got: %v", msg.DeleteOriginal)
+			return
+		}
+	})
+
+	once.Do(startServer)
+	api := New(validToken, OptionAPIURL("http://"+serverAddr+"/"))
+
+	responseURL := api.endpoint + "response-url"
+
+	_, _, _ = api.PostMessage("CXXX", MsgOptionDeleteOriginal(responseURL))
+}