func MsgOptionDeleteOriginal(responseURL string) MsgOption {
	return func(config *sendConfig) error {
		config.mode = chatResponse
		config.endpoint = responseURL
		config.deleteOriginal = true
		return nil
	}
}
MsgOptionDeleteOriginal deletes original message with response url
package slack
import (
	"context"
	"encoding/json"
	"net/http"
	"net/url"
	"strconv"
	"github.com/slack-go/slack/slackutilsx"
)
const (
	DEFAULT_MESSAGE_USERNAME         = ""
	DEFAULT_MESSAGE_REPLY_BROADCAST  = false
	DEFAULT_MESSAGE_ASUSER           = false
	DEFAULT_MESSAGE_PARSE            = ""
	DEFAULT_MESSAGE_THREAD_TIMESTAMP = ""
	DEFAULT_MESSAGE_LINK_NAMES       = 0
	DEFAULT_MESSAGE_UNFURL_LINKS     = false
	DEFAULT_MESSAGE_UNFURL_MEDIA     = true
	DEFAULT_MESSAGE_ICON_URL         = ""
	DEFAULT_MESSAGE_ICON_EMOJI       = ""
	DEFAULT_MESSAGE_MARKDOWN         = true
	DEFAULT_MESSAGE_ESCAPE_TEXT      = true
)
type chatResponseFull struct {
	Channel            string `json:"channel"`
	Timestamp          string `json:"ts"`                              
	MessageTimeStamp   string `json:"message_ts"`                      
	ScheduledMessageID string `json:"scheduled_message_id,omitempty"`  
	Text               string `json:"text"`
	SlackResponse
}
func (c chatResponseFull) getMessageTimestamp() string {
	if len(c.Timestamp) > 0 {
		return c.Timestamp
	}
	return c.MessageTimeStamp
}
type PostMessageParameters struct {
	Username        string `json:"username"`
	AsUser          bool   `json:"as_user"`
	Parse           string `json:"parse"`
	ThreadTimestamp string `json:"thread_ts"`
	ReplyBroadcast  bool   `json:"reply_broadcast"`
	LinkNames       int    `json:"link_names"`
	UnfurlLinks     bool   `json:"unfurl_links"`
	UnfurlMedia     bool   `json:"unfurl_media"`
	IconURL         string `json:"icon_url"`
	IconEmoji       string `json:"icon_emoji"`
	Markdown        bool   `json:"mrkdwn,omitempty"`
	EscapeText      bool   `json:"escape_text"`
	Channel string `json:"channel"`
	User    string `json:"user"`
}
func NewPostMessageParameters() PostMessageParameters {
	return PostMessageParameters{
		Username:        DEFAULT_MESSAGE_USERNAME,
		User:            DEFAULT_MESSAGE_USERNAME,
		AsUser:          DEFAULT_MESSAGE_ASUSER,
		Parse:           DEFAULT_MESSAGE_PARSE,
		ThreadTimestamp: DEFAULT_MESSAGE_THREAD_TIMESTAMP,
		LinkNames:       DEFAULT_MESSAGE_LINK_NAMES,
		UnfurlLinks:     DEFAULT_MESSAGE_UNFURL_LINKS,
		UnfurlMedia:     DEFAULT_MESSAGE_UNFURL_MEDIA,
		IconURL:         DEFAULT_MESSAGE_ICON_URL,
		IconEmoji:       DEFAULT_MESSAGE_ICON_EMOJI,
		Markdown:        DEFAULT_MESSAGE_MARKDOWN,
		EscapeText:      DEFAULT_MESSAGE_ESCAPE_TEXT,
	}
}
func (api *Client) DeleteMessage(channel, messageTimestamp string) (string, string, error) {
	respChannel, respTimestamp, _, err := api.SendMessageContext(
		context.Background(),
		channel,
		MsgOptionDelete(messageTimestamp),
	)
	return respChannel, respTimestamp, err
}
func (api *Client) DeleteMessageContext(ctx context.Context, channel, messageTimestamp string) (string, string, error) {
	respChannel, respTimestamp, _, err := api.SendMessageContext(
		ctx,
		channel,
		MsgOptionDelete(messageTimestamp),
	)
	return respChannel, respTimestamp, err
}
func (api *Client) ScheduleMessage(channelID, postAt string, options ...MsgOption) (string, string, error) {
	respChannel, respTimestamp, _, err := api.SendMessageContext(
		context.Background(),
		channelID,
		MsgOptionSchedule(postAt),
		MsgOptionCompose(options...),
	)
	return respChannel, respTimestamp, err
}
func (api *Client) PostMessage(channelID string, options ...MsgOption) (string, string, error) {
	respChannel, respTimestamp, _, err := api.SendMessageContext(
		context.Background(),
		channelID,
		MsgOptionPost(),
		MsgOptionCompose(options...),
	)
	return respChannel, respTimestamp, err
}
func (api *Client) PostMessageContext(ctx context.Context, channelID string, options ...MsgOption) (string, string, error) {
	respChannel, respTimestamp, _, err := api.SendMessageContext(
		ctx,
		channelID,
		MsgOptionPost(),
		MsgOptionCompose(options...),
	)
	return respChannel, respTimestamp, err
}
func (api *Client) PostEphemeral(channelID, userID string, options ...MsgOption) (string, error) {
	return api.PostEphemeralContext(
		context.Background(),
		channelID,
		userID,
		options...,
	)
}
func (api *Client) PostEphemeralContext(ctx context.Context, channelID, userID string, options ...MsgOption) (timestamp string, err error) {
	_, timestamp, _, err = api.SendMessageContext(
		ctx,
		channelID,
		MsgOptionPostEphemeral(userID),
		MsgOptionCompose(options...),
	)
	return timestamp, err
}
func (api *Client) UpdateMessage(channelID, timestamp string, options ...MsgOption) (string, string, string, error) {
	return api.SendMessageContext(
		context.Background(),
		channelID,
		MsgOptionUpdate(timestamp),
		MsgOptionCompose(options...),
	)
}
func (api *Client) UpdateMessageContext(ctx context.Context, channelID, timestamp string, options ...MsgOption) (string, string, string, error) {
	return api.SendMessageContext(
		ctx,
		channelID,
		MsgOptionUpdate(timestamp),
		MsgOptionCompose(options...),
	)
}
func (api *Client) UnfurlMessage(channelID, timestamp string, unfurls map[string]Attachment, options ...MsgOption) (string, string, string, error) {
	return api.SendMessageContext(context.Background(), channelID, MsgOptionUnfurl(timestamp, unfurls), MsgOptionCompose(options...))
}
func (api *Client) SendMessage(channel string, options ...MsgOption) (string, string, string, error) {
	return api.SendMessageContext(context.Background(), channel, options...)
}
func (api *Client) SendMessageContext(ctx context.Context, channelID string, options ...MsgOption) (_channel string, _timestamp string, _text string, err error) {
	var (
		req      *http.Request
		parser   func(*chatResponseFull) responseParser
		response chatResponseFull
	)
	if req, parser, err = buildSender(api.endpoint, options...).BuildRequest(api.token, channelID); err != nil {
		return "", "", "", err
	}
	if err = doPost(ctx, api.httpclient, req, parser(&response), api); err != nil {
		return "", "", "", err
	}
	return response.Channel, response.getMessageTimestamp(), response.Text, response.Err()
}
func UnsafeApplyMsgOptions(token, channel, apiurl string, options ...MsgOption) (string, url.Values, error) {
	config, err := applyMsgOptions(token, channel, apiurl, options...)
	return config.endpoint, config.values, err
}
func applyMsgOptions(token, channel, apiurl string, options ...MsgOption) (sendConfig, error) {
	config := sendConfig{
		apiurl:   apiurl,
		endpoint: apiurl + string(chatPostMessage),
		values: url.Values{
			"token":   {token},
			"channel": {channel},
		},
	}
	for _, opt := range options {
		if err := opt(&config); err != nil {
			return config, err
		}
	}
	return config, nil
}
func buildSender(apiurl string, options ...MsgOption) sendConfig {
	return sendConfig{
		apiurl:  apiurl,
		options: options,
	}
}
type sendMode string
const (
	chatUpdate          sendMode = "chat.update"
	chatPostMessage     sendMode = "chat.postMessage"
	chatScheduleMessage sendMode = "chat.scheduleMessage"
	chatDelete          sendMode = "chat.delete"
	chatPostEphemeral   sendMode = "chat.postEphemeral"
	chatResponse        sendMode = "chat.responseURL"
	chatMeMessage       sendMode = "chat.meMessage"
	chatUnfurl          sendMode = "chat.unfurl"
)
type sendConfig struct {
	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) {
	if t, err = applyMsgOptions(token, channelID, t.apiurl, t.options...); err != nil {
		return nil, nil, err
	}
	switch t.mode {
	case chatResponse:
		return responseURLSender{
			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()
	}
}
type formSender struct {
	endpoint string
	values   url.Values
}
func (t formSender) BuildRequest() (*http.Request, func(*chatResponseFull) responseParser, error) {
	req, err := formReq(t.endpoint, t.values)
	return req, func(resp *chatResponseFull) responseParser {
		return newJSONParser(resp)
	}, err
}
type responseURLSender struct {
	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,
		ReplaceOriginal: t.replaceOriginal,
		DeleteOriginal:  t.deleteOriginal,
	})
	return req, func(resp *chatResponseFull) responseParser {
		return newContentTypeParser(resp)
	}, err
}
type MsgOption func(*sendConfig) error
func MsgOptionSchedule(postAt string) MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatScheduleMessage)
		config.values.Add("post_at", postAt)
		return nil
	}
}
func MsgOptionPost() MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatPostMessage)
		config.values.Del("ts")
		return nil
	}
}
func MsgOptionPostEphemeral(userID string) MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatPostEphemeral)
		MsgOptionUser(userID)(config)
		config.values.Del("ts")
		return nil
	}
}
func MsgOptionMeMessage() MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatMeMessage)
		return nil
	}
}
func MsgOptionUpdate(timestamp string) MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatUpdate)
		config.values.Add("ts", timestamp)
		return nil
	}
}
func MsgOptionDelete(timestamp string) MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatDelete)
		config.values.Add("ts", timestamp)
		return nil
	}
}
func MsgOptionUnfurl(timestamp string, unfurls map[string]Attachment) MsgOption {
	return func(config *sendConfig) error {
		config.endpoint = config.apiurl + string(chatUnfurl)
		config.values.Add("ts", timestamp)
		unfurlsStr, err := json.Marshal(unfurls)
		if err == nil {
			config.values.Add("unfurls", string(unfurlsStr))
		}
		return err
	}
}
func MsgOptionResponseURL(url string, responseType string) MsgOption {
	return func(config *sendConfig) error {
		config.mode = chatResponse
		config.endpoint = url
		config.responseType = responseType
		config.values.Del("ts")
		return nil
	}
}
func MsgOptionReplaceOriginal(responseURL string) MsgOption {
	return func(config *sendConfig) error {
		config.mode = chatResponse
		config.endpoint = responseURL
		config.replaceOriginal = true
		return nil
	}
}