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

Issue notifications via direct message (#77) #124

Open
wants to merge 6 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
12 changes: 12 additions & 0 deletions app/views/settings/_slack_settings.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,15 @@
<label for="settings_post_wiki_updates">Post Wiki Updates?</label>
<input type="checkbox" id="settings_post_wiki_updates" value="1" name="settings[post_wiki_updates]" <%= settings['post_wiki_updates'] == '1' ? 'checked="checked"' : '' %> />
</p>
<p>
<label for="settings_post_updates">Post Direct Messages?</label>
<input type="checkbox" id="settings_direct_speak" value="1" name="settings[direct_speak]" <%= settings['direct_speak'] == '1' ? 'checked="checked"' : '' %> />
</p>

<p>
<label for="settings_direct_speak_rule">Direct Messages Rule</label>
<select id="settings_direct_speak_rule" value="<%= settings['direct_speak_rule'] %>" name="settings[direct_speak_rule]">
<option value="DirectPost_Disabled">Disabled</option>
<option value="DirectPost_IgnoreMyActions" <%= settings['direct_speak_rule'] != 'DirectPost_Disabled' ? %q(selected="selected") : '' %>>Send direct post if issue was modified not by assignee user</option>
</select>
</p>
114 changes: 100 additions & 14 deletions lib/redmine_slack/listener.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ def controller_issues_new_after_save(context={})
channel = channel_for_project issue.project
url = url_for_project issue.project

return unless channel and url
return if issue.is_private?

msg = "[#{escape issue.project}] #{escape issue.author} created <#{object_url issue}|#{escape issue}>#{mentions issue.description}"

attachment = {}
Expand All @@ -22,18 +19,24 @@ def controller_issues_new_after_save(context={})
:title => I18n.t("field_priority"),
:value => escape(issue.priority.to_s),
:short => true
}, {
}]
attachment[:fields] << {
:title => I18n.t("field_assigned_to"),
:value => escape(issue.assigned_to.to_s),
:value => escape("@"+issue.assigned_to.login),
:short => true
}]
} if issue.assigned_to

attachment[:fields] << {
:title => I18n.t("field_watcher"),
:value => escape(issue.watcher_users.join(', ')),
:short => true
} if Setting.plugin_redmine_slack['display_watchers'] == 'yes'

directSpeak issue, msg, attachment, url if Setting.plugin_redmine_slack[:direct_speak] == '1'

return unless channel and url
return if issue.is_private?

speak msg, channel, attachment, url
end

Expand All @@ -44,15 +47,28 @@ def controller_issues_edit_after_save(context={})
channel = channel_for_project issue.project
url = url_for_project issue.project

return unless channel and url and Setting.plugin_redmine_slack['post_updates'] == '1'
return if issue.is_private?
return if journal.private_notes?

msg = "[#{escape issue.project}] #{escape journal.user.to_s} updated <#{object_url issue}|#{escape issue}>#{mentions journal.notes}"

attachment = {}
attachment[:text] = escape journal.notes if journal.notes
attachment[:fields] = journal.details.map { |d| detail_to_field d }

directSpeak issue, msg, attachment, url if Setting.plugin_redmine_slack[:direct_speak] == '1'

# send msg to old user that he was aware of
old_user_obj = "nil"
journal.details.map { |d| old_user_obj = d if d.prop_key == "assigned_to_id" }
if not old_user_obj == "nil"
olduser = User.find(old_user_obj.old_value) rescue nil
if olduser != nil
issue.assigned_to = olduser
directSpeak issue, msg, attachment, url, true if Setting.plugin_redmine_slack[:direct_speak] == '1'
end
end

return unless channel and url and Setting.plugin_redmine_slack['post_updates'] == '1'
return if issue.is_private?
return if journal.private_notes?

speak msg, channel, attachment, url
end
Expand All @@ -65,9 +81,6 @@ def model_changeset_scan_commit_for_issue_ids_pre_issue_update(context={})
channel = channel_for_project issue.project
url = url_for_project issue.project

return unless channel and url and issue.save
return if issue.is_private?

msg = "[#{escape issue.project}] #{escape journal.user.to_s} updated <#{object_url issue}|#{escape issue}>"

repository = changeset.repository
Expand Down Expand Up @@ -100,6 +113,22 @@ def model_changeset_scan_commit_for_issue_ids_pre_issue_update(context={})
attachment = {}
attachment[:text] = ll(Setting.default_language, :text_status_changed_by_changeset, "<#{revision_url}|#{escape changeset.comments}>")
attachment[:fields] = journal.details.map { |d| detail_to_field d }

directSpeak issue, msg, attachment, url if Setting.plugin_redmine_slack[:direct_speak] == '1'

# send msg to old user that he was aware of
old_user_obj = "nil"
journal.details.map { |d| old_user_obj = d if d.prop_key == "assigned_to_id" }
if not old_user_obj == "nil"
olduser = User.find(old_user_obj.old_value) rescue nil
if olduser != nil
issue.assigned_to = olduser
directSpeak issue, msg, attachment, url, true if Setting.plugin_redmine_slack[:direct_speak] == '1'
end
end

return unless channel and url and issue.save
return if issue.is_private?

speak msg, channel, attachment, url
end
Expand Down Expand Up @@ -160,6 +189,55 @@ def speak(msg, channel, attachment=nil, url=nil)
Rails.logger.warn(e)
end
end

def directSpeak(issue, msg, attachment=nil, url=nil, full=false)

# Filter1. Send direct post if issue was modified not by assignee user
if issue.current_journal #if issue is edited
(return if issue.assigned_to and issue.current_journal.user.login == issue.assigned_to.login) if Setting.plugin_redmine_slack[:direct_speak_rule] == 'DirectPost_IgnoreMyActions'
end

url = Setting.plugin_redmine_slack[:slack_url] if not url
icon = Setting.plugin_redmine_slack[:icon]

params = {
:text => msg,
:link_names => 1,
}

params[:username] = "#{issue.author}"
if issue.assigned_to
params[:channel] = "@#{issue.assigned_to.login}"
else
params[:channel] = "@slackbot"
end

if attachment
# duplicate 'attachment' to 'localAttache' without 'Assignee' field for direct message
localAttache = attachment.dup
localAttache[:fields] = []
attachment[:fields].each {|x| localAttache[:fields] << x if full or not x.has_value?(I18n.t("field_assigned_to"))}

params[:attachments] = [localAttache]
end

if icon and not icon.empty?
if icon.start_with? ':'
params[:icon_emoji] = icon
else
params[:icon_url] = icon
end
end

begin
client = HTTPClient.new
client.ssl_config.cert_store.set_default_paths
client.ssl_config.ssl_version = "SSLv23"
client.post_async url, {:payload => params.to_json}
rescue
# Bury exception if connection error
end
end

private
def escape(msg)
Expand Down Expand Up @@ -229,6 +307,7 @@ def detail_to_field(detail)

short = true
value = escape detail.value.to_s
old_value = "nil"

case key
when "title", "subject", "description"
Expand All @@ -250,10 +329,16 @@ def detail_to_field(detail)
value = escape category.to_s
when "assigned_to"
user = User.find(detail.value) rescue nil
value = escape user.to_s
value = escape user.login

olduser = User.find(detail.old_value) rescue nil
old_value = escape olduser.to_s
when "fixed_version"
version = Version.find(detail.value) rescue nil
value = escape version.to_s

oldversion = Version.find(detail.old_value) rescue nil
old_value = escape oldversion.to_s
when "attachment"
attachment = Attachment.find(detail.prop_key) rescue nil
value = "<#{object_url attachment}|#{escape attachment.filename}>" if attachment
Expand All @@ -266,6 +351,7 @@ def detail_to_field(detail)

result = { :title => title, :value => value }
result[:short] = true if short
result[:old_value] = old_value
result
end

Expand Down
Loading