Skip to content

Commit

Permalink
Allow custom fields to be passed into the slack_fields payload
Browse files Browse the repository at this point in the history
Currently, you can only use the built in slack fields of:

```
['status', 'stage', 'branch', 'revision', 'hosts']
```

This change allows custom fields to be passed through by defining a
mapping of how to display them. e.g.

```
set :slack_fields, ['status', 'environment', 'docker_image']
set :slack_custom_field_mapping, -> {
  {
    'environment' => {
      title: 'Environment',
      value: -> {
        if fetch(:stage) == :production
          'production'
        else
          "staging-#{fetch(:staging_name)
        end
      },
      short: true,
    },
    'docker_image' => {
      title: 'Docker image',
      value: fetch(:docker_image),
      short: false,
    },
  }
}
```
  • Loading branch information
mikespokefire committed Jul 25, 2016
1 parent ec4a33e commit ede6991
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 27 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,32 @@ Any of the defaults can be over-ridden in `config/deploy.rb`:
set :slack_deploy_failed_color, 'danger'
set :slack_notify_events, [:started, :finished, :failed]

You can setup custom fields by defining a mapping for how to display them in slack:

set :slack_fields, ['status', 'environment', 'docker_image']
# You could also add your custom mappings to the defaults with:
# set :slack_fields, fetch(:slack_fields).push('environment', 'docker_image')
set :slack_custom_field_mapping, -> {
{
'environment' => {
title: 'Environment',
value: -> {
if fetch(:stage) == :production
'production'
else
"staging-#{fetch(:staging_name)}"
end
},
short: true,
},
'docker_image' => {
title: 'Docker image',
value: fetch(:docker_image),
short: false,
},
}
}

To configure the way slack parses your message (see 'Parsing Modes' at https://api.slack.com/docs/formatting) use the `:slack_parse` setting:

set :slack_parse, 'none' # available options: 'default', 'none', 'full'
Expand Down
1 change: 1 addition & 0 deletions lib/capistrano/tasks/slackify.cap
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ namespace :load do
set :slack_parse, 'default'
set :slack_user, -> { local_user.strip }
set :slack_fields, ['status', 'stage', 'branch', 'revision', 'hosts']
set :slack_custom_field_mapping, {}
set :slack_mrkdwn_in, []
set :slack_hosts, -> { release_roles(:all).map(&:hostname).join("\n") }
set :slack_url, -> { fail ':slack_url is not set' }
Expand Down
63 changes: 38 additions & 25 deletions lib/slackify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,44 @@ def build
end

def payload
fields_map = {
fields = fetch(:slack_fields).each_with_object([]) { |field, fields|
if fields_map[field].fetch(:value).respond_to?(:call)
field_data = fields_map[field]
field_data[:value] = field_data.fetch(:value).call
fields.push(field_data)
else
fields.push(fields_map[field])
end
}

MultiJson.dump(
{
channel: fetch(:slack_channel),
username: fetch(:slack_username),
icon_emoji: fetch(:slack_emoji),
parse: fetch(:slack_parse),
attachments: [
{
fallback: text,
color: color,
text: text,
fields: fields,
mrkdwn_in: fetch(:slack_mrkdwn_in),
}
]
}
)
end

def fields_map
@fields_map ||= [
default_field_map,
fetch(:slack_custom_field_mapping),
].reduce(&:merge)
end

def default_field_map
{
'status' => {
title: 'Status',
value: @status,
Expand All @@ -44,30 +81,6 @@ def payload
short: true
}
}

fields = []

fetch(:slack_fields).each { |field|
fields.push(fields_map[field])
}

MultiJson.dump(
{
channel: fetch(:slack_channel),
username: fetch(:slack_username),
icon_emoji: fetch(:slack_emoji),
parse: fetch(:slack_parse),
attachments: [
{
fallback: text,
color: color,
text: text,
fields: fields,
mrkdwn_in: fetch(:slack_mrkdwn_in),
}
]
}
)
end

def fetch(*args, &block)
Expand Down
18 changes: 16 additions & 2 deletions spec/lib/slackify_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,21 @@ module Slackify
slack_emoji: ':ghost:',
slack_parse: 'default',
slack_user: 'You',
slack_fields: ['status', 'stage', 'branch', 'revision', 'hosts'],
slack_fields: ['status', 'stage', 'branch', 'revision', 'hosts', 'custom_field', 'custom_field_with_proc'],
slack_custom_field_mapping: {
'custom_field' => {
title: 'custom title',
value: 'custom value',
short: false
},
'custom_field_with_proc' => {
title: 'custom title proc',
value: -> {
'custom value proc'
},
short: false
}
},
slack_mrkdwn_in: ['text'],
slack_hosts: "192.168.10.1\r192.168.10.2",
slack_text: ':boom:',
Expand All @@ -22,7 +36,7 @@ module Slackify
}

let(:payload) {
%{'payload={"channel":"#general","username":"Capistrano","icon_emoji":":ghost:","parse":"default","attachments":[{"fallback":":boom:","color":"good","text":":boom:","fields":[{"title":"Status","value":"success","short":true},{"title":"Stage","value":"sandbox","short":true},{"title":"Branch","value":"master","short":true},{"title":"Revision","value":"SHA","short":true},{"title":"Hosts","value":"192.168.10.1\\r192.168.10.2","short":true}],"mrkdwn_in":["text"]}]}'}
%{'payload={"channel":"#general","username":"Capistrano","icon_emoji":":ghost:","parse":"default","attachments":[{"fallback":":boom:","color":"good","text":":boom:","fields":[{"title":"Status","value":"success","short":true},{"title":"Stage","value":"sandbox","short":true},{"title":"Branch","value":"master","short":true},{"title":"Revision","value":"SHA","short":true},{"title":"Hosts","value":"192.168.10.1\\r192.168.10.2","short":true},{"title":"custom title","value":"custom value","short":false},{"title":"custom title proc","value":"custom value proc","short":false}],"mrkdwn_in":["text"]}]}'}
}

let(:text) { context.fetch(:slack_text) }
Expand Down

0 comments on commit ede6991

Please sign in to comment.