Commit 77f94168 authored by Jessica McKellar's avatar Jessica McKellar Committed by Jessica McKellar
Browse files

Add support for forwarding to Zulip on issue creation or update.

parent cf4a5c36
<p>
<%= form.text_field :zulip_email %>
This should be a bot address for most uses.
</p>
<p>
<%= form.text_field :zulip_api_key %>
The API key for the bot.
</p>
<p>
<%= form.text_field :zulip_stream %>
Which Zulip stream will receive updates. The message topic will be the project name.
</p>
<p>
<%= content_tag(:label, l(:zulip_settings_label_email)) %>
<%= text_field_tag 'settings[zulip_email]', @settings[:zulip_email] %>
</p>
<p>
<%= content_tag(:label, l(:zulip_settings_label_api_key)) %>
<%= text_field_tag 'settings[zulip_api_key]', @settings[:zulip_api_key] %>
</p>
<p>
<%= content_tag(:label, l(:zulip_settings_label_stream)) %>
<%= text_field_tag 'settings[zulip_stream]', @settings[:zulip_stream] %>
</p>
<p>
<%= content_tag(:label, l(:zulip_settings_label_projects)) %>
<%= select_tag 'settings[projects][]', project_tree_options_for_select(Project.active, :selected => Project.find_by_id(@settings[:projects])), :multiple => true, :size => Project.active.size %>
</p>
en:
zulip_settings_header: Zulip Plugin Configuration
zulip_settings_label_stream: Stream name
zulip_settings_label_email: Zulip Email
zulip_settings_label_api_key: Zulip API key
zulip_settings_label_projects: Projects
field_zulip_email: Zulip Email
field_zulip_api_key: Zulip API key
field_zulip_stream: Stream name
class AddZulipAuthToProject < ActiveRecord::Migration
def change
add_column :projects, :zulip_email, :string, :default => "", :null => false
add_column :projects, :zulip_api_key, :string, :default => "", :null => false
add_column :projects, :zulip_stream, :string, :default => "", :null => false
end
end
Redmine::Plugin.register :redmine_zulip do
name 'Zulip'
author 'Zulip, Inc.'
description 'Sends notifications to Zulip.'
version '0.9'
url 'https://github.com/zulip/zulip-redmine-plugin'
author_url 'https://www.zulip.com/'
Rails.configuration.to_prepare do
require_dependency 'zulip_hooks'
require_dependency 'zulip_view_hooks'
require_dependency 'project_patch'
Project.send(:include, RedmineZulip::Patches::ProjectPatch)
end
settings :partial => 'settings/redmine_zulip',
:default => {
:zulip_email => "",
:zulip_api_key => "",
:zulip_stream => ""}
end
module RedmineZulip
module Patches
module ProjectPatch
def self.included(base)
base.class_eval do
safe_attributes 'zulip_email', 'zulip_api_key', 'zulip_stream'
end
end
end
end
end
# encoding: utf-8
require 'json'
class NotificationHook < Redmine::Hook::Listener
# We generate Zulips for creating and updating issues.
def controller_issues_new_after_save(context = {})
extract_and_send(context, "new")
end
def controller_issues_edit_after_save(context = {})
extract_and_send(context, "edit")
end
private
def configured(project)
# The plugin can be configured as a system setting or per-project.
if !project.zulip_email.empty? && !project.zulip_api_key.empty? &&
!project.zulip_stream.empty?
# We have full per-project settings.
return true
elsif Setting.plugin_redmine_zulip[:projects] &&
Setting.plugin_redmine_zulip[:zulip_email] &&
Setting.plugin_redmine_zulip[:zulip_api_key] &&
Setting.plugin_redmine_zulip[:zulip_stream]
# We have full global settings.
return true
end
Rails.logger.info "Missing config, can't sent to Zulip!"
return false
end
def zulip_email(project)
if !project.zulip_email.empty?
return project.zulip_email
end
return Setting.plugin_redmine_zulip[:zulip_email]
end
def zulip_api_key(project)
if !project.zulip_api_key.empty?
return project.zulip_api_key
end
return Setting.plugin_redmine_zulip[:zulip_api_key]
end
def zulip_stream(project)
if !project.zulip_stream.empty?
return project.zulip_stream
end
return Setting.plugin_redmine_zulip[:zulip_stream]
end
def send_message(data)
Rails.logger.info "Forwarding to Zulip: #{data[:payload]}"
http = Net::HTTP.new("api.zulip.com", 443)
http.use_ssl = true
req = Net::HTTP::Post.new("/api/v1/external/redmine")
req.set_form_data({
"email" => data[:zulip_email],
"api-key" => data[:zulip_api_key],
"stream" => data[:zulip_stream],
"payload" => data[:payload]
})
begin
http.request(req)
rescue Net::HTTPBadResponse => e
Rails.logger.error "Error while POSTing to Zulip: #{e}"
end
end
def extract_and_send(context, type)
issue = context[:issue]
project = issue.project
if !configured(project)
# Fail silently: the rest of the app needs to continue working.
return true
end
author = CGI::escapeHTML(User.current.name)
subject = CGI::escapeHTML(issue.subject)
url = "#{Setting[:protocol]}://#{Setting[:host_name]}/issues/#{issue.id}"
payload = {:type => type,
:project => project.name,
:issue_id => issue.id,
:issue_subject => subject,
:issue_description => issue.description,
:priority => issue.priority.to_s,
:status => issue.status.to_s,
:assignee => issue.assigned_to.to_s,
:notes => issue.notes,
:author => author,
:url => "#{url}##{issue.id}"}.to_json
data = {:payload => payload,
:zulip_email => zulip_email(project),
:zulip_api_key => zulip_api_key(project),
:zulip_stream => zulip_stream(project)}
send_message(data)
end
end
class NotificationViewHook < Redmine::Hook::ViewListener
render_on(:view_projects_form, :partial => 'projects/redmine_zulip', :layout => false)
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment