Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail on errors returned from the Slack API when using API Token #86

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,8 @@ func postMessage(conf Config, msg Message) error {
return fmt.Errorf("server error: %s, response: %s", resp.Status, body)
}

if err := exportOutputs(&conf, resp); err != nil {
return fmt.Errorf("failed to export outputs: %s", err)
if err := processResponse(&conf, resp); err != nil {
return err
}

return nil
Expand All @@ -176,6 +176,11 @@ func validate(conf *Config) error {
conf.WebhookURL = ""

}

if conf.APIToken == "" && isRequestingOutput(conf) {
return fmt.Errorf("Outputs can only be set when using the API Token.")
}

return nil
}

Expand Down
34 changes: 19 additions & 15 deletions outputs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,43 @@ import (
"fmt"
"net/http"
"os/exec"
"strings"

"github.com/bitrise-io/go-utils/log"
)

// SendMessageResponse is the response from Slack POST
// https://api.slack.com/methods/chat.postMessage#examples
type SendMessageResponse struct {
/// The status of the request. When `false`, check the Error for a reason
Ok bool `json:"ok"`

/// Describes an error that prevented the message from being sent
Error string `json:"error"`

/// The Thread Timestamp
Timestamp string `json:"ts"`
}

/// Export the output variables after a successful response
func exportOutputs(conf *Config, resp *http.Response) error {

if !isRequestingOutput(conf) {
log.Debugf("Not requesting any outputs")
// Check the response status and set any output variables if required
func processResponse(conf *Config, resp *http.Response) error {
// if the request was made using a legacy webhook url, skip processing as there is no response.
if conf.APIToken == "" {
log.Debugf("Skipping response processing because legacy webhook urls do not return any content")
return nil
}

isWebhook := strings.TrimSpace(selectValue(string(conf.WebhookURL), string(conf.WebhookURLOnError))) != ""

// Slack webhooks do not return any useful response information
if isWebhook {
return fmt.Errorf("For output support, do not submit a WebHook URL")
}

var response SendMessageResponse
parseError := json.NewDecoder(resp.Body).Decode(&response)
if parseError != nil {
// here we want to fail, because the user is expecting an output
return fmt.Errorf("Failed to parse response: %s", parseError)
}

// if slack didn't return 'ok', fail with the error code
if !response.Ok {
return fmt.Errorf("Slack responded with error: %s", response.Error)
}

if string(conf.ThreadTsOutputVariableName) != "" {
log.Debugf("Exporting output: %s=%s\n", string(conf.ThreadTsOutputVariableName), response.Timestamp)
err := exportEnvVariable(string(conf.ThreadTsOutputVariableName), response.Timestamp)
Expand All @@ -50,12 +54,12 @@ func exportOutputs(conf *Config, resp *http.Response) error {

}

/// Checks if we are requesting an output of anything
// Checks if we are requesting an output of anything
func isRequestingOutput(conf *Config) bool {
return string(conf.ThreadTsOutputVariableName) != ""
}

/// Exports env using envman
// Exports env using envman
func exportEnvVariable(variable string, value string) error {
c := exec.Command("envman", "add", "--key", variable, "--value", value)
err := c.Run()
Expand Down