telegram_bot_engine 0.2.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +33 -0
- data/app/controllers/telegram_bot_engine/admin/events_controller.rb +21 -0
- data/app/jobs/telegram_bot_engine/delivery_job.rb +12 -0
- data/app/models/telegram_bot_engine/event.rb +38 -0
- data/app/views/telegram_bot_engine/admin/events/index.html.erb +115 -0
- data/app/views/telegram_bot_engine/admin/layouts/application.html.erb +2 -0
- data/config/routes.rb +1 -0
- data/db/migrate/003_create_telegram_bot_engine_events.rb +22 -0
- data/lib/telegram_bot_engine/configuration.rb +4 -1
- data/lib/telegram_bot_engine/subscriber_commands.rb +21 -0
- data/lib/telegram_bot_engine/version.rb +1 -1
- data/lib/telegram_bot_engine.rb +13 -0
- metadata +5 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5b3bf5d33786a7847de84d3b85308001301ea88d642d8b8e881341be9bd311d1
|
|
4
|
+
data.tar.gz: 71a00b7a640dfd91c79b6080a3295ab6621fc938a05504f94c28f9757a655c59
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4d892f84a28953e2bc78c157ae9169ba3907e0482b15c79ae3068b2d7c43514d3014ee46ca415e33aaaa94c72d1c9470a9e139066ea816c17844711373d7d18f
|
|
7
|
+
data.tar.gz: f9154fdc913b4fe766d89a9e5a6fcca88333a192e1e71c233972c0d1335d7641ef0f30fe2554a1ad16e37920c36e5a91b53a3600f7c754f3eb8e74890cd3c2cf
|
data/README.md
CHANGED
|
@@ -53,6 +53,10 @@ TelegramBotEngine.configure do |config|
|
|
|
53
53
|
# Optional: custom messages
|
|
54
54
|
# config.unauthorized_message = "Sorry, you're not authorized to use this bot."
|
|
55
55
|
# config.welcome_message = "Welcome %{username}! Available commands:\n%{commands}"
|
|
56
|
+
|
|
57
|
+
# Event logging — logs commands, deliveries, auth failures to the database
|
|
58
|
+
# config.event_logging = true # default: true
|
|
59
|
+
# config.event_retention_days = 30 # default: 30, auto-purges older events
|
|
56
60
|
end
|
|
57
61
|
```
|
|
58
62
|
|
|
@@ -149,6 +153,35 @@ When mounted, the engine provides a web interface for:
|
|
|
149
153
|
- **Dashboard** — bot info, subscription counts
|
|
150
154
|
- **Subscriptions** — list, activate/deactivate, delete
|
|
151
155
|
- **Allowlist** — add/remove usernames (when `config.allowed_usernames = :database`)
|
|
156
|
+
- **Events** — browsable log of commands, deliveries, and auth failures with filtering by type, action, and chat ID
|
|
157
|
+
|
|
158
|
+
### Event log
|
|
159
|
+
|
|
160
|
+
The engine automatically logs operational events to the `telegram_bot_engine_events` table:
|
|
161
|
+
|
|
162
|
+
| Event type | Actions | When |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| `command` | `start`, `stop`, `help` | User sends a bot command |
|
|
165
|
+
| `delivery` | `broadcast`, `notify`, `delivered`, `blocked` | Messages are queued or delivered |
|
|
166
|
+
| `auth_failure` | `unauthorized` | Unauthorized user attempts a command |
|
|
167
|
+
|
|
168
|
+
Events are viewable in the admin UI and can be queried directly:
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
# Recent command events
|
|
172
|
+
TelegramBotEngine::Event.by_type("command").recent.limit(20)
|
|
173
|
+
|
|
174
|
+
# Deliveries to a specific chat
|
|
175
|
+
TelegramBotEngine::Event.by_type("delivery").by_chat_id(123456789)
|
|
176
|
+
|
|
177
|
+
# Events in the last 24 hours
|
|
178
|
+
TelegramBotEngine::Event.since(24.hours.ago)
|
|
179
|
+
|
|
180
|
+
# Manual purge (automatic purge runs probabilistically)
|
|
181
|
+
TelegramBotEngine::Event.purge_old!
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Disable event logging entirely with `config.event_logging = false`.
|
|
152
185
|
|
|
153
186
|
## Requirements
|
|
154
187
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TelegramBotEngine
|
|
4
|
+
module Admin
|
|
5
|
+
class EventsController < BaseController
|
|
6
|
+
PER_PAGE = 50
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
@events = Event.recent
|
|
10
|
+
@events = @events.by_type(params[:type]) if params[:type].present?
|
|
11
|
+
@events = @events.by_action(params[:action_name]) if params[:action_name].present?
|
|
12
|
+
@events = @events.by_chat_id(params[:chat_id]) if params[:chat_id].present?
|
|
13
|
+
|
|
14
|
+
@total_count = @events.count
|
|
15
|
+
@page = [params[:page].to_i, 1].max
|
|
16
|
+
@events = @events.offset((@page - 1) * PER_PAGE).limit(PER_PAGE)
|
|
17
|
+
@total_pages = (@total_count.to_f / PER_PAGE).ceil
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -11,10 +11,22 @@ module TelegramBotEngine
|
|
|
11
11
|
text: text,
|
|
12
12
|
**options.symbolize_keys
|
|
13
13
|
)
|
|
14
|
+
|
|
15
|
+
TelegramBotEngine::Event.log(
|
|
16
|
+
event_type: "delivery", action: "delivered",
|
|
17
|
+
chat_id: chat_id,
|
|
18
|
+
details: { text_preview: text.to_s[0, 100] }
|
|
19
|
+
)
|
|
14
20
|
rescue Telegram::Bot::Forbidden
|
|
15
21
|
# User blocked the bot - deactivate subscription
|
|
16
22
|
TelegramBotEngine::Subscription.where(chat_id: chat_id).update_all(active: false)
|
|
17
23
|
Rails.logger.info("[TelegramBotEngine] Deactivated subscription for blocked chat: #{chat_id}")
|
|
24
|
+
|
|
25
|
+
TelegramBotEngine::Event.log(
|
|
26
|
+
event_type: "delivery", action: "blocked",
|
|
27
|
+
chat_id: chat_id,
|
|
28
|
+
details: { text_preview: text.to_s[0, 100] }
|
|
29
|
+
)
|
|
18
30
|
end
|
|
19
31
|
end
|
|
20
32
|
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module TelegramBotEngine
|
|
4
|
+
class Event < ActiveRecord::Base
|
|
5
|
+
self.table_name = "telegram_bot_engine_events"
|
|
6
|
+
|
|
7
|
+
scope :recent, -> { order(created_at: :desc) }
|
|
8
|
+
scope :by_type, ->(type) { where(event_type: type) if type.present? }
|
|
9
|
+
scope :by_action, ->(action) { where(action: action) if action.present? }
|
|
10
|
+
scope :by_chat_id, ->(chat_id) { where(chat_id: chat_id) if chat_id.present? }
|
|
11
|
+
scope :since, ->(time) { where("created_at >= ?", time) }
|
|
12
|
+
|
|
13
|
+
validates :event_type, presence: true
|
|
14
|
+
validates :action, presence: true
|
|
15
|
+
|
|
16
|
+
def self.log(event_type:, action:, chat_id: nil, username: nil, details: {})
|
|
17
|
+
return unless TelegramBotEngine.config.event_logging
|
|
18
|
+
|
|
19
|
+
create!(
|
|
20
|
+
event_type: event_type,
|
|
21
|
+
action: action,
|
|
22
|
+
chat_id: chat_id,
|
|
23
|
+
username: username,
|
|
24
|
+
details: details
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
purge_old_randomly!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.purge_old!
|
|
31
|
+
where("created_at < ?", TelegramBotEngine.config.event_retention_days.days.ago).delete_all
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.purge_old_randomly!
|
|
35
|
+
purge_old! if rand(100).zero?
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
<div class="mb-6">
|
|
2
|
+
<h1 class="text-2xl font-bold text-gray-900">Events</h1>
|
|
3
|
+
<p class="mt-1 text-sm text-gray-500"><%= @total_count %> total</p>
|
|
4
|
+
</div>
|
|
5
|
+
|
|
6
|
+
<div class="mb-6 bg-white shadow-sm rounded-lg border border-gray-200 p-6">
|
|
7
|
+
<%= form_with url: telegram_bot_engine.admin_events_path, method: :get, local: true, class: "flex items-end space-x-4" do %>
|
|
8
|
+
<div>
|
|
9
|
+
<label for="type" class="block text-sm font-medium text-gray-700 mb-1">Event Type</label>
|
|
10
|
+
<select name="type" id="type" class="block rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm px-3 py-2 border">
|
|
11
|
+
<option value="">All</option>
|
|
12
|
+
<% %w[command delivery auth_failure subscription_change].each do |t| %>
|
|
13
|
+
<option value="<%= t %>" <%= "selected" if params[:type] == t %>><%= t %></option>
|
|
14
|
+
<% end %>
|
|
15
|
+
</select>
|
|
16
|
+
</div>
|
|
17
|
+
<div>
|
|
18
|
+
<label for="action_name" class="block text-sm font-medium text-gray-700 mb-1">Action</label>
|
|
19
|
+
<select name="action_name" id="action_name" class="block rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm px-3 py-2 border">
|
|
20
|
+
<option value="">All</option>
|
|
21
|
+
<% %w[start stop help broadcast notify delivered blocked failed unauthorized].each do |a| %>
|
|
22
|
+
<option value="<%= a %>" <%= "selected" if params[:action_name] == a %>><%= a %></option>
|
|
23
|
+
<% end %>
|
|
24
|
+
</select>
|
|
25
|
+
</div>
|
|
26
|
+
<div>
|
|
27
|
+
<label for="chat_id" class="block text-sm font-medium text-gray-700 mb-1">Chat ID</label>
|
|
28
|
+
<input type="text" name="chat_id" id="chat_id" value="<%= params[:chat_id] %>"
|
|
29
|
+
class="block rounded-md border-gray-300 shadow-sm focus:ring-blue-500 focus:border-blue-500 text-sm px-3 py-2 border"
|
|
30
|
+
placeholder="e.g. 12345">
|
|
31
|
+
</div>
|
|
32
|
+
<div>
|
|
33
|
+
<button type="submit"
|
|
34
|
+
class="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
|
|
35
|
+
Filter
|
|
36
|
+
</button>
|
|
37
|
+
</div>
|
|
38
|
+
<% end %>
|
|
39
|
+
</div>
|
|
40
|
+
|
|
41
|
+
<div class="bg-white shadow-sm rounded-lg border border-gray-200 overflow-hidden">
|
|
42
|
+
<table class="min-w-full divide-y divide-gray-200">
|
|
43
|
+
<thead class="bg-gray-50">
|
|
44
|
+
<tr>
|
|
45
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Timestamp</th>
|
|
46
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Type</th>
|
|
47
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Action</th>
|
|
48
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Username</th>
|
|
49
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Chat ID</th>
|
|
50
|
+
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Details</th>
|
|
51
|
+
</tr>
|
|
52
|
+
</thead>
|
|
53
|
+
<tbody class="bg-white divide-y divide-gray-200">
|
|
54
|
+
<% @events.each do |event| %>
|
|
55
|
+
<tr>
|
|
56
|
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
|
|
57
|
+
<%= event.created_at.strftime("%Y-%m-%d %H:%M:%S") %>
|
|
58
|
+
</td>
|
|
59
|
+
<td class="px-6 py-4 whitespace-nowrap">
|
|
60
|
+
<%
|
|
61
|
+
badge_colors = {
|
|
62
|
+
"command" => "bg-blue-100 text-blue-800",
|
|
63
|
+
"delivery" => "bg-green-100 text-green-800",
|
|
64
|
+
"auth_failure" => "bg-red-100 text-red-800",
|
|
65
|
+
"subscription_change" => "bg-yellow-100 text-yellow-800"
|
|
66
|
+
}
|
|
67
|
+
color = badge_colors[event.event_type] || "bg-gray-100 text-gray-800"
|
|
68
|
+
%>
|
|
69
|
+
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <%= color %>">
|
|
70
|
+
<%= event.event_type %>
|
|
71
|
+
</span>
|
|
72
|
+
</td>
|
|
73
|
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
|
|
74
|
+
<%= event.action %>
|
|
75
|
+
</td>
|
|
76
|
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-600">
|
|
77
|
+
<%= event.username || "-" %>
|
|
78
|
+
</td>
|
|
79
|
+
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500 font-mono">
|
|
80
|
+
<%= event.chat_id || "-" %>
|
|
81
|
+
</td>
|
|
82
|
+
<td class="px-6 py-4 text-sm text-gray-500 max-w-xs truncate" title="<%= event.details.to_json %>">
|
|
83
|
+
<%= event.details.present? ? event.details.to_json.truncate(80) : "-" %>
|
|
84
|
+
</td>
|
|
85
|
+
</tr>
|
|
86
|
+
<% end %>
|
|
87
|
+
|
|
88
|
+
<% if @events.empty? %>
|
|
89
|
+
<tr>
|
|
90
|
+
<td colspan="6" class="px-6 py-12 text-center text-sm text-gray-500">
|
|
91
|
+
No events found.
|
|
92
|
+
</td>
|
|
93
|
+
</tr>
|
|
94
|
+
<% end %>
|
|
95
|
+
</tbody>
|
|
96
|
+
</table>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<% if @total_pages > 1 %>
|
|
100
|
+
<div class="mt-4 flex justify-between items-center">
|
|
101
|
+
<div class="text-sm text-gray-500">
|
|
102
|
+
Page <%= @page %> of <%= @total_pages %>
|
|
103
|
+
</div>
|
|
104
|
+
<div class="flex space-x-2">
|
|
105
|
+
<% if @page > 1 %>
|
|
106
|
+
<%= link_to "Previous", telegram_bot_engine.admin_events_path(type: params[:type], action_name: params[:action_name], chat_id: params[:chat_id], page: @page - 1),
|
|
107
|
+
class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50" %>
|
|
108
|
+
<% end %>
|
|
109
|
+
<% if @page < @total_pages %>
|
|
110
|
+
<%= link_to "Next", telegram_bot_engine.admin_events_path(type: params[:type], action_name: params[:action_name], chat_id: params[:chat_id], page: @page + 1),
|
|
111
|
+
class: "inline-flex items-center px-4 py-2 border border-gray-300 rounded-md shadow-sm text-sm font-medium text-gray-700 bg-white hover:bg-gray-50" %>
|
|
112
|
+
<% end %>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
<% end %>
|
|
@@ -22,6 +22,8 @@
|
|
|
22
22
|
<%= link_to "Allowlist", telegram_bot_engine.admin_allowlist_index_path,
|
|
23
23
|
class: "px-3 py-2 rounded-md text-sm font-medium #{request.path.include?('allowlist') ? 'text-blue-600 bg-blue-50' : 'text-gray-600 hover:text-gray-900 hover:bg-gray-50'}" %>
|
|
24
24
|
<% end %>
|
|
25
|
+
<%= link_to "Events", telegram_bot_engine.admin_events_path,
|
|
26
|
+
class: "px-3 py-2 rounded-md text-sm font-medium #{request.path.include?('events') ? 'text-blue-600 bg-blue-50' : 'text-gray-600 hover:text-gray-900 hover:bg-gray-50'}" %>
|
|
25
27
|
</div>
|
|
26
28
|
</div>
|
|
27
29
|
</div>
|
data/config/routes.rb
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateTelegramBotEngineEvents < ActiveRecord::Migration[7.0]
|
|
4
|
+
def adapter_type
|
|
5
|
+
ActiveRecord::Base.connection.adapter_name.downcase.include?("postgresql") ? :jsonb : :json
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def change
|
|
9
|
+
create_table :telegram_bot_engine_events do |t|
|
|
10
|
+
t.string :event_type, null: false
|
|
11
|
+
t.string :action, null: false
|
|
12
|
+
t.bigint :chat_id
|
|
13
|
+
t.string :username
|
|
14
|
+
t.column :details, adapter_type, default: {}
|
|
15
|
+
t.datetime :created_at, null: false
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_index :telegram_bot_engine_events, :event_type
|
|
19
|
+
add_index :telegram_bot_engine_events, :created_at
|
|
20
|
+
add_index :telegram_bot_engine_events, :chat_id
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
module TelegramBotEngine
|
|
4
4
|
class Configuration
|
|
5
|
-
attr_accessor :allowed_usernames, :admin_enabled, :unauthorized_message, :welcome_message
|
|
5
|
+
attr_accessor :allowed_usernames, :admin_enabled, :unauthorized_message, :welcome_message,
|
|
6
|
+
:event_logging, :event_retention_days
|
|
6
7
|
|
|
7
8
|
def initialize
|
|
8
9
|
@allowed_usernames = nil
|
|
9
10
|
@admin_enabled = true
|
|
10
11
|
@unauthorized_message = "Sorry, you're not authorized to use this bot."
|
|
11
12
|
@welcome_message = "Welcome %{username}! Available commands:\n%{commands}"
|
|
13
|
+
@event_logging = true
|
|
14
|
+
@event_retention_days = 30
|
|
12
15
|
end
|
|
13
16
|
end
|
|
14
17
|
end
|
|
@@ -22,6 +22,11 @@ module TelegramBotEngine
|
|
|
22
22
|
)
|
|
23
23
|
subscription.save!
|
|
24
24
|
|
|
25
|
+
TelegramBotEngine::Event.log(
|
|
26
|
+
event_type: "command", action: "start",
|
|
27
|
+
chat_id: chat["id"], username: from["username"]
|
|
28
|
+
)
|
|
29
|
+
|
|
25
30
|
welcome = TelegramBotEngine.config.welcome_message % {
|
|
26
31
|
username: from["first_name"] || from["username"],
|
|
27
32
|
commands: available_commands_text
|
|
@@ -33,11 +38,22 @@ module TelegramBotEngine
|
|
|
33
38
|
def stop!(*)
|
|
34
39
|
subscription = TelegramBotEngine::Subscription.find_by(chat_id: chat["id"])
|
|
35
40
|
subscription&.update(active: false)
|
|
41
|
+
|
|
42
|
+
TelegramBotEngine::Event.log(
|
|
43
|
+
event_type: "command", action: "stop",
|
|
44
|
+
chat_id: chat["id"], username: from["username"]
|
|
45
|
+
)
|
|
46
|
+
|
|
36
47
|
respond_with :message, text: "You've been unsubscribed. Send /start to resubscribe."
|
|
37
48
|
end
|
|
38
49
|
|
|
39
50
|
# /help - list all available commands
|
|
40
51
|
def help!(*)
|
|
52
|
+
TelegramBotEngine::Event.log(
|
|
53
|
+
event_type: "command", action: "help",
|
|
54
|
+
chat_id: chat["id"], username: from["username"]
|
|
55
|
+
)
|
|
56
|
+
|
|
41
57
|
respond_with :message, text: "📋 *Available Commands*\n\n#{available_commands_text}", parse_mode: "Markdown"
|
|
42
58
|
end
|
|
43
59
|
|
|
@@ -46,6 +62,11 @@ module TelegramBotEngine
|
|
|
46
62
|
def authorize_user!
|
|
47
63
|
return if TelegramBotEngine::Authorizer.authorized?(from["username"])
|
|
48
64
|
|
|
65
|
+
TelegramBotEngine::Event.log(
|
|
66
|
+
event_type: "auth_failure", action: "unauthorized",
|
|
67
|
+
chat_id: chat["id"], username: from["username"]
|
|
68
|
+
)
|
|
69
|
+
|
|
49
70
|
respond_with :message, text: TelegramBotEngine.config.unauthorized_message
|
|
50
71
|
throw :abort
|
|
51
72
|
end
|
data/lib/telegram_bot_engine.rb
CHANGED
|
@@ -23,18 +23,31 @@ module TelegramBotEngine
|
|
|
23
23
|
|
|
24
24
|
# Broadcast to all active subscribers via background jobs
|
|
25
25
|
def broadcast(text, **options)
|
|
26
|
+
subscriber_count = 0
|
|
26
27
|
TelegramBotEngine::Subscription.active.find_each do |subscription|
|
|
27
28
|
TelegramBotEngine::DeliveryJob.perform_later(
|
|
28
29
|
subscription.chat_id,
|
|
29
30
|
text,
|
|
30
31
|
options
|
|
31
32
|
)
|
|
33
|
+
subscriber_count += 1
|
|
32
34
|
end
|
|
35
|
+
|
|
36
|
+
TelegramBotEngine::Event.log(
|
|
37
|
+
event_type: "delivery", action: "broadcast",
|
|
38
|
+
details: { subscriber_count: subscriber_count, text_preview: text.to_s[0, 100] }
|
|
39
|
+
)
|
|
33
40
|
end
|
|
34
41
|
|
|
35
42
|
# Send to a specific chat via background job
|
|
36
43
|
def notify(chat_id:, text:, **options)
|
|
37
44
|
TelegramBotEngine::DeliveryJob.perform_later(chat_id, text, options)
|
|
45
|
+
|
|
46
|
+
TelegramBotEngine::Event.log(
|
|
47
|
+
event_type: "delivery", action: "notify",
|
|
48
|
+
chat_id: chat_id,
|
|
49
|
+
details: { text_preview: text.to_s[0, 100] }
|
|
50
|
+
)
|
|
38
51
|
end
|
|
39
52
|
end
|
|
40
53
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: telegram_bot_engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- TelegramBotEngine Contributors
|
|
@@ -47,17 +47,21 @@ files:
|
|
|
47
47
|
- app/controllers/telegram_bot_engine/admin/allowlist_controller.rb
|
|
48
48
|
- app/controllers/telegram_bot_engine/admin/base_controller.rb
|
|
49
49
|
- app/controllers/telegram_bot_engine/admin/dashboard_controller.rb
|
|
50
|
+
- app/controllers/telegram_bot_engine/admin/events_controller.rb
|
|
50
51
|
- app/controllers/telegram_bot_engine/admin/subscriptions_controller.rb
|
|
51
52
|
- app/jobs/telegram_bot_engine/delivery_job.rb
|
|
52
53
|
- app/models/telegram_bot_engine/allowed_user.rb
|
|
54
|
+
- app/models/telegram_bot_engine/event.rb
|
|
53
55
|
- app/models/telegram_bot_engine/subscription.rb
|
|
54
56
|
- app/views/telegram_bot_engine/admin/allowlist/index.html.erb
|
|
55
57
|
- app/views/telegram_bot_engine/admin/dashboard/show.html.erb
|
|
58
|
+
- app/views/telegram_bot_engine/admin/events/index.html.erb
|
|
56
59
|
- app/views/telegram_bot_engine/admin/layouts/application.html.erb
|
|
57
60
|
- app/views/telegram_bot_engine/admin/subscriptions/index.html.erb
|
|
58
61
|
- config/routes.rb
|
|
59
62
|
- db/migrate/001_create_telegram_bot_engine_subscriptions.rb
|
|
60
63
|
- db/migrate/002_create_telegram_bot_engine_allowed_users.rb
|
|
64
|
+
- db/migrate/003_create_telegram_bot_engine_events.rb
|
|
61
65
|
- lib/tasks/telegram_bot_engine.rake
|
|
62
66
|
- lib/telegram_bot_engine.rb
|
|
63
67
|
- lib/telegram_bot_engine/authorizer.rb
|