telegem 2.0.7 → 2.0.9
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/Test-Projects/Movie-tracker-bot/Gemfile +2 -0
- data/Test-Projects/Movie-tracker-bot/bot.rb +62 -0
- data/Test-Projects/Movie-tracker-bot/handlers/.gitkeep +0 -0
- data/Test-Projects/Movie-tracker-bot/handlers/add_1_.rb +160 -0
- data/Test-Projects/Movie-tracker-bot/handlers/add_2_.rb +139 -0
- data/Test-Projects/Movie-tracker-bot/handlers/premium.rb +13 -0
- data/Test-Projects/Movie-tracker-bot/handlers/report.rb +31 -0
- data/Test-Projects/Movie-tracker-bot/handlers/search.rb +150 -0
- data/Test-Projects/Movie-tracker-bot/handlers/sponsor.rb +14 -0
- data/Test-Projects/Movie-tracker-bot/handlers/start.rb +48 -0
- data/Test-Projects/Movie-tracker-bot/handlers/watch.rb +210 -0
- data/Test-Projects/Test-submitted-by-marvel/.gitkeep +0 -0
- data/Test-Projects/Test-submitted-by-marvel/Marvel-bot.md +3 -0
- data/docs-src/.gitkeep +0 -0
- data/docs-src/Bot-registration_.PNG +0 -0
- data/docs-src/bot.md +295 -0
- data/docs-src/context|ctx|.md +531 -0
- data/docs-src/getting-started.md +328 -0
- data/docs-src/keyboard_inline.md +413 -0
- data/docs-src/scene.md +509 -0
- data/docs-src/understanding-ctx.md +581 -0
- data/lib/api/client.rb +17 -16
- data/lib/core/bot.rb +19 -25
- data/lib/telegem.rb +1 -1
- data/lib/webhook/server.rb +1 -1
- metadata +26 -15
- data/docs/Api.md +0 -211
- data/docs/Cookbook(copy_paste).md +0 -644
- data/docs/Getting_started.md +0 -348
- data/docs/How_to_use.md +0 -571
- data/docs/QuickStart.md +0 -258
- data/docs/Understanding_Scene.md +0 -434
- data/docs/Usage.md +0 -717
- data/docs/webhook_setup.md +0 -199
- /data/{docs → Test-Projects/Movie-tracker-bot}/.gitkeep +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6f431a8a7aa53b06ed13e1eee3097ad92cff466b3eec7bf447f1502ac1216c3c
|
|
4
|
+
data.tar.gz: 8e3e297669ac814867accea2c898d96c4b73ec080dd5f89b863b3fe42b57d7a4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fd58b32563a8dd8ae705d2bb3933b4c7f237b81833733c534375bfdd1fb9c6e043de7c6411dfd0b478f24bd0c4d534789885bd64b9dd58116676d6743a92292e
|
|
7
|
+
data.tar.gz: 0b04670c9e2382aedd71d6f1f2c89067cc127c113ac834bb459335fcb366f6b73e32e2088a8abf7cf017a0f044c613d726b69242d382288e58680c4802e773e0
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'telegem'
|
|
3
|
+
require 'sqlite3'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
require_relative './handlers/start'
|
|
8
|
+
require_relative './handlers/add_1_'
|
|
9
|
+
require_relative './handlers/premium'
|
|
10
|
+
require_relative './handlers/add_2_'
|
|
11
|
+
require_relative './handlers/sponsor'
|
|
12
|
+
require_relative './handlers/watch'
|
|
13
|
+
require_relative './handlers/report'
|
|
14
|
+
require_relative './handlers/search'
|
|
15
|
+
|
|
16
|
+
bot_token = ENV['BOT_TOKEN']
|
|
17
|
+
|
|
18
|
+
bot = Telegem.new(ENV['BOT_TOKEN'])
|
|
19
|
+
puts "token is #{bot_token[0..10]}"
|
|
20
|
+
# In your code:
|
|
21
|
+
db = SQLite3::Database.new "movieflix.db"
|
|
22
|
+
|
|
23
|
+
puts "started sqlite"
|
|
24
|
+
|
|
25
|
+
StartHandler.new(bot, db)
|
|
26
|
+
SearchHandler.new(bot, db)
|
|
27
|
+
WatchHandler.new(bot, db)
|
|
28
|
+
HelpHandler.new(bot)
|
|
29
|
+
PremiumHandler.new(bot)
|
|
30
|
+
SponsorHandler.new(bot)
|
|
31
|
+
AddHandler.new(bot, db)
|
|
32
|
+
AddHears.new(bot, db)
|
|
33
|
+
|
|
34
|
+
port = (ENV['PORT'] || 3000).to_i
|
|
35
|
+
puts " 📍 Using port: #{port}"
|
|
36
|
+
puts " 🌐 Bind host: 0.0.0.0"
|
|
37
|
+
|
|
38
|
+
# Start polling
|
|
39
|
+
bot.start_polling
|
|
40
|
+
puts " started polling"
|
|
41
|
+
|
|
42
|
+
# Minimal health check server
|
|
43
|
+
Thread.new do
|
|
44
|
+
require 'socket'
|
|
45
|
+
server = TCPServer.new('0.0.0.0', port || 10000)
|
|
46
|
+
puts "✅ Health check server listening on port #{ENV['PORT'] || 10000}"
|
|
47
|
+
|
|
48
|
+
loop do
|
|
49
|
+
client = server.accept
|
|
50
|
+
request = client.gets
|
|
51
|
+
|
|
52
|
+
# Simple response for any request
|
|
53
|
+
client.puts "HTTP/1.1 200 OK\r\n"
|
|
54
|
+
client.puts "Content-Type: text/plain\r\n"
|
|
55
|
+
client.puts "\r\n"
|
|
56
|
+
client.puts "Telegram Bot is running"
|
|
57
|
+
client.close
|
|
58
|
+
end
|
|
59
|
+
puts "bot is running "
|
|
60
|
+
end
|
|
61
|
+
sleep
|
|
62
|
+
puts "bot is running alive now "
|
|
File without changes
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
class AddHandler
|
|
2
|
+
def initialize(bot, db)
|
|
3
|
+
@bot = bot
|
|
4
|
+
@db = db
|
|
5
|
+
setup_add_commands
|
|
6
|
+
setup_my_shows_command # ← FIXED: Added this call
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def setup_add_commands
|
|
10
|
+
@bot.command("add") do |ctx|
|
|
11
|
+
handle_add_command(ctx)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def handle_add_command(ctx)
|
|
16
|
+
args = ctx.message.text.split[1..-1] || []
|
|
17
|
+
|
|
18
|
+
# Input validation
|
|
19
|
+
if args.empty?
|
|
20
|
+
ctx.reply("❌ Usage: /add <show_id>\nExample: /add 1")
|
|
21
|
+
return
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if args.length > 10
|
|
25
|
+
ctx.reply("❌ You can only add up to 10 shows at once")
|
|
26
|
+
return
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
user_id = ctx.from.id
|
|
30
|
+
first_name = ctx.from.first_name
|
|
31
|
+
|
|
32
|
+
# Send processing message for bulk adds
|
|
33
|
+
if args.length > 3
|
|
34
|
+
ctx.reply("⏳ Adding #{args.length} shows...")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
added_shows = []
|
|
38
|
+
failed_shows = []
|
|
39
|
+
|
|
40
|
+
begin
|
|
41
|
+
@db.transaction do
|
|
42
|
+
args.each do |show_id_str|
|
|
43
|
+
show_id = show_id_str.to_i
|
|
44
|
+
|
|
45
|
+
if show_id <= 0
|
|
46
|
+
failed_shows << "#{show_id_str} (invalid ID)"
|
|
47
|
+
next
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
result = subscribe_user_to_show(user_id, show_id, first_name)
|
|
51
|
+
|
|
52
|
+
if result[:success]
|
|
53
|
+
added_shows << result[:show_title]
|
|
54
|
+
else
|
|
55
|
+
failed_shows << "#{show_id_str} (#{result[:error]})"
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
rescue SQLite3::Exception => e
|
|
60
|
+
ctx.reply("❌ Database error occurred. Please try again.")
|
|
61
|
+
return
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
send_add_response(ctx, added_shows, failed_shows)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def subscribe_user_to_show(user_id, show_id, user_name)
|
|
68
|
+
begin
|
|
69
|
+
show = @db.execute(
|
|
70
|
+
"SELECT id, title FROM movies WHERE id = ?",
|
|
71
|
+
[show_id]
|
|
72
|
+
).first
|
|
73
|
+
|
|
74
|
+
unless show
|
|
75
|
+
return {success: false, error: "Show not found"}
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
show_db_id = show[0]
|
|
79
|
+
show_title = show[1]
|
|
80
|
+
|
|
81
|
+
# Ensure user exists
|
|
82
|
+
@db.execute(
|
|
83
|
+
"INSERT OR IGNORE INTO users (telegram_id, first_name) VALUES (?, ?)",
|
|
84
|
+
[user_id, user_name]
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
# Add to watched table
|
|
88
|
+
@db.execute(<<-SQL, [user_id, show_db_id])
|
|
89
|
+
INSERT OR IGNORE INTO watched (telegram_id, movie_id, season, episode)
|
|
90
|
+
VALUES (?, ?, 1, 0)
|
|
91
|
+
SQL
|
|
92
|
+
|
|
93
|
+
inserted = @db.changes > 0
|
|
94
|
+
|
|
95
|
+
if inserted
|
|
96
|
+
{success: true, show_title: show_title, show_id: show_db_id}
|
|
97
|
+
else
|
|
98
|
+
{success: false, error: "Already subscribed"}
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
rescue SQLite3::Exception => e
|
|
102
|
+
return {success: false, error: "Database error"}
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def send_add_response(ctx, added_shows, failed_shows)
|
|
107
|
+
response = ""
|
|
108
|
+
|
|
109
|
+
if added_shows.any?
|
|
110
|
+
response += "✅ *Added to your list:*\n"
|
|
111
|
+
added_shows.each_with_index do |show, i|
|
|
112
|
+
response += "#{i + 1}. #{show}\n"
|
|
113
|
+
end
|
|
114
|
+
response += "\n"
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
if failed_shows.any?
|
|
118
|
+
response += "❌ *Failed to add:*\n"
|
|
119
|
+
failed_shows.each do |fail|
|
|
120
|
+
response += "• #{fail}\n"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
if response.empty?
|
|
125
|
+
response = "⚠️ Nothing was added"
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
ctx.reply(response, parse_mode: 'Markdown')
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def setup_my_shows_command
|
|
132
|
+
@bot.command("myshows") do |ctx|
|
|
133
|
+
user_id = ctx.from.id
|
|
134
|
+
|
|
135
|
+
begin
|
|
136
|
+
shows = @db.execute(<<-SQL, [user_id])
|
|
137
|
+
SELECT movies.id, movies.title, watched.season, watched.episode
|
|
138
|
+
FROM watched
|
|
139
|
+
JOIN movies ON movies.id = watched.movie_id
|
|
140
|
+
WHERE watched.telegram_id = ?
|
|
141
|
+
ORDER BY movies.title
|
|
142
|
+
SQL
|
|
143
|
+
|
|
144
|
+
if shows.empty?
|
|
145
|
+
ctx.reply("📭 Your list is empty!\nUse /search to find shows, then /add <id>")
|
|
146
|
+
else
|
|
147
|
+
response = "📺 *Your Shows:*\n\n"
|
|
148
|
+
shows.each do |id, title, season, episode|
|
|
149
|
+
response += "🎬 #{title}\n"
|
|
150
|
+
response += " ID: `#{id}` | Last: S#{season}E#{episode}\n"
|
|
151
|
+
response += " /watch #{id} s#{season}e#{episode + 1}\n\n"
|
|
152
|
+
end
|
|
153
|
+
ctx.reply(response, parse_mode: 'Markdown')
|
|
154
|
+
end
|
|
155
|
+
rescue SQLite3::Exception => e
|
|
156
|
+
ctx.reply("❌ Error loading your shows. Please try again.")
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
class AddHears
|
|
2
|
+
def initialize(bot, db)
|
|
3
|
+
@bot = bot
|
|
4
|
+
@db = db
|
|
5
|
+
setup_add_commands
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def setup_add_commands
|
|
9
|
+
# Command: /add <show_id>
|
|
10
|
+
@bot.hears("〽️Add_Movie") do |ctx|
|
|
11
|
+
handle_add_command(ctx)
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def handle_add_command(ctx)
|
|
16
|
+
|
|
17
|
+
args = ctx.message.text.split[1..-1] || []
|
|
18
|
+
|
|
19
|
+
if args.empty?
|
|
20
|
+
ctx.reply("❌ Usage: /add <show_id>\nExample: /add 1")
|
|
21
|
+
return
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
user_id = ctx.from.id
|
|
25
|
+
first_name = ctx.from.first_name
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
added_shows = []
|
|
29
|
+
failed_shows = []
|
|
30
|
+
|
|
31
|
+
args.each do |show_id_str|
|
|
32
|
+
show_id = show_id_str.to_i
|
|
33
|
+
|
|
34
|
+
if show_id <= 0
|
|
35
|
+
failed_shows << "#{show_id_str} (invalid ID)"
|
|
36
|
+
next
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
result = subscribe_user_to_show(user_id, show_id, first_name)
|
|
40
|
+
|
|
41
|
+
if result[:success]
|
|
42
|
+
added_shows << result[:show_title]
|
|
43
|
+
else
|
|
44
|
+
failed_shows << "#{show_id_str} (#{result[:error]})"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Send response
|
|
49
|
+
send_add_response(ctx, added_shows, failed_shows)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def subscribe_user_to_show(user_id, show_id, user_name)
|
|
53
|
+
|
|
54
|
+
show = @db.execute(
|
|
55
|
+
"SELECT id, title FROM movies WHERE id = ?",
|
|
56
|
+
[show_id]
|
|
57
|
+
).first
|
|
58
|
+
|
|
59
|
+
unless show
|
|
60
|
+
return {success: false, error: "Show not found"}
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
show_db_id = show[0]
|
|
64
|
+
show_title = show[1]
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@db.execute(
|
|
68
|
+
"INSERT OR IGNORE INTO users (telegram_id, first_name) VALUES (?, ?)",
|
|
69
|
+
[user_id, user_name]
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
# 3. Add to watched table (initial state: season=1, episode=0)
|
|
73
|
+
@db.execute(<<-SQL, [user_id, show_db_id])
|
|
74
|
+
INSERT OR IGNORE INTO watched (telegram_id, movie_id, season, episode)
|
|
75
|
+
VALUES (?, ?, 1, 0)
|
|
76
|
+
SQL
|
|
77
|
+
|
|
78
|
+
# 4. Check if actually inserted
|
|
79
|
+
inserted = @db.changes > 0
|
|
80
|
+
|
|
81
|
+
if inserted
|
|
82
|
+
{success: true, show_title: show_title, show_id: show_db_id}
|
|
83
|
+
else
|
|
84
|
+
{success: false, error: "Already subscribed"}
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def send_add_response(ctx, added_shows, failed_shows)
|
|
89
|
+
response = ""
|
|
90
|
+
|
|
91
|
+
if added_shows.any?
|
|
92
|
+
response += "✅ *Added to your list:*\n"
|
|
93
|
+
added_shows.each_with_index do |show, i|
|
|
94
|
+
response += "#{i + 1}. #{show}\n"
|
|
95
|
+
end
|
|
96
|
+
response += "\n"
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if failed_shows.any?
|
|
100
|
+
response += "❌ *Failed to add:*\n"
|
|
101
|
+
failed_shows.each do |fail|
|
|
102
|
+
response += "• #{fail}\n"
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
if response.empty?
|
|
107
|
+
response = "⚠️ Nothing was added"
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
ctx.reply(response, parse_mode: 'Markdown')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
# Optional: Show user's current shows
|
|
114
|
+
def setup_my_shows_command
|
|
115
|
+
@bot.hears("my shows") do |ctx|
|
|
116
|
+
user_id = ctx.from.id
|
|
117
|
+
|
|
118
|
+
shows = @db.execute(<<-SQL, [user_id])
|
|
119
|
+
SELECT movies.id, movies.title, watched.season, watched.episode
|
|
120
|
+
FROM watched
|
|
121
|
+
JOIN movies ON movies.id = watched.movie_id
|
|
122
|
+
WHERE watched.telegram_id = ?
|
|
123
|
+
ORDER BY movies.title
|
|
124
|
+
SQL
|
|
125
|
+
|
|
126
|
+
if shows.empty?
|
|
127
|
+
ctx.reply("📭 Your list is empty!\nUse /search to find shows, then /add <id>")
|
|
128
|
+
else
|
|
129
|
+
response = "📺 *Your Shows:*\n\n"
|
|
130
|
+
shows.each do |id, title, season, episode|
|
|
131
|
+
response += "🎬 #{title}\n"
|
|
132
|
+
response += " ID: `#{id}` | Last: S#{season}E#{episode}\n"
|
|
133
|
+
response += " /watch #{id} s#{season}e#{episode + 1}\n\n"
|
|
134
|
+
end
|
|
135
|
+
ctx.reply(response, parse_mode: 'Markdown')
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
class HelpHandler
|
|
2
|
+
def initialize(bot)
|
|
3
|
+
@bot = bot
|
|
4
|
+
start_helper
|
|
5
|
+
end
|
|
6
|
+
def start_helper
|
|
7
|
+
@bot.hears("🧑🏿✈️report_bug") do |ctx|
|
|
8
|
+
ctx.reply("welcome to MovieFlix report section")
|
|
9
|
+
inline = Telegem.inline do
|
|
10
|
+
url "🙋♀️ FAQ", "https://gitlab.com/ynwghosted/flix-faq"
|
|
11
|
+
end
|
|
12
|
+
ctx.reply("👋 pls describe the issues you facing or visit our FAQ", reply_markup: inline)
|
|
13
|
+
issue = ctx.message.text
|
|
14
|
+
user_id = ctx.from.id
|
|
15
|
+
if issue.nil?
|
|
16
|
+
ctx.reply("whats the issue??")
|
|
17
|
+
else
|
|
18
|
+
ctx.reply("issue has been submitted")
|
|
19
|
+
end
|
|
20
|
+
JSON.parse(File.read('issues.json'))
|
|
21
|
+
issues << {
|
|
22
|
+
"text" => issue,
|
|
23
|
+
"user_id" => user_id
|
|
24
|
+
}
|
|
25
|
+
File.write('issues.json', JSON.pretty_generate(issues))
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require 'uri'
|
|
2
|
+
require 'net/http'
|
|
3
|
+
require 'json'
|
|
4
|
+
|
|
5
|
+
class SearchHandler
|
|
6
|
+
def initialize(bot, db)
|
|
7
|
+
@bot = bot
|
|
8
|
+
@db = db
|
|
9
|
+
setup_search_commands
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def setup_search_commands
|
|
13
|
+
# Command: /search
|
|
14
|
+
@bot.hears("🔃search") do |ctx|
|
|
15
|
+
ctx.reply("🎬 Search for TV shows\n\nUse: search <show name>\nExample: search Stranger Things")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Hears: "search merlin" or "search stranger things"
|
|
19
|
+
@bot.hears(/^\s*search\s+/i) do |ctx|
|
|
20
|
+
handle_search_request(ctx)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def handle_search_request(ctx)
|
|
25
|
+
# Extract show name from message
|
|
26
|
+
text = ctx.message.text
|
|
27
|
+
show_name = text.sub(/^\s*search\s+/i, "").strip
|
|
28
|
+
|
|
29
|
+
if show_name.empty?
|
|
30
|
+
ctx.reply("❌ Please provide a show name")
|
|
31
|
+
return
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
ctx.reply("🔍 Searching for '#{show_name}'...")
|
|
35
|
+
|
|
36
|
+
# Step 1: Check OUR database first
|
|
37
|
+
local_show = find_in_local_database(show_name)
|
|
38
|
+
|
|
39
|
+
if local_show
|
|
40
|
+
# Found in our DB
|
|
41
|
+
send_local_result(ctx, local_show)
|
|
42
|
+
else
|
|
43
|
+
# Not in our DB → Search API
|
|
44
|
+
api_result = search_tvmaze_api(show_name)
|
|
45
|
+
|
|
46
|
+
if api_result[:error]
|
|
47
|
+
ctx.reply("❌ #{api_result[:error]}")
|
|
48
|
+
else
|
|
49
|
+
# Save to OUR database
|
|
50
|
+
saved_show = save_show_to_database(api_result)
|
|
51
|
+
send_api_result(ctx, saved_show)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def find_in_local_database(show_name)
|
|
58
|
+
# Search in movies table
|
|
59
|
+
result = @db.execute(
|
|
60
|
+
"SELECT id, title, created_at FROM movies WHERE title LIKE ? LIMIT 1",
|
|
61
|
+
["%#{show_name}%"]
|
|
62
|
+
).first
|
|
63
|
+
|
|
64
|
+
return nil unless result
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
id: result[0],
|
|
68
|
+
title: result[1], # Show title
|
|
69
|
+
created_at: result[2], #
|
|
70
|
+
source: :local_database
|
|
71
|
+
}
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def save_show_to_database(show_data)
|
|
75
|
+
# Insert into movies table
|
|
76
|
+
@db.execute(
|
|
77
|
+
"INSERT OR IGNORE INTO movies (title) VALUES (?)",
|
|
78
|
+
[show_data[:name]]
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
# Get the ID we just inserted (or existing ID)
|
|
82
|
+
db_id = @db.execute(
|
|
83
|
+
"SELECT id FROM movies WHERE title = ?",
|
|
84
|
+
[show_data[:name]]
|
|
85
|
+
).first[0]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
id: db_id,
|
|
90
|
+
title: show_data[:name],
|
|
91
|
+
tvmaze_id: show_data[:id],
|
|
92
|
+
next_airdate: show_data[:next_airdate],
|
|
93
|
+
source: :tvmaze_api
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def search_tvmaze_api(show_name)
|
|
100
|
+
url = "https://api.tvmaze.com/singlesearch/shows?q=#{URI.encode_www_form_component(show_name)}&embed=nextepisode"
|
|
101
|
+
|
|
102
|
+
begin
|
|
103
|
+
uri = URI(url)
|
|
104
|
+
response = Net::HTTP.get(uri)
|
|
105
|
+
data = JSON.parse(response)
|
|
106
|
+
|
|
107
|
+
if data["id"].nil?
|
|
108
|
+
return { error: "Show '#{show_name}' not found on TVMaze" }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
{
|
|
112
|
+
id: data["id"],
|
|
113
|
+
name: data["name"],
|
|
114
|
+
air_days: data.dig("schedule", "days") || [],
|
|
115
|
+
next_airdate: data.dig("_embedded", "nextepisode", "airdate"),
|
|
116
|
+
summary: data["summary"] || "No summary available",
|
|
117
|
+
status: data["status"] || "Unknown"
|
|
118
|
+
}
|
|
119
|
+
rescue => e
|
|
120
|
+
return { error: "API error: #{e.message}" }
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def send_local_result(ctx, show)
|
|
127
|
+
message = "✅ Found in our database!\n\n"
|
|
128
|
+
message += "🎬 #{show[:title]}\n"
|
|
129
|
+
message += "🆔 Our ID: #{show[:id]}\n"
|
|
130
|
+
message += "📅 Added: #{show[:created_at]}\n\n"
|
|
131
|
+
message += "Use /add #{show[:id]} to track this show"
|
|
132
|
+
|
|
133
|
+
ctx.reply(message)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def send_api_result(ctx, show)
|
|
137
|
+
message = "🎬 #{show[:title]}\n"
|
|
138
|
+
message += "🆔 TVMaze ID: #{show[:tvmaze_id]}\n"
|
|
139
|
+
message += "🆔 Our DB ID: #{show[:id]}\n"
|
|
140
|
+
|
|
141
|
+
if show[:next_airdate]
|
|
142
|
+
message += "📅 Next episode: #{show[:next_airdate]}\n"
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
message += "\n✅ Saved to our database!\n"
|
|
146
|
+
message += "Use /add #{show[:id]} to track this show"
|
|
147
|
+
|
|
148
|
+
ctx.reply(message)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class SponsorHandler
|
|
2
|
+
def initialize(bot)
|
|
3
|
+
@bot = bot
|
|
4
|
+
start_sponsoring_div
|
|
5
|
+
end
|
|
6
|
+
def start_sponsoring_div
|
|
7
|
+
@bot.hears("🤠sponsor") do |ctx|
|
|
8
|
+
ctx.typing
|
|
9
|
+
sleep 5
|
|
10
|
+
ctx.reply("utimately your application will be viewed by the board")
|
|
11
|
+
ctx.reply("chat with our board @darksnipe")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
class StartHandler
|
|
2
|
+
def initialize(bot, db)
|
|
3
|
+
@bot = bot
|
|
4
|
+
@db = db
|
|
5
|
+
start_command
|
|
6
|
+
create_tables
|
|
7
|
+
end
|
|
8
|
+
def start_command
|
|
9
|
+
@bot.command("start") do |ctx|
|
|
10
|
+
ctx.reply("welcome to MOVIE_FLIx")
|
|
11
|
+
keyboard = Telegem.keyboard do
|
|
12
|
+
row "🔃search", "〽️Add_Movie"
|
|
13
|
+
row "👩💻help", "🧑🏿✈️report_bug"
|
|
14
|
+
row "🤴🏼premium", "🤠sponsor"
|
|
15
|
+
end
|
|
16
|
+
ctx.reply("Best flix tracker bot....", reply_markup: keyboard)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
def create_tables
|
|
20
|
+
@db.execute <<-SQL
|
|
21
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
22
|
+
telegram_id INTEGER PRIMARY KEY,
|
|
23
|
+
first_name TEXT,
|
|
24
|
+
username TEXT,
|
|
25
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
26
|
+
)
|
|
27
|
+
SQL
|
|
28
|
+
|
|
29
|
+
@db.execute <<-SQL
|
|
30
|
+
CREATE TABLE IF NOT EXISTS movies (
|
|
31
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
32
|
+
title TEXT UNIQUE,
|
|
33
|
+
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
34
|
+
)
|
|
35
|
+
SQL
|
|
36
|
+
|
|
37
|
+
@db.execute <<-SQL
|
|
38
|
+
CREATE TABLE IF NOT EXISTS watched (
|
|
39
|
+
telegram_id INTEGER,
|
|
40
|
+
movie_id INTEGER,
|
|
41
|
+
season INTEGER DEFAULT 1,
|
|
42
|
+
episode INTEGER DEFAULT 0,
|
|
43
|
+
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
|
44
|
+
UNIQUE(telegram_id, movie_id)
|
|
45
|
+
)
|
|
46
|
+
SQL
|
|
47
|
+
end
|
|
48
|
+
end
|