Установка плагина для Redmine - Telegram email
Данная инструкция покажет как сделать Telegram канал для информирования об изменении в проектах.
Так же можно реализовать, что бы лично каждому пользователю в Telegram бот приходило уведомление.
Установка Telegram email
Инструкцию по установке можно найти можно найти тут
Для установки переходим в папку с плагинами:
cd /var/www/redmine/plugins
Нужно скачать сам плагин:
git clone https://github.com/aekondratiev/redmine_telegram_email redmine_telegram_email
Установка плагина:
bundle install
Производим миграцию
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
После чего перезапускаем службу:
bundle exec rake generate_secret_token
Необходимо заменить в файле listner.rb
, для этого переходим в папку
sudo nano /var/www/redmine/lib/redmine_telegram_email/listener.rb
Заменить все на это
require 'httpclient'
class RedmineTelegramEmail::Listener < Redmine::Hook::Listener
DEBUG = 0
def redmine_telegram_email_issues_new_after_save(context={})
issue = context[:issue]
users = []
users.push(issue.author) if issue.author != issue.assigned_to
users.push(issue.assigned_to) if issue.assigned_to
if issue.assigned_to.type == 'Group'
g_users = User.where(id: issue.assigned_to.user_ids, status: 1)
users.push(*g_users) if g_users
else
users.push(issue.assigned_to)
end
issue.watcher_users.each do |watcher|
if watcher.type == 'Group'
g_users = User.where(id: watcher.user_ids, status: 1)
users.push(*g_users) if g_users
else
users.push(watcher)
end
end
msg = "<b>[#{escape issue.project}]</b>\n<a href='#{object_url issue}'>#{escape issue}</a>\n<b>#{escape issue.author}</b> #{l(:field_created_on)}\n"
Rails.logger.info("TELEGRAM NEW ISSUE [#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}")
attachment = {}
attachment[:text] = escape issue.description if issue.description
attachment[:fields] = [{
:title => I18n.t("field_status"),
:value => escape(issue.status.to_s),
:short => true
}, {
:title => I18n.t("field_priority"),
:value => escape(issue.priority.to_s),
:short => true
}, {
:title => I18n.t("field_assigned_to"),
:value => escape(issue.assigned_to.to_s),
:short => true
}]
attachment[:fields] << {
:title => I18n.t("field_watcher"),
:value => escape(issue.watcher_users.join(', ')),
:short => true
} if Setting.plugin_redmine_telegram_email['display_watchers'] == 'yes'
users_processing users, issue, msg, attachment
end
def redmine_telegram_email_issues_edit_after_save(context={})
issue = context[:issue]
journal = context[:journal]
Rails.logger.info("TELEGRAM CONTENT #{context} WATCHERS #{issue.watcher_users} ASSIGNED_TO #{issue.assigned_to} ISSUEAUTHOR #{issue.author}") if DEBUG == 1
users = []
users.push(issue.author) if issue.author != issue.assigned_to
if issue.assigned_to.type == 'Group'
g_users = User.where(id: issue.assigned_to.user_ids, status: 1)
users.push(*g_users) if g_users
else
users.push(issue.assigned_to)
end
issue.watcher_users.each do |watcher|
if watcher.type == 'Group'
g_users = User.where(id: watcher.user_ids, status: 1)
users.push(*g_users) if g_users
else
users.push(watcher)
end
end
users = users.uniq
msg = "<b>[#{escape issue.project}]</b>\n<a href='#{object_url issue}'>#{escape issue}</a>\n<b>#{journal.user.to_s}</b> #{l(:field_updated_on)}"
Rails.logger.info("TELEGRAM EDITED ISSUE [#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] (#{issue.status.name}) #{issue.subject}")
attachment = {}
attachment[:text] = escape journal.notes if journal.notes
attachment[:fields] = journal.details.map { |d| detail_to_field d }
users_processing users, issue, msg, attachment
end
def users_processing(users, issue, msg, attachment)
users.each do |user|
Rails.logger.info("TELEGRAM USER ARRAY NAME: #{user}") if DEBUG == 1
next if user.id.to_i == issue.author_id.to_i and Setting.plugin_redmine_telegram_email[:selfupdate_dont_send] == '1'
telegram_chat_id = 0
telegram_disable = 0
user.custom_field_values.each do |telegram_field|
if telegram_field.custom_field.name.to_s == 'Telegram Channel' and telegram_field.value.to_i != 0
telegram_chat_id = telegram_field.value.to_i
end
if telegram_field.custom_field.name.to_s == 'Telegram disable email'
telegram_disable = telegram_field.value.to_i
end
end
Rails.logger.info("TELEGRAM CHAT AND DISABLED #{telegram_chat_id} #{telegram_disable}") if DEBUG == 1
if telegram_chat_id != 0
speak msg, telegram_chat_id, attachment
Rails.logger.info("TELEGRAM SPEAK TO #{telegram_chat_id} #{attachment} #{user.login}")
end
end
end
def speak(msg, channel, attachment=nil)
Rails.logger.info("TELEGRAM SPEAK\n #{msg}\n => #{channel}") if DEBUG == 1
token = Setting.plugin_redmine_telegram_email['telegram_bot_token']
Rails.logger.info("TELEGRAM TOKEN EMPTY, PLEASE SET IT IN PLUGIN SETTINGS") if token.nil? || token.empty?
proxyurl = Setting.plugin_redmine_telegram_email['proxyurl']
telegram_url = "https://api.telegram.org/bot#{token}/sendMessage"
Rails.logger.info("telegram_url #{telegram_url}")
params = {}
params[:chat_id] = channel if channel
params[:parse_mode] = "HTML"
params[:disable_web_page_preview] = 1
if attachment
msg = msg + "\r\n"
msg = msg + attachment[:text] if attachment[:text]
for field_item in attachment[:fields] do
msg = msg +"\r\n"+"<b>"+field_item[:title]+":</b> " + escape(field_item[:value])
end
end
params[:text] = msg
Thread.new do
retries = 0
begin
if Setting.plugin_redmine_telegram_email['use_proxy'] == '1'
client = HTTPClient.new(proxyurl)
else
client = HTTPClient.new
end
client.connect_timeout = 2
client.send_timeout = 2
client.receive_timeout = 2
client.keep_alive_timeout = 2
client.ssl_config.timeout = 2
conn = client.post_async(telegram_url, params)
Rails.logger.info("TELEGRAM TEXT TO SEND #{params[:text]}") if DEBUG == 1
Rails.logger.info("TELEGRAM ANSWER #{conn.pop.body.read}") if DEBUG == 1
Rails.logger.info("TELEGRAM CODE: #{conn.pop.status_code}")
rescue Exception => e
Rails.logger.warn("TELEGRAM CANNOT CONNECT TO #{telegram_url} RETRY ##{retries}, ERROR #{e}")
retry if (retries += 1) < 5
end
end
end
private
def escape(msg)
msg.to_s.gsub("&", "&").gsub("<", "<").gsub(">", ">")
end
def object_url(obj)
if Setting.host_name.to_s =~ /\A(https?\:\/\/)?(.+?)(\:(\d+))?(\/.+)?\z/i
host, port, prefix = $2, $4, $5
Rails.application.routes.url_for(obj.event_url({
:host => host,
:protocol => Setting.protocol,
:port => port,
:script_name => prefix
}))
else
Rails.application.routes.url_for(obj.event_url({
:host => Setting.host_name,
:protocol => Setting.protocol
}))
end
end
def detail_to_field(detail)
case detail.property
when "cf"
custom_field = detail.custom_field
key = custom_field.name
title = key
value = (detail.value)? IssuesController.helpers.format_value(detail.value, custom_field) : ""
when "attachment"
key = "attachment"
title = I18n.t :label_attachment
value = escape detail.value.to_s
else
key = detail.prop_key.to_s.sub("_id", "")
if key == "parent"
title = I18n.t "field_#{key}_issue"
else
title = I18n.t "field_#{key}"
end
value = escape detail.value.to_s
end
short = true
case key
when "title", "subject", "description"
short = false
when "tracker"
tracker = Tracker.find(detail.value) rescue nil
value = escape tracker.to_s
when "project"
project = Project.find(detail.value) rescue nil
value = escape project.to_s
when "status"
status = IssueStatus.find(detail.value) rescue nil
value = escape status.to_s
when "priority"
priority = IssuePriority.find(detail.value) rescue nil
value = escape priority.to_s
when "category"
category = IssueCategory.find(detail.value) rescue nil
value = escape category.to_s
when "assigned_to"
user = User.find(detail.value) rescue nil
value = escape user.to_s
when "fixed_version"
version = Version.find(detail.value) rescue nil
value = escape version.to_s
when "attachment"
attachment = Attachment.find(detail.prop_key) rescue nil
value = "<#{object_url attachment}|#{escape attachment.filename}>" if attachment
when "parent"
issue = Issue.find(detail.value) rescue nil
value = "<#{object_url issue}|#{escape issue}>" if issue
end
value = "-" if value.empty?
result = { :title => title, :value => value }
result[:short] = true if short
result
end
end
Так же в этом файле мы добавляем возможность отправлять сообщения в Telegram при назначенной группе на задачу . То есть если задача назначена группе, то все члены группы получат сообщения в Telegram.
Производим миграцию
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
После чего перезапускаем службу:
bundle exec rake generate_secret_token
После этого необходимо запустить службу:
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
Заходим на сайт http://IP:3000 и заходим в Администрирование
:
Выбираем Модули
, если все установлено верно, будет модуль телграм. Нажимаем Параметры
Telegram BOT Token - сюда вводится token бота.
Далее для корректной работы необходимо добавить пользовательские поля для пользователей.
Переходим в пункт Настраиваемые поля
-> Новое настраиваемое поле
-> Пользователи
и прописываем именно данный параметр в Имя
и убираем галочку с Видимое
.
Telegram Channel
Сохраняем и создаем еще одно, только теперь Формат
нужно поставить Логический
, снять галочку Видимое
и Имя
:
Telegram disable email
Создания пользователя для оповещения
Для начала Создаем Канал в Telegram, добавляем в него созданного ранее бота.
После чего нам нужно определить какой ID канала, для этого пишем любое сообщение в канал и пересылаем это сообщение этому боту. В ответ он отправляет несколько ID, нас интересует то что с "-".
Forwarded from chat: -1002336217068
Переходим в пункт Пользователи
и нажимаем Новый пользователь
и заполняем поля. В поле Telegram Channel
пишем ID канала Telegram, полученный через бот ранее.
Сохраняем и переходим в Группы
и нажимаем Новая группа
, даем ей понятное для нас название и после добавляем пользователей в эту группу
Переходим в Настройки
-> Задачи
и ставим галочку на Разрешить назначение задач группам пользователей
. Данный пункт позволит назначать группу пользователей на Задачу
Далее схема работы будет следующая, когда создается задача, необходимо назначать созданную группу, после чего будет приходить сообщение в канал Telegram. Всех своих коллег\друзей можно добавить в этот канал. Далее использовать Telegram канал как базу знаний, там хороший поиск.
Надеюсь у Вас все получилось и Вы можете пользоваться этим с удовольствием.