Repository: prometheus/alertmanager
File: notify/slack/slack.go (Go)

Code before:
		content, err := os.ReadFile(n.conf.APIURLFile)
		if err != nil {
			return false, err
		}
		u = strings.TrimSpace(string(content))
	}

	if n.conf.Timeout > 0 {
		postCtx, cancel := context.WithTimeoutCause(ctx, n.conf.Timeout, fmt.Errorf("configured slack timeout reached (%s)", n.conf.Timeout))
		defer cancel()
		ctx = postCtx
	}

	req := &request{
		Channel:     tmplText(n.conf.Channel),
		Username:    tmplText(n.conf.Username),
		IconEmoji:   tmplText(n.conf.IconEmoji),
		IconURL:     tmplText(n.conf.IconURL),
		LinkNames:   n.conf.LinkNames,
		Text:        tmplText(n.conf.MessageText),
		Attachments: []attachment{*att},
	}

	// If a notification for this alert group has already been sent and `update_message` config is set
	// edit API endpoint and payload to update notification instead of sending a new one.
	if n.conf.UpdateMessage && threadTs != "" && channelId != "" {
		u = strings.Replace(u, "chat.postMessage", "chat.update", 1)
		req.Timestamp = threadTs
		req.Channel = channelId
		logger.With("threadTs", threadTs).With("channelId", channelId).Debug("updating previously sent message")
	}

	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(req); err != nil {
		return false, err
	}

	resp, err := n.postJSONFunc(ctx, n.client, u, &buf)
	if err != nil {
		if ctx.Err() != nil {
			err = fmt.Errorf("%w: %w", err, context.Cause(ctx))
		}
		return true, notify.RedactURL(err)
	}
	defer notify.Drain(resp)

	// Use a retrier to generate an error message for non-200 responses and
	// classify them as retriable or not.
	retry, err := n.retrier.Check(resp.StatusCode, resp.Body)
	if err != nil {
		err = fmt.Errorf("channel %q: %w", req.Channel, err)

Review comment (bug):
We are already trying to retrieve these values from nflog above, so we can have a boolean (let's call it `messageUpdatable` or something like that) which is set to `n.conf.UpdateMessage` value and then it is set to false on failure to retrieve these values and use that single boolean for a simpler condition here.

Code after:
		LinkNames:   n.conf.LinkNames,
		Text:        tmplText(n.conf.MessageText),
		Attachments: []attachment{*att},
	}

	// If a notification for this alert group has already been sent and `update_message` config is set
	// edit API endpoint and payload to update notification instead of sending a new one.
	var store *nflog.Store

	if n.conf.UpdateMessage {
		var ok bool
		store, ok = notify.NflogStore(ctx)
		if !ok {
			logger.Warn("cannot create NflogStore, updatable messages will be disabled.")
		} else {
			threadTs, _ := store.GetStr("threadTs")
			channelId, _ := store.GetStr("channelId")
			logger.Debug("attempt recovering threadTs and channelId to update an existing message", "threadTs", threadTs, "channelId", channelId)
			if threadTs != "" && channelId != "" {
				u = "https://slack.com/api/chat.update"
				req.Timestamp = threadTs
				req.Channel = channelId
				logger.Debug("updating previously sent message", "threadTs", threadTs, "channelId", channelId)
			}
		}
	}
	var buf bytes.Buffer
	if err := json.NewEncoder(&buf).Encode(req); err != nil {
		return false, err
	}

	resp, err := n.postJSONFunc(ctx, n.client, u, &buf)
	if err != nil {
		if ctx.Err() != nil {
			err = fmt.Errorf("%w: %w", err, context.Cause(ctx))
		}
		return true, notify.RedactURL(err)
	}
	defer notify.Drain(resp)

	// Use a retrier to generate an error message for non-200 responses and
	// classify them as retriable or not.
	retry, err := n.retrier.Check(resp.StatusCode, resp.Body)
	if err != nil {
		err = fmt.Errorf("channel %q: %w", req.Channel, err)
		return retry, notify.NewErrorWithReason(notify.GetFailureReasonFromStatusCode(resp.StatusCode), err)
	}

	retry, err = n.slackResponseHandler(resp, store)
	if err != nil {
		err = fmt.Errorf("channel %q: %w", req.Channel, err)