Skip to content

Commit

Permalink
Add bot message attribute to TelegramMessage, Add daily report worker…
Browse files Browse the repository at this point in the history
…, add some localization, bot can identify bot messages
  • Loading branch information
arturtr committed Apr 6, 2016
1 parent 63f7f59 commit 29654d2
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 70 deletions.
6 changes: 4 additions & 2 deletions app/controllers/telegram_group_chats_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ def create
shared_url: telegram_chat_url
end

@issue.init_journal(current_user, "По ссылке #{telegram_chat_url} создан чат.")
@issue.init_journal(current_user,
I18n.t('redmine_chat_telegram.journal.chat_was_created',
telegram_chat_url: telegram_chat_url))
@issue.save

@project = @issue.project
Expand All @@ -50,7 +52,7 @@ def destroy
@project = @issue.project

@issue.telegram_group.destroy
@issue.init_journal(user, 'Чат Telegram закрыт')
@issue.init_journal(user, I18n.t('redmine_chat_telegram.journal.chat_was_closed'))

if @issue.save
TelegramGroupCloseWorker.perform_async(@issue.id, User.current.id)
Expand Down
8 changes: 7 additions & 1 deletion app/views/telegram_messages/_message.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
<span class="telegram-message-author <%= "user-color-#{color_number_for_user(message.user_id)}" %>">
<%= message.author_name %>
</span>
<span><%= message.message %></div>
<span>
<% if message.message == 'chat_was_created' %>
<%= t 'redmine_chat_telegram.archive.chat_was_created' %>
<% else %>
<%= message.message %>
<% end %>
</span>
</div>
<% else %>
<div class="telegram-message" id="telegram_message_<%= message.id %>" data-sent-at=<%= message.sent_at.to_i %>>
Expand Down
3 changes: 2 additions & 1 deletion app/workers/telegram_group_close_notification_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class TelegramGroupCloseNotificationWorker
'telegram-group-close-notification.log'))

def perform(issue_id)
I18n.locale = Setting['default_language']

issue = Issue.find issue_id
TELEGRAM_GROUP_CLOSE_NOTIFICATION_LOG.debug issue.inspect
Expand All @@ -23,7 +24,7 @@ def perform(issue_id)

# send notification to chat
time_in_words = distance_of_time_in_words(Time.now, telegram_group.need_to_close_at)
close_message_text = "Задача по этому чату закрыта. Чат будет автоматически расформирован через #{time_in_words}."
close_message_text = I18n.t('redmine_chat_telegram.messages.close_notification', time_in_words: time_in_words)
cmd = "#{cli_base} \"msg #{chat_name} #{close_message_text}\""
msg = %x( #{cmd} )

Expand Down
21 changes: 7 additions & 14 deletions app/workers/telegram_group_close_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ class TelegramGroupCloseWorker
TELEGRAM_GROUP_CLOSE_LOG = Logger.new(Rails.root.join('log/chat_telegram', 'telegram-group-close.log'))

def perform(issue_id, user_id = nil)
I18n.locale = Setting['default_language']

user = user_id.present? ? User.find(user_id) : User.anonymous

Expand All @@ -26,13 +27,13 @@ def perform(issue_id, user_id = nil)
TELEGRAM_GROUP_CLOSE_LOG.debug %x( #{cmd} )


unless user.anonymous?

# send notification to chat
close_message_text = 'чат закрыт из задачи'
cmd = "#{cli_base} \"msg #{chat_name} #{close_message_text}\""
msg = %x( #{cmd} )
end
close_message_text = user.anonymous? ?
I18n.t('redmine_chat_telegram.messages.closed_automaticaly') :
I18n.t('redmine_chat_telegram.messages.closed_from_issue')

cmd = "#{cli_base} \"msg #{chat_name} #{close_message_text}\""
msg = %x( #{cmd} )

# remove chat users

Expand All @@ -46,14 +47,6 @@ def perform(issue_id, user_id = nil)
TELEGRAM_GROUP_CLOSE_LOG.debug %x( #{cmd} )
end

# post message to archive

message_text = 'Chat closed'
TelegramMessage.create issue_id: issue.id,
sent_at: Time.now, message: message_text,
from_first_name: user.firstname,
from_last_name: user.lastname

telegram_group.destroy
rescue ActiveRecord::RecordNotFound => e
# ignore
Expand Down
31 changes: 31 additions & 0 deletions app/workers/telegram_group_daily_report_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class TelegramGroupDailyReportWorker
include Sidekiq::Worker
include Redmine::I18n

TELEGRAM_GROUP_DAILY_REPORT_LOG = Logger.new(Rails.root.join('log/chat_telegram', 'telegram-group-daily-report.log'))

def perform
if Setting.plugin_redmine_chat_telegram['daily_report']
yesterday = 12.hours.ago
time_from = yesterday.beginning_of_day
time_to = yesterday.end_of_day

Issue.joins(:telegram_messages).where('telegram_messages.sent_at >= ? and telegram_messages.sent_at <= ?',
time_from, time_to).find_each do |issue|
telegram_messages = issue.telegram_messages.
where('sent_at >= ? and sent_at <= ?', time_from, time_to).
where(is_system: false, bot_message: false)

# TODO: Localize it
date_string = format_date(yesterday)
user_names = telegram_messages.map(&:author_name).uniq
joined_user_names = user_names.join(', ')
journal_text = "За #{date_string} в чате переписывались #{joined_user_names}, всего #{telegram_messages.size} реплик. Всего в чате было #{user_names.count} человек."
issue.init_journal(User.current, "_Из чата Telegram:_ \n\n#{journal_text}")
issue.save
end
end
rescue ActiveRecord::RecordNotFound => e
# ignore
end
end
12 changes: 10 additions & 2 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ en:
permission_close_telegram_chat: Close Telegram Chat
permission_view_telegram_chat_link: View Telegram Chat Link
permission_view_telegram_chat_archive: View Chat Archive

redmine_chat_telegram:
tab_title: Chat Telegram
settings:
daily_report: Post a comment with chat summary once a day

messages:
hello: "Hello, everybody! This is a chat for issue: %{issue_url}"
closed_from_issue: chat was closed from issue
closed_automaticaly: chat was closed automatically
close_notification: "The issue of this chat is closed. Chat will automatically disbanded after %{time_in_words}."
archive:
chat_was_created: "Chat was created"
journal:
chat_was_created: "Chat was created. Join it here: %{telegram_chat_url}"
chat_was_closed: Telegram Group was closed
10 changes: 10 additions & 0 deletions config/locales/ru.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ ru:
tab_title: Chat Telegram
settings:
daily_report: Публиковать комментарий со сводкой по чату раз в сутки
messages:
hello: "Всем привет! Это чат для задачи: %{issue_url}"
closed_from_issue: чат закрыт из задачи
closed_automaticaly: чат закрыт автоматически
close_notification: "Задача по этому чату закрыта. Чат будет автоматически расформирован через %{time_in_words}."
archive:
chat_was_created: Чат создан
journal:
chat_was_created: "По ссылке %{telegram_chat_url} создан чат."
chat_was_closed: Чат Telegram закрыт
5 changes: 5 additions & 0 deletions db/migrate/008_add_bot_message_to_telegram_messages.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddBotMessageToTelegramMessages < ActiveRecord::Migration
def change
add_column :telegram_messages, :bot_message, :boolean, default: false, null: false
end
end
116 changes: 66 additions & 50 deletions lib/tasks/chat_telegram.rake
Original file line number Diff line number Diff line change
Expand Up @@ -2,62 +2,68 @@ def chat_user_full_name(telegram_user)
[telegram_user.first_name, telegram_user.last_name].compact.join
end

namespace :chat_telegram do
# bundle exec rake chat_telegram:bot PID_DIR='/tmp'
desc "Runs telegram bot process (options: PID_DIR='/pid/dir')"
task :bot => :environment do
LOG = Rails.env.production? ? Logger.new(Rails.root.join('log/chat_telegram', 'bot.log')) : Logger.new(STDOUT)
def chat_telegram_bot_init
Process.daemon(true, true) if Rails.env.production?

if ENV['PID_DIR']
pid_dir = ENV['PID_DIR']
PidFile.new(piddir: pid_dir, pidfile: 'telegram-chat-bot.pid')
else
PidFile.new(pidfile: 'telegram-chat-bot.pid')
end

Process.daemon(true, true) if Rails.env.production?
at_exit { LOG.error 'aborted by some reasons' }

if ENV['PID_DIR']
pid_dir = ENV['PID_DIR']
PidFile.new(piddir: pid_dir, pidfile: 'telegram-chat-bot.pid')
else
PidFile.new(pidfile: 'telegram-chat-bot.pid')
end
Signal.trap('TERM') do
at_exit { LOG.error 'Aborted with TERM signal' }
abort 'Aborted with TERM signal'
end
Signal.trap('QUIT') do
at_exit { LOG.error 'Aborted with QUIT signal' }
abort 'Aborted with QUIT signal'
end
Signal.trap('HUP') do
at_exit { LOG.error 'Aborted with HUP signal' }
abort 'Aborted with HUP signal'
end

at_exit { LOG.error 'aborted by some reasons' }
LOG.info 'Start daemon...'

Signal.trap('TERM') do
at_exit { LOG.error 'Aborted with TERM signal' }
abort 'Aborted with TERM signal'
end
Signal.trap('QUIT') do
at_exit { LOG.error 'Aborted with QUIT signal' }
abort 'Aborted with QUIT signal'
end
Signal.trap('HUP') do
at_exit { LOG.error 'Aborted with HUP signal' }
abort 'Aborted with HUP signal'
end
token = Setting.plugin_redmine_chat_telegram['bot_token']

LOG.info 'Start daemon...'
unless token.present?
LOG.error 'Telegram Bot Token not found. Please set it in the plugin config web-interface.'
exit
end

token = Setting.plugin_redmine_chat_telegram['bot_token']
LOG.info 'Telegram Bot: Connecting to telegram...'
bot = Telegrammer::Bot.new(token)
bot_name = bot.me.username

unless token.present?
LOG.error 'Telegram Bot Token not found. Please set it in the plugin config web-interface.'
exit
end
until bot_name.present?

LOG.error 'Telegram Bot Token is invalid or Telegram API is in downtime. I will try again after minute'
sleep 60

LOG.info 'Telegram Bot: Connecting to telegram...'
bot = Telegrammer::Bot.new(token)
bot_name = bot.me.username

until bot_name.present?

LOG.error 'Telegram Bot Token is invalid or Telegram API is in downtime. I will try again after minute'
sleep 60
end

LOG.info 'Telegram Bot: Connecting to telegram...'
bot = Telegrammer::Bot.new(token)
bot_name = bot.me.username
LOG.info "#{bot_name}: connected"
LOG.info "#{bot_name}: waiting for new messages in group chats..."
bot
end

end
namespace :chat_telegram do
# bundle exec rake chat_telegram:bot PID_DIR='/tmp'
desc "Runs telegram bot process (options: PID_DIR='/pid/dir')"
task :bot => :environment do
LOG = Rails.env.production? ? Logger.new(Rails.root.join('log/chat_telegram', 'bot.log')) : Logger.new(STDOUT)
I18n.locale = Setting['default_language']

LOG.info "#{bot_name}: connected"
LOG.info "#{bot_name}: waiting for new messages in group chats..."
bot = chat_telegram_bot_init

bot.get_updates(fail_silently: false) do |message|
begin
Expand All @@ -77,25 +83,27 @@ namespace :chat_telegram do
next
end


if message.group_chat_created

issue_url = RedmineChatTelegram.issue_url(issue.id)
bot.send_message(chat_id: telegram_chat_id,
text: "Hello, everybody! This is a chat for issue: #{issue_url}",
text: I18n.t('redmine_chat_telegram.messages.hello', issue_url: issue_url),
disable_web_page_preview: true)

message_text = 'Chat created'
# Localized in archive
message_text = 'chat_was_created'
telegram_message = TelegramMessage.create issue_id: issue.id,
telegram_id: telegram_id,
sent_at: sent_at, message: message_text,
from_id: from_id, from_first_name: from_first_name,
from_last_name: from_last_name, from_username: from_username,
is_system: true
is_system: true, bot_message: true
else

if message.new_chat_participant.present?
new_chat_participant = message.new_chat_participant

# TODO: Localize it
message_text = if message.from.id == new_chat_participant.id
'joined to the group'
else
Expand All @@ -106,9 +114,10 @@ namespace :chat_telegram do
sent_at: sent_at, message: message_text,
from_id: from_id, from_first_name: from_first_name,
from_last_name: from_last_name, from_username: from_username,
is_system: true
is_system: true, bot_message: true
elsif message.left_chat_participant.present?
left_chat_participant = message.left_chat_participant
# TODO: Localize it
message_text = if message.from.id == left_chat_participant.id
'left the group'
else
Expand All @@ -119,33 +128,40 @@ namespace :chat_telegram do
sent_at: sent_at, message: message_text,
from_id: from_id, from_first_name: from_first_name,
from_last_name: from_last_name, from_username: from_username,
is_system: true
is_system: true, bot_message: true

elsif message.text.present? and message.chat.type == 'group'
issue_url = RedmineChatTelegram.issue_url(issue.id)

message_text = message.text
issue_url_text = "#{issue.subject}\n#{issue_url}"

if message_text.include?('/task') or message_text.include?('/link') or message_text.include?('/url')
bot.send_message(chat_id: telegram_chat_id,
text: "#{issue.subject}\n#{issue_url}",
text: issue_url_text,
disable_web_page_preview: true)

next unless message_text.gsub('/task', '').gsub('/link', '').gsub('/url', '').strip.present?

end

bot_message_regexp = Regexp.new(
I18n.t('redmine_chat_telegram.messages').values.map {|m| m.gsub(/%{.+}/, '.+')}.join('|'))

bot_message = (message_text == issue_url_text) or (message_text =~ bot_message_regexp ).present?

telegram_message = TelegramMessage.new issue_id: issue.id,
telegram_id: telegram_id,
sent_at: sent_at, message: message_text,
from_id: from_id, from_first_name: from_first_name,
from_last_name: from_last_name, from_username: from_username
from_last_name: from_last_name, from_username: from_username,
bot_message: bot_message

if message_text.include?('/log')
telegram_message.message = message_text.gsub('/log', '')

journal_text = telegram_message.as_text(with_time: false)

# TODO: Localize it
issue.init_journal(User.current, "_Из Telegram:_ \n\n#{journal_text}")
issue.save
end
Expand Down

0 comments on commit 29654d2

Please sign in to comment.