tramway-bots 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/app/assets/config/tramway_bots_manifest.js +1 -0
- data/app/assets/stylesheets/tramway/bots/application.css +15 -0
- data/app/controllers/tramway/bots/application_controller.rb +6 -0
- data/app/helpers/tramway/bots/application_helper.rb +6 -0
- data/app/jobs/tramway/bots/application_job.rb +6 -0
- data/app/mailers/tramway/bots/application_mailer.rb +8 -0
- data/app/models/tramway/bots/application_record.rb +7 -0
- data/app/models/tramway/bots/bot.rb +50 -0
- data/app/models/tramway/bots/telegram/channel.rb +4 -0
- data/app/models/tramway/bots/telegram/chat.rb +12 -0
- data/app/models/tramway/bots/telegram/message.rb +15 -0
- data/app/models/tramway/bots/telegram/user.rb +37 -0
- data/app/models/tramway/bots/telegram/users/state.rb +6 -0
- data/app/models/tramway/bots/telegram/users.rb +7 -0
- data/app/views/layouts/tramway/bots/application.html.erb +15 -0
- data/config/routes.rb +2 -0
- data/lib/tramway/bots/engine.rb +7 -0
- data/lib/tramway/bots/generates/install_generator.rb +45 -0
- data/lib/tramway/bots/generates/templates/create_tramway_bots_bots.rb +17 -0
- data/lib/tramway/bots/generates/templates/create_tramway_bots_telegram_channels.rb +15 -0
- data/lib/tramway/bots/generates/templates/create_tramway_bots_telegram_chats.rb +17 -0
- data/lib/tramway/bots/generates/templates/create_tramway_bots_telegram_messages.rb +19 -0
- data/lib/tramway/bots/generates/templates/create_tramway_bots_telegram_users.rb +17 -0
- data/lib/tramway/bots/generates/templates/create_tramway_bots_telegram_users_states.rb +15 -0
- data/lib/tramway/bots/telegram/custom/message.rb +42 -0
- data/lib/tramway/bots/telegram/custom/notify/file.rb +22 -0
- data/lib/tramway/bots/telegram/custom/notify/text.rb +29 -0
- data/lib/tramway/bots/telegram/custom/notify.rb +12 -0
- data/lib/tramway/bots/telegram/custom/scenario.rb +17 -0
- data/lib/tramway/bots/telegram/custom.rb +6 -0
- data/lib/tramway/bots/telegram/info.rb +50 -0
- data/lib/tramway/bots/telegram/message.rb +42 -0
- data/lib/tramway/bots/telegram/messages_manager.rb +100 -0
- data/lib/tramway/bots/telegram.rb +6 -0
- data/lib/tramway/bots/version.rb +5 -0
- data/lib/tramway/bots.rb +10 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d462c8140b6b03f7886b70a4cd4c6149701bfc4de48ff6216d24d654a655a15c
|
4
|
+
data.tar.gz: fc46a58321fba4a96af57e7b5e68e9ac9204699f07da2ce7cdef700c3882c682
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 58c561c068af69ed6b9aa05953a89b5f5388ba49e8180e4ad6b4c92c0a0b5872958b14348f9b47e79c10e9da25435e58e6f874a19106df8275e07c58bd178562
|
7
|
+
data.tar.gz: 8dff845aef42cd104405ae3b1e3b7ffed207bab999fba665ca39c6f5d43098b8a268e4e6763b84bc7e2f7be48475232c4175215abb75fd4406da6404e8c83ed1
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 Pavel Kalashnikov
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# Tramway::Bots
|
2
|
+
Short description and motivation.
|
3
|
+
|
4
|
+
## Usage
|
5
|
+
How to use my plugin.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
gem "tramway-bots"
|
12
|
+
```
|
13
|
+
|
14
|
+
And then execute:
|
15
|
+
```bash
|
16
|
+
$ bundle
|
17
|
+
```
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
```bash
|
21
|
+
$ gem install tramway-bots
|
22
|
+
```
|
23
|
+
|
24
|
+
## Contributing
|
25
|
+
Contribution directions go here.
|
26
|
+
|
27
|
+
## License
|
28
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets/tramway/bots .css
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Tramway::Bots::Bot < ApplicationRecord
|
4
|
+
has_many :scenario_steps, -> { order(:name) }, class_name: 'BotTelegram::Scenario::Step'
|
5
|
+
has_many :progress_records, through: :scenario_steps, class_name: 'BotTelegram::Scenario::ProgressRecord'
|
6
|
+
has_many :attenders, through: :progress_records, class_name: 'BotTelegram::User', source: :user
|
7
|
+
has_many :messages, class_name: 'BotTelegram::Message'
|
8
|
+
has_many :users, through: :messages, class_name: 'BotTelegram::User'
|
9
|
+
|
10
|
+
TEAMS = %i[rsm night purple_magic benchkiller].freeze
|
11
|
+
|
12
|
+
enumerize :team, in: TEAMS
|
13
|
+
|
14
|
+
TEAMS.each do |team|
|
15
|
+
scope "#{team}_scope".to_sym, lambda { |_user_id|
|
16
|
+
where team: team
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
store_accessor :options, :custom
|
21
|
+
store_accessor :options, :scenario
|
22
|
+
|
23
|
+
def start_step
|
24
|
+
# scenario_steps.find_by name: :start did not work for some reason. Think it's about step word in Rails
|
25
|
+
scenario_steps.select { |s| s.name == 'start' }.first
|
26
|
+
end
|
27
|
+
|
28
|
+
def finish_step
|
29
|
+
return unless team.night?
|
30
|
+
|
31
|
+
scenario_steps.finish_step
|
32
|
+
end
|
33
|
+
|
34
|
+
def finished_users
|
35
|
+
return [] unless finish_step.present?
|
36
|
+
|
37
|
+
progress_records.where(bot_telegram_scenario_step_id: finish_step.id).uniq(&:bot_telegram_user_id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def new_users_between(begin_date, end_date)
|
41
|
+
users.uniq.map do |user|
|
42
|
+
first_message_created_at = user.messages.order(created_at: :asc).first.created_at
|
43
|
+
user if first_message_created_at.between?(begin_date, end_date)
|
44
|
+
end.compact
|
45
|
+
end
|
46
|
+
|
47
|
+
def uniq_users_between(begin_date, end_date)
|
48
|
+
messages.where('created_at >= ? AND created_at <= ?', begin_date, end_date).map(&:user).uniq
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Tramway::Bots::Telegram::Chat < ApplicationRecord
|
4
|
+
self.table_name = 'tramway_bots_telegram_chats'
|
5
|
+
|
6
|
+
has_many :messages, class_name: 'Tramway::Bots::Telegram::Message'
|
7
|
+
belongs_to :bot, class_name: 'Bot'
|
8
|
+
|
9
|
+
def private?
|
10
|
+
chat_type == 'private'
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Tramway::Bots::Telegram::Message < ApplicationRecord
|
4
|
+
self.table_name = 'tramway_bots_telegram_messages'
|
5
|
+
|
6
|
+
belongs_to :user, class_name: 'Tramway::Bots::Telegram::User', optional: true
|
7
|
+
belongs_to :bot, class_name: 'Tramway::Bots::Bot', optional: true
|
8
|
+
belongs_to :chat, class_name: 'Tramway::Bots::Telegram::Chat', optional: true
|
9
|
+
|
10
|
+
enumerize :message_type, in: %i[regular callback], default: :regular
|
11
|
+
|
12
|
+
validates :telegram_message_id, uniqueness: { scope: [ :bot_id, :chat_id ] }, allow_nil: true
|
13
|
+
|
14
|
+
search_by :text, user: %i[username first_name]
|
15
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Tramway::Bots::Telegram::User < ApplicationRecord
|
4
|
+
self.table_name = 'tramway_bots_telegram_users'
|
5
|
+
|
6
|
+
has_many :messages, class_name: 'Tramway::Bots::Telegram::Message'
|
7
|
+
has_many :bots, class_name: 'Tramway::Bots::Bot', through: :steps
|
8
|
+
has_many :states, class_name: 'Tramway::Bots::Telegram::Users::State'
|
9
|
+
|
10
|
+
validates :telegram_id, uniqueness: true
|
11
|
+
validates :username, uniqueness: true, allow_blank: true, allow_nil: true
|
12
|
+
|
13
|
+
search_by :first_name, :username, :last_name
|
14
|
+
|
15
|
+
scope :partner_scope, ->(_user_id) { all }
|
16
|
+
%i[rsm night purple_magic].each do |team|
|
17
|
+
scope "#{team}_scope".to_sym, lambda { |_user_id|
|
18
|
+
step_ids = Bot.where(team: team).map(&:steps).flatten.map(&:id)
|
19
|
+
records = BotTelegram::Scenario::ProgressRecord.where(bot_telegram_scenario_step_id: step_ids)
|
20
|
+
BotTelegram::User.where id: records.map(&:bot_telegram_user_id)
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def current_state(bot)
|
25
|
+
states.where(bot_id: bot.id).last&.current_state
|
26
|
+
end
|
27
|
+
|
28
|
+
# rubocop:disable Naming/AccessorMethodName
|
29
|
+
def set_finished_state_for(bot:)
|
30
|
+
states.create! bot_id: bot.id, current_state: :finished
|
31
|
+
end
|
32
|
+
# rubocop:enable Naming/AccessorMethodName
|
33
|
+
|
34
|
+
def finished_state_for?(bot:)
|
35
|
+
states.empty? || states.where(bot_id: bot.id).last&.current_state == 'finished'
|
36
|
+
end
|
37
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails/generators'
|
4
|
+
require 'tramway/core/generators/install_generator'
|
5
|
+
|
6
|
+
module Tramway::Bots::Generators
|
7
|
+
class InstallGenerator < ::Tramway::Core::Generators::InstallGenerator
|
8
|
+
include Rails::Generators::Migration
|
9
|
+
source_root File.expand_path('templates', __dir__)
|
10
|
+
|
11
|
+
def self.next_migration_number(path)
|
12
|
+
next_migration_number = current_migration_number(path) + 1
|
13
|
+
ActiveRecord::Migration.next_migration_number next_migration_number
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_migrations
|
17
|
+
migrations = %i[
|
18
|
+
create_tramway_bots_bots
|
19
|
+
create_tramway_bots_telegram_channels
|
20
|
+
create_tramway_bots_telegram_chats
|
21
|
+
create_tramway_bots_telegram_messages
|
22
|
+
create_tramway_bots_telegram_users
|
23
|
+
create_tramway_bots_telegram_users_states
|
24
|
+
]
|
25
|
+
|
26
|
+
migrations.each do |migration|
|
27
|
+
migration_template "#{migration}.rb", "db/migrate/#{migration}.rb"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def copy_factories
|
32
|
+
factories = [
|
33
|
+
'tramway/bots/telegram/messages',
|
34
|
+
'tramway/bots/telegram/chats',
|
35
|
+
'tramway/bots/telegram/users',
|
36
|
+
'tramway/bots/bots'
|
37
|
+
]
|
38
|
+
|
39
|
+
factories.each do |factory|
|
40
|
+
# TODO write generator for minitest
|
41
|
+
create_file "spec/factories/#{factory}.rb", File.read("#{File.dirname(__dir__)}/../../../spec/factories/#{factory}.rb")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateTramwayBotsBots < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :tramway_bots_bots do |t|
|
6
|
+
t.text :name
|
7
|
+
t.text :state
|
8
|
+
t.text :team
|
9
|
+
t.text :token
|
10
|
+
t.jsonb :options
|
11
|
+
t.text :slug
|
12
|
+
t.datetime :deleted_at
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateTramwayBotsTelegramChannels < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :tramway_bot_engine_telegram_channels do |t|
|
6
|
+
t.integer :bot_id
|
7
|
+
t.text :title
|
8
|
+
t.text :state
|
9
|
+
t.text :telegram_channel_id
|
10
|
+
t.datetime :deleted_at
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateTramwayBotsTelegramChats < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :tramway_bots_telegram_chats do |t|
|
6
|
+
t.text :title
|
7
|
+
t.text :chat_type
|
8
|
+
t.jsonb :options
|
9
|
+
t.text :state
|
10
|
+
t.text :telegram_chat_id
|
11
|
+
t.integer :bot_id
|
12
|
+
t.datetime :deleted_at
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateTramwayBotsTelegramMessages < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :tramway_bots_telegram_messages do |t|
|
6
|
+
t.integer :chat_id
|
7
|
+
t.integer :user_id
|
8
|
+
t.text :text
|
9
|
+
t.jsonb :options
|
10
|
+
t.text :state
|
11
|
+
t.integer :bot_id
|
12
|
+
t.text :message_type, default: "regular"
|
13
|
+
t.datetime :deleted_at
|
14
|
+
t.integer :telegram_message_id
|
15
|
+
|
16
|
+
t.timestamps
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateTramwayBotsTelegramUsers < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :tramway_bots_telegram_users do |t|
|
6
|
+
t.text "first_name"
|
7
|
+
t.text "last_name"
|
8
|
+
t.text "username"
|
9
|
+
t.jsonb "options"
|
10
|
+
t.text "state"
|
11
|
+
t.text "telegram_id"
|
12
|
+
t.datetime "deleted_at"
|
13
|
+
|
14
|
+
t.timestamps
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class CreateTramwayBotsTelegramUsersStates < ActiveRecord::Migration[5.1]
|
4
|
+
def change
|
5
|
+
create_table :tramway_bots_telegram_users_states do |t|
|
6
|
+
t.integer "user_id"
|
7
|
+
t.integer "bot_id"
|
8
|
+
t.text "current_state"
|
9
|
+
t.text "state"
|
10
|
+
t.datetime "deleted_at"
|
11
|
+
|
12
|
+
t.timestamps
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'telegram/bot'
|
4
|
+
|
5
|
+
class Tramway::Bots::Telegram::Custom::Message
|
6
|
+
attr_reader :file
|
7
|
+
|
8
|
+
def initialize(text: nil, file: nil, reply_markup: nil, inline_keyboard: nil)
|
9
|
+
raise 'You set text: argument for message' unless text.present?
|
10
|
+
|
11
|
+
@text = text
|
12
|
+
@file = file
|
13
|
+
@reply_markup = reply_markup
|
14
|
+
@inline_keyboard = inline_keyboard
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_options(button)
|
18
|
+
button_options = { text: button[0] }
|
19
|
+
button_options.merge! callback_data: button[1][:data].to_json if button[1][:data].present?
|
20
|
+
Telegram::Bot::Types::InlineKeyboardButton.new(**button_options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def options
|
24
|
+
arguments = {}
|
25
|
+
arguments.merge!(text: @text) if @text.present?
|
26
|
+
if @reply_markup.present?
|
27
|
+
arguments.merge!(reply_markup: Telegram::Bot::Types::ReplyKeyboardMarkup.new(**@reply_markup))
|
28
|
+
elsif @inline_keyboard.present?
|
29
|
+
keyboard = @inline_keyboard.map do |button|
|
30
|
+
if button[0].is_a? Array
|
31
|
+
button.map do |b|
|
32
|
+
build_options b
|
33
|
+
end
|
34
|
+
else
|
35
|
+
build_options button
|
36
|
+
end
|
37
|
+
end
|
38
|
+
arguments.merge!(reply_markup: Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: keyboard))
|
39
|
+
end
|
40
|
+
arguments
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Bots::Telegram::Custom::Notify::File
|
4
|
+
class << self
|
5
|
+
include Tramway::Bots::Telegram::MessagesManager
|
6
|
+
|
7
|
+
def send_to_user(bot_id, username, file)
|
8
|
+
bot_record = Bot.find bot_id
|
9
|
+
bot = ::Telegram::Bot::Client.new bot_record.token
|
10
|
+
chat = ::Tramway::Bots::Telegram::Chat.where(bot_id: bot_id).find_by "options ->> 'username' = '#{username}'"
|
11
|
+
bot_message = ::Tramway::Bots::Telegram::Leopold::Message.new file
|
12
|
+
send_file bot.api, chat.telegram_chat_id, bot_message
|
13
|
+
end
|
14
|
+
|
15
|
+
def send_to_chat(bot_id, chat_id, file)
|
16
|
+
bot_record = Bot.find bot_id
|
17
|
+
bot = ::Telegram::Bot::Client.new bot_record.token
|
18
|
+
bot_message = ::Tramway::Bots::Telegram::Leopold::Message.new file
|
19
|
+
send_file bot.api, chat_id, bot_message.file
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'telegram/bot'
|
4
|
+
require 'tramway/bots/telegram/messages_manager'
|
5
|
+
|
6
|
+
module Tramway::Bots::Telegram::Custom::Notify::Text
|
7
|
+
class << self
|
8
|
+
include ::Tramway::Bots::Telegram::MessagesManager
|
9
|
+
|
10
|
+
def send_to_user(bot_id, username, message)
|
11
|
+
bot_record = Tramway::Bots::Bot.find bot_id
|
12
|
+
bot = ::Telegram::Bot::Client.new bot_record.token
|
13
|
+
chat = Tramway::Bots::Telegram::Chat.where(bot_id: bot_id).find_by "options ->> 'username' = '#{username}'"
|
14
|
+
message_to_user bot.api, message, chat.telegram_chat_id if chat.present?
|
15
|
+
end
|
16
|
+
|
17
|
+
def send_to_chat(bot_id, chat_id, message, **options)
|
18
|
+
bot_record = Tramway::Bots::Bot.find bot_id
|
19
|
+
bot = ::Telegram::Bot::Client.new bot_record.token
|
20
|
+
message_to_chat bot.api, chat_id, message, **options
|
21
|
+
end
|
22
|
+
|
23
|
+
def send_to_channel(bot_id, channel_id, message)
|
24
|
+
bot_record = Tramway::Bots::Bot.find bot_id
|
25
|
+
bot = ::Telegram::Bot::Client.new bot_record.token
|
26
|
+
message_to_user bot.api, message, channel_id
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Tramway::Bots::Telegram::Custom::Scenario
|
4
|
+
include ::Tramway::Bots::Telegram::MessagesManager
|
5
|
+
include ::Tramway::Bots::Telegram::Info
|
6
|
+
|
7
|
+
attr_reader :bot, :bot_record, :chat, :message_from_telegram, :message, :user
|
8
|
+
|
9
|
+
def initialize(**options)
|
10
|
+
@bot = options[:bot]
|
11
|
+
@message_from_telegram = options[:message]
|
12
|
+
@bot_record = options[:bot_record]
|
13
|
+
@chat = options[:chat]
|
14
|
+
@message = options[:message_object]
|
15
|
+
@user = options[:user]
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Bots::Telegram::Info
|
4
|
+
def user_from(sender)
|
5
|
+
user = Tramway::Bots::Telegram::User.find_by telegram_id: sender.id
|
6
|
+
params = {
|
7
|
+
username: sender.username,
|
8
|
+
first_name: sender.first_name,
|
9
|
+
last_name: sender.last_name,
|
10
|
+
project_id: Project.find_by(title: 'PurpleMagic').id,
|
11
|
+
options: {
|
12
|
+
can_join_groups: sender.can_join_groups,
|
13
|
+
can_read_all_group_messages: sender.can_read_all_group_messages,
|
14
|
+
language_code: sender.language_code,
|
15
|
+
supports_inline_queries: sender.supports_inline_queries,
|
16
|
+
is_bot: sender.is_bot
|
17
|
+
}
|
18
|
+
}
|
19
|
+
if user.present?
|
20
|
+
user.update! params
|
21
|
+
user.reload
|
22
|
+
else
|
23
|
+
Tramway::Bots::Telegram::User.create! telegram_id: sender.id, **params
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def chat_from(message_chat, bot_record)
|
28
|
+
chat = Tramway::Bots::Telegram::Chat.find_or_create_by! telegram_chat_id: message_chat.id, bot_id: bot_record.id
|
29
|
+
chat.update! title: message_chat.title,
|
30
|
+
bot_id: bot_record.id,
|
31
|
+
chat_type: message_chat.type,
|
32
|
+
project_id: Project.find_by(title: 'PurpleMagic').id,
|
33
|
+
options: (%i[
|
34
|
+
all_members_are_administrators can_set_sticker_set description first_name invite_link
|
35
|
+
last_name permissions photo pinned_message slow_mode_delay sticker_set_name
|
36
|
+
username
|
37
|
+
].reduce({}) do |hash, attribute|
|
38
|
+
hash.merge! attribute => message_chat.send(attribute)
|
39
|
+
end)
|
40
|
+
chat.reload
|
41
|
+
end
|
42
|
+
|
43
|
+
def channel_from(channel, bot_record)
|
44
|
+
channel_record = Tramway::Bots::Telegram::Channel.find_or_create_by! telegram_channel_id: channel.id
|
45
|
+
channel_record.update! title: channel.title,
|
46
|
+
bot_id: bot_record.id,
|
47
|
+
project_id: Project.find_by(title: 'PurpleMagic').id
|
48
|
+
channel_record.reload
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'telegram/bot'
|
4
|
+
|
5
|
+
class BotTelegram::Custom::Message
|
6
|
+
attr_reader :file
|
7
|
+
|
8
|
+
def initialize(text: nil, file: nil, reply_markup: nil, inline_keyboard: nil)
|
9
|
+
raise 'You set text: argument for message' unless text.present?
|
10
|
+
|
11
|
+
@text = text
|
12
|
+
@file = file
|
13
|
+
@reply_markup = reply_markup
|
14
|
+
@inline_keyboard = inline_keyboard
|
15
|
+
end
|
16
|
+
|
17
|
+
def build_options(button)
|
18
|
+
button_options = { text: button[0] }
|
19
|
+
button_options.merge! callback_data: button[1][:data].to_json if button[1][:data].present?
|
20
|
+
Telegram::Bot::Types::InlineKeyboardButton.new(**button_options)
|
21
|
+
end
|
22
|
+
|
23
|
+
def options
|
24
|
+
arguments = {}
|
25
|
+
arguments.merge!(text: @text) if @text.present?
|
26
|
+
if @reply_markup.present?
|
27
|
+
arguments.merge!(reply_markup: Telegram::Bot::Types::ReplyKeyboardMarkup.new(**@reply_markup))
|
28
|
+
elsif @inline_keyboard.present?
|
29
|
+
keyboard = @inline_keyboard.map do |button|
|
30
|
+
if button[0].is_a? Array
|
31
|
+
button.map do |b|
|
32
|
+
build_options b
|
33
|
+
end
|
34
|
+
else
|
35
|
+
build_options button
|
36
|
+
end
|
37
|
+
end
|
38
|
+
arguments.merge!(reply_markup: Telegram::Bot::Types::InlineKeyboardMarkup.new(inline_keyboard: keyboard))
|
39
|
+
end
|
40
|
+
arguments
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tramway::Bots::Telegram::MessagesManager
|
4
|
+
def log_message(message, user, chat, bot)
|
5
|
+
file_path = "#{Rails.root}/lib/tasks/bot_telegram/bot_message_attributes.yml"
|
6
|
+
telegram_message_attributes = YAML.load_file(file_path)['telegram_message']['attributes']
|
7
|
+
|
8
|
+
message_object = Tramway::Bots::Telegram::Message.find_or_create_by(
|
9
|
+
telegram_message_id: message.message_id,
|
10
|
+
bot_id: bot.id,
|
11
|
+
user_id: user.id,
|
12
|
+
chat_id: chat.id
|
13
|
+
)
|
14
|
+
|
15
|
+
message_object.update! text: message.try(:text),
|
16
|
+
project_id: Project.find_by(title: 'PurpleMagic').id,
|
17
|
+
options: (telegram_message_attributes.reduce({}) do |hash, attribute|
|
18
|
+
hash.merge! attribute => message.send(attribute)
|
19
|
+
end)
|
20
|
+
|
21
|
+
message_object
|
22
|
+
end
|
23
|
+
|
24
|
+
# :reek:FeatureEnvy { enabled: false }
|
25
|
+
def message_to_chat(bot_api, chat_id, message_obj, **options)
|
26
|
+
case message_obj.class.to_s
|
27
|
+
when 'String'
|
28
|
+
send_string bot_api, chat_id, message_obj, **options
|
29
|
+
when 'Tramway::Bots::Telegram::Custom::Message'
|
30
|
+
bot_api.send_message chat_id: chat_id, **message_obj.options.merge(options)
|
31
|
+
send_file bot_api, chat_id, message_obj if message_obj.file.present?
|
32
|
+
else
|
33
|
+
raise message_obj.class.to_s
|
34
|
+
end
|
35
|
+
rescue StandardError => error
|
36
|
+
Airbrake.notify error
|
37
|
+
end
|
38
|
+
# :reek:FeatureEnvy { enabled: true }
|
39
|
+
|
40
|
+
def message_to_user(bot_api, message_obj, chat_id)
|
41
|
+
case message_obj.class.to_s
|
42
|
+
when 'String'
|
43
|
+
send_string bot_api, chat_id, message_obj
|
44
|
+
when 'Tramway::Bots::Telegram::Scenario::Step'
|
45
|
+
send_scenario_step bot_api, chat_id, message_obj
|
46
|
+
when 'Tramway::Bots::Telegram::Custom::Message'
|
47
|
+
bot_api.send_message chat_id: chat_id, **message_obj.options
|
48
|
+
end
|
49
|
+
rescue StandardError => error
|
50
|
+
Airbrake.notify error
|
51
|
+
end
|
52
|
+
|
53
|
+
def send_file(bot_api, chat_id, message_obj)
|
54
|
+
mime_type = case message_obj.file.file.file[-3..].downcase
|
55
|
+
when 'jpg', 'png'
|
56
|
+
[:photo, 'image/jpeg']
|
57
|
+
when 'mp3'
|
58
|
+
[:voice, 'audio/mpeg']
|
59
|
+
end
|
60
|
+
params = {
|
61
|
+
chat_id: chat_id,
|
62
|
+
mime_type[0] => Faraday::UploadIO.new(message_obj.file.file.file, mime_type[1])
|
63
|
+
}
|
64
|
+
if message_obj.reply_markup.present?
|
65
|
+
params.merge!(
|
66
|
+
reply_markup: Telegram::Bot::Types::ReplyKeyboardMarkup.new(**message_obj.reply_markup),
|
67
|
+
parse_mode: :markdown
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
bot_api.public_send "send_#{mime_type[0]}", **params
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def send_string(bot_api, chat_id, message_obj, **options)
|
77
|
+
sleep 1
|
78
|
+
bot_api.send_message(
|
79
|
+
chat_id: chat_id,
|
80
|
+
text: message_obj,
|
81
|
+
**options
|
82
|
+
)
|
83
|
+
end
|
84
|
+
|
85
|
+
def send_scenario_step(bot_api, chat_id, message_obj)
|
86
|
+
if message_obj.try(:text).present?
|
87
|
+
if message_obj.reply_markup.present?
|
88
|
+
bot_api.send_message(
|
89
|
+
chat_id: chat_id,
|
90
|
+
text: message_obj&.text,
|
91
|
+
reply_markup: Telegram::Bot::Types::ReplyKeyboardMarkup.new(**message_obj.reply_markup),
|
92
|
+
parse_mode: :markdown
|
93
|
+
)
|
94
|
+
else
|
95
|
+
bot_api.send_message chat_id: chat_id, text: message_obj.text, parse_mode: :markdown
|
96
|
+
end
|
97
|
+
end
|
98
|
+
send_file bot_api, chat_id, message_obj if message_obj.file.path.present?
|
99
|
+
end
|
100
|
+
end
|
data/lib/tramway/bots.rb
ADDED
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tramway-bots
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pavel Kalashnikov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-06-07 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description:
|
14
|
+
email:
|
15
|
+
- kalashnikovisme@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- MIT-LICENSE
|
21
|
+
- README.md
|
22
|
+
- Rakefile
|
23
|
+
- app/assets/config/tramway_bots_manifest.js
|
24
|
+
- app/assets/stylesheets/tramway/bots/application.css
|
25
|
+
- app/controllers/tramway/bots/application_controller.rb
|
26
|
+
- app/helpers/tramway/bots/application_helper.rb
|
27
|
+
- app/jobs/tramway/bots/application_job.rb
|
28
|
+
- app/mailers/tramway/bots/application_mailer.rb
|
29
|
+
- app/models/tramway/bots/application_record.rb
|
30
|
+
- app/models/tramway/bots/bot.rb
|
31
|
+
- app/models/tramway/bots/telegram/channel.rb
|
32
|
+
- app/models/tramway/bots/telegram/chat.rb
|
33
|
+
- app/models/tramway/bots/telegram/message.rb
|
34
|
+
- app/models/tramway/bots/telegram/user.rb
|
35
|
+
- app/models/tramway/bots/telegram/users.rb
|
36
|
+
- app/models/tramway/bots/telegram/users/state.rb
|
37
|
+
- app/views/layouts/tramway/bots/application.html.erb
|
38
|
+
- config/routes.rb
|
39
|
+
- lib/tramway/bots.rb
|
40
|
+
- lib/tramway/bots/engine.rb
|
41
|
+
- lib/tramway/bots/generates/install_generator.rb
|
42
|
+
- lib/tramway/bots/generates/templates/create_tramway_bots_bots.rb
|
43
|
+
- lib/tramway/bots/generates/templates/create_tramway_bots_telegram_channels.rb
|
44
|
+
- lib/tramway/bots/generates/templates/create_tramway_bots_telegram_chats.rb
|
45
|
+
- lib/tramway/bots/generates/templates/create_tramway_bots_telegram_messages.rb
|
46
|
+
- lib/tramway/bots/generates/templates/create_tramway_bots_telegram_users.rb
|
47
|
+
- lib/tramway/bots/generates/templates/create_tramway_bots_telegram_users_states.rb
|
48
|
+
- lib/tramway/bots/telegram.rb
|
49
|
+
- lib/tramway/bots/telegram/custom.rb
|
50
|
+
- lib/tramway/bots/telegram/custom/message.rb
|
51
|
+
- lib/tramway/bots/telegram/custom/notify.rb
|
52
|
+
- lib/tramway/bots/telegram/custom/notify/file.rb
|
53
|
+
- lib/tramway/bots/telegram/custom/notify/text.rb
|
54
|
+
- lib/tramway/bots/telegram/custom/scenario.rb
|
55
|
+
- lib/tramway/bots/telegram/info.rb
|
56
|
+
- lib/tramway/bots/telegram/message.rb
|
57
|
+
- lib/tramway/bots/telegram/messages_manager.rb
|
58
|
+
- lib/tramway/bots/version.rb
|
59
|
+
homepage: https://github.com/Purple-Magic/tramway-bots
|
60
|
+
licenses:
|
61
|
+
- MIT
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
requirements: []
|
78
|
+
rubygems_version: 3.1.6
|
79
|
+
signing_key:
|
80
|
+
specification_version: 4
|
81
|
+
summary: Rails Engine for bot management
|
82
|
+
test_files: []
|