Skip to content

Commit

Permalink
Merge pull request #125 from southbridgeio/develop
Browse files Browse the repository at this point in the history
Release 1.5.0
  • Loading branch information
vladislav-yashin authored Jan 10, 2020
2 parents deb03e6 + 7ea6f75 commit 5c60285
Show file tree
Hide file tree
Showing 33 changed files with 480 additions and 112 deletions.
12 changes: 9 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
language: ruby
rvm:
- 2.3.8
- 2.6.0
- 2.4.9
- 2.6.5
- 2.7.0

#branches:
# only:
Expand All @@ -13,7 +14,12 @@ addons:

env:
- REDMINE_VER=3.4-stable
- REDMINE_VER=4.0-stable
- REDMINE_VER=4.1-stable

matrix:
exclude:
- env: REDMINE_VER=3.4-stable
rvm: 2.7.0

install: "echo skip bundle install"

Expand Down
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
# 1.5.0

* Add plugins deprecation warning
* Fix project settings page performance
* Implement message previews
* Don’t send updates to updated_by
* Don’t send live updates to inactive users
* Handle telegram group upgrade errors
* Set telegram rate limiting
* Use html formatting in telegram
* Fix idempotency

# 1.4.0

* Adapt for Redmine 4
Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ gem 'sidekiq-rate-limiter', git: 'https://github.com/centosadmin/sidekiq-rate-li

group :test do
gem 'minitest-reporters', '<= 1.3.0'
gem 'mocha'
gem 'mocha', '>= 1.4.0'
end
2 changes: 1 addition & 1 deletion README-RU.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

## Требования

* **Ruby 2.3+**
* **Ruby 2.4+**
* **Redmine 3.1+**
* Настроенный [redmine_telegram_common](https://github.com/southbridgeio/redmine_telegram_common)
* У Вас должен быть бот в Telegram
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Please help us make this plugin better telling us of any [issues](https://github

## Requirements

* **Ruby 2.3+**
* **Ruby 2.4+**
* **Redmine 3.1+**
* Configured [redmine_bots](https://github.com/southbridgeio/redmine_bots)
* Install [Redis](https://redis.io) 2.8 or higher. Run Redis and add it to autorun.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
<% @priorities ||= IssuePriority.order(:position) %>
<% @statuses ||= IssueStatus.order(:position) %>

<p class="description">
<%= t("intouch.project.settings.issue_update.#{kind}.description") %>
</p>
Expand Down Expand Up @@ -26,7 +29,7 @@
<thead>
<tr>
<th><%= t('field_status') %> \ <%= t('field_priority') %></th>
<% IssuePriority.order(:position).each do |priority| %>
<% @priorities.each do |priority| %>
<th>
<%= check_box_tag "#{kind}_priority_#{priority.id}", '1', false, class: 'prioritySelectAll',
data: { kind: kind, priority_id: priority.id }
Expand All @@ -37,15 +40,15 @@
</tr>
</thead>
<tbody>
<% IssueStatus.order(:position).each do |status| %>
<% @statuses.each do |status| %>
<tr>
<th>
<%= check_box_tag "#{kind}_status_#{status.id}", '1', false, class: 'statusSelectAll',
data: { kind: kind, status_id: status.id }
%>
<%= label_tag "#{kind}_status_#{status.id}", status.name %>
</th>
<% IssuePriority.order(:position).each do |priority| %>
<% @priorities.each do |priority| %>
<td>
<% Intouch.active_protocols.each do |protocol, _| %>
<%= check_box_tag "intouch_settings[#{protocol}_settings][#{kind}][#{status.id}][]",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
<%= button_tag t('intouch.project.settings.common.copy'), class: 'copySettingsFromOtherTab' %>
</div>

<% priorities = IssuePriority.order(:position) %>
<% statuses = IssueStatus.order(:position) %>

<% TelegramGroupChat.find_each do |telegram_group| %>
<% kind = dom_id(telegram_group) %>
<h4><%= telegram_group.title %></h4>
Expand All @@ -30,7 +33,7 @@
<thead>
<tr>
<th><%= t('field_status') %> \ <%= t('field_priority') %></th>
<% IssuePriority.order(:position).each do |priority| %>
<% priorities.each do |priority| %>
<th>
<%= check_box_tag "#{kind}_priority_#{priority.id}", '1', false, class: 'prioritySelectAll',
data: { kind: kind, priority_id: priority.id }
Expand All @@ -41,15 +44,15 @@
</tr>
</thead>
<tbody>
<% IssueStatus.order(:position).each do |status| %>
<% statuses.each do |status| %>
<tr>
<th>
<%= check_box_tag "#{kind}_status_#{status.id}", '1', false, class: 'statusSelectAll',
data: {kind: kind, status_id: status.id}
%>
<%= label_tag "#{kind}_status_#{status.id}", status.name %>
</th>
<% IssuePriority.order(:position).each do |priority| %>
<% priorities.each do |priority| %>

<td>
<%= check_box_tag "intouch_settings[telegram_settings][groups][#{telegram_group.id}][#{status.id}][]", priority.id,
Expand Down
10 changes: 10 additions & 0 deletions app/views/settings/_common.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,13 @@
</ul>
</div>
<% end %>

<div class="box tabular settings">
<h4><%= l 'label_preview' %></h4>
<ul class="inline-checkboxes">
<li>
<%= label_tag 'settings[telegram_preview]', "#{l('label_preview')} (Telegram)" %>
<%= check_box_tag 'settings[telegram_preview]', '1', @settings['telegram_preview'] %>
</li>
</ul>
</div>
2 changes: 2 additions & 0 deletions app/views/settings/_intouch.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
{name: 'sidekiq_cron_jobs', partial: 'settings/sidekiq_cron_jobs', label: 'intouch.label.sidekiq_cron_jobs'}
] %>

<%= render partial: 'settings/redmine_bots/deprecation_warning' %>

<% unless Redmine::Plugin.installed?('redmine_sidekiq') %>
<h1 style="text-align: center">
!!! <a href="https://github.com/ogom/redmine_sidekiq" target="_blank">redmine_sidekiq</a>
Expand Down
12 changes: 3 additions & 9 deletions app/workers/telegram_group_live_sender_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,13 @@ def perform(issue_id, journal_id)

return unless group_for_send_ids.present?

message = issue.as_markdown
message = issue.as_html

logger.debug "message: #{message}"

TelegramGroupChat.where(id: group_for_send_ids).uniq.each do |group|
logger.debug "group: #{group.inspect}"
next unless group.tid.present?

job = TelegramMessageSender.perform_async(-group.tid, message)

logger.debug job.inspect
group_for_send_ids.each do |group_id|
TelegramGroupMessageSender.perform_async(group_id, message, issue_id, journal_id)
end
logger.debug "DONE for issue_id #{issue_id}"
rescue ActiveRecord::RecordNotFound => e
# ignore
end
Expand Down
23 changes: 23 additions & 0 deletions app/workers/telegram_group_message_sender.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class TelegramGroupMessageSender
include Sidekiq::Worker

sidekiq_options queue: :telegram,
rate: {
name: 'telegram_group_rate_limit',
limit: 20,
period: 60
}

def perform(chat_id, message, issue_id, journal_id)
chat = TelegramGroupChat.find_by(id: chat_id) || return

Intouch.handle_group_upgrade(chat) do |group|
next unless group.tid.present?

RedmineBots::Telegram::Bot::MessageSender.call(message: message,
chat_id: -group.tid,
parse_mode: 'HTML',
**Intouch::Preview::KeyboardMarkup.build_hash(issue_id, journal_id))
end
end
end
29 changes: 19 additions & 10 deletions app/workers/telegram_group_sender_worker.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
class TelegramGroupSenderWorker
include Sidekiq::Worker

def perform(issue_id, group_ids, state)
return unless group_ids.present?
sidekiq_options queue: :telegram,
rate: {
name: 'telegram_rate_limit',
limit: 1,
period: 4
}

def perform(issue_id, group_id, state)
return unless group_id.present?

@issue = Issue.find_by(id: issue_id)
@group_ids = group_ids
@group_id = group_id
@state = state

return unless @issue.present?
return unless notificable?
return unless groups.present?
return unless group.present?

log

groups.each { |group| send_message(group) }
Intouch.handle_group_upgrade(group) { |chat| send_message(chat) }
end

private

attr_reader :issue, :state, :group_ids
attr_reader :issue, :state, :group_id

def notificable?
Intouch::Regular::Checker::Base.new(
Expand All @@ -29,13 +36,15 @@ def notificable?
).required?
end

def groups
@groups ||= ::TelegramGroupChat.where(id: group_ids).uniq
def group
@group ||= ::TelegramGroupChat.find_by(id: group_id)
end

def send_message(group)
return unless group.tid.present?
TelegramMessageSender.perform_async(-group.tid, message)
RedmineBots::Telegram::Bot::MessageSender.call(message: message,
chat_id: -group.tid,
parse_mode: 'HTML')
end

def message
Expand All @@ -51,7 +60,7 @@ def log
logger.info "Notification for state: #{state}"
logger.info message
logger.debug issue.inspect
logger.debug group_ids.inspect
logger.debug group_id.inspect
logger.info '========================================='
end

Expand Down
32 changes: 19 additions & 13 deletions app/workers/telegram_live_sender_worker.rb
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
class TelegramLiveSenderWorker
include Sidekiq::Worker

def perform(issue_id, journal_id, recipient_ids)
sidekiq_options queue: :telegram,
rate: {
name: 'telegram_rate_limit',
limit: 1,
period: 1
}

def perform(issue_id, journal_id, user_id)
logger.debug "START for issue_id #{issue_id}"

Intouch.set_locale

issue = Intouch::IssueDecorator.new(Issue.find(issue_id), journal_id, protocol: 'telegram')
logger.debug issue.inspect

User.where(id: recipient_ids).each do |user|
message = issue.as_markdown(user_id: user.id)

logger.debug "user: #{user.inspect}"
user = User.find(user_id)
message = issue.as_html(user_id: user.id)

telegram_account = TelegramAccount.find_by(user_id: user.id)
logger.debug "telegram_account: #{telegram_account.inspect}"
next unless telegram_account.present?
logger.debug "user: #{user.inspect}"

logger.debug message
telegram_account = TelegramAccount.find_by!(user_id: user.id)
logger.debug "telegram_account: #{telegram_account.inspect}"

job = TelegramMessageSender.perform_async(telegram_account.telegram_id, message)
logger.debug message

logger.debug job.inspect
end
RedmineBots::Telegram::Bot::MessageSender.call(message: message,
chat_id: telegram_account.telegram_id,
parse_mode: 'HTML',
**Intouch::Preview::KeyboardMarkup.build_hash(issue_id, journal_id))

logger.debug "FINISH for issue_id #{issue_id}"
rescue ActiveRecord::RecordNotFound => e
rescue ActiveRecord::RecordNotFound
# ignore
end

Expand Down
43 changes: 4 additions & 39 deletions app/workers/telegram_message_sender.rb
Original file line number Diff line number Diff line change
@@ -1,49 +1,14 @@
class TelegramMessageSender
include Sidekiq::Worker

sidekiq_options queue: :telegram,
rate: {
name: 'telegram_rate_limit',
limit: 15,
limit: 1,
period: 1
}

TELEGRAM_MESSAGE_SENDER_LOG = Logger.new(Rails.root.join('log/intouch', 'telegram-message-sender.log'))
TELEGRAM_MESSAGE_SENDER_ERRORS_LOG = Logger.new(Rails.root.join('log/intouch', 'telegram-message-sender-errors.log'))

def perform(telegram_account_id, message)
token = Intouch.bot_token
bot = Telegram::Bot::Client.new(token)

begin
bot.api.send_message(chat_id: telegram_account_id,
text: message,
disable_web_page_preview: true,
parse_mode: 'Markdown')
TELEGRAM_MESSAGE_SENDER_LOG.info "telegram_account_id: #{telegram_account_id}\tmessage: #{message}"

rescue => e

TELEGRAM_MESSAGE_SENDER_ERRORS_LOG.info "MESSAGE: #{message}"

telegram_account = (telegram_account_id > 0) ?
TelegramAccount.find_by(telegram_id: telegram_account_id) :
TelegramGroupChat.find_by(tid: telegram_account_id.abs)

if e.message.include? 'Bot was kicked'
TELEGRAM_MESSAGE_SENDER_ERRORS_LOG.info "Bot was kicked from chat."

elsif e.message.include?('429') || e.message.include?('retry later')

TELEGRAM_MESSAGE_SENDER_ERRORS_LOG.error "429 retry later error. retry to send after 5 seconds\ntelegram_account_id: #{telegram_account_id}\tmessage: #{message}"
TelegramMessageSender.perform_in(5.seconds, telegram_account_id, message)

else

TELEGRAM_MESSAGE_SENDER_ERRORS_LOG.error "#{e.class}: #{e.message}"
TELEGRAM_MESSAGE_SENDER_ERRORS_LOG.debug "#{telegram_account.inspect}"

end

end
def perform(telegram_account_id, message, params = {})
RedmineBots::Telegram::Bot::MessageSender.call(chat_id: telegram_account_id, message: message, **params.transform_keys(&:to_sym))
end
end
Loading

0 comments on commit 5c60285

Please sign in to comment.