Add multi-user and cron support.
This commit is contained in:
parent
32facc0d87
commit
7834d345bf
|
@ -5,70 +5,111 @@ require "time"
|
|||
require "sqlite3"
|
||||
require "cron_scheduler"
|
||||
|
||||
|
||||
# Chat IDs
|
||||
chatid_joann = 215301902
|
||||
chatid_daniel = 220888832
|
||||
CHATID_JOANN = 215301902_i64
|
||||
CHATID_DANIEL = 220888832_i64
|
||||
DATABASE_URL = "sqlite3://./data.sqlite"
|
||||
BOT_TOKEN = "599474797:AAEmjQNO32uqurI16blS9FT4OoO7GdUZ6h0"
|
||||
EXTENSIONS = ["png", "jpeg", "jpg"]
|
||||
LOGGER = Logger.new(STDOUT)
|
||||
|
||||
# Configuration
|
||||
database = "sqlite3://./data.sqlite"
|
||||
subreddit = "rarepuppers"
|
||||
chatid = chatid_daniel
|
||||
delay = 1.hours
|
||||
active_hours = 7..24
|
||||
bot_token = "599474797:AAEmjQNO32uqurI16blS9FT4OoO7GdUZ6h0"
|
||||
class BotConfiguration
|
||||
JSON.mapping(
|
||||
subreddits: Array(String),
|
||||
send_cron: String,
|
||||
refresh_cron: String,
|
||||
recepients: Array(Int64))
|
||||
|
||||
# Setup
|
||||
completed = [] of String
|
||||
logger = Logger.new(STDOUT)
|
||||
bot = Telepathy::Bot.new bot_token
|
||||
def initialize
|
||||
@subreddits = [ "rarepuppers" ]
|
||||
@send_cron = "00 8-21 * * *"
|
||||
@refresh_cron = "*/15 * * * *"
|
||||
@recepients = [ CHATID_DANIEL ]
|
||||
end
|
||||
end
|
||||
|
||||
class PupperBot
|
||||
@db : DB::Database
|
||||
|
||||
def initialize(@configuration : BotConfiguration)
|
||||
@telegram_bot = Telepathy::Bot.new BOT_TOKEN
|
||||
@db = DB.open DATABASE_URL
|
||||
initialize_db
|
||||
update_database
|
||||
initialize_timers
|
||||
initialize_telegram
|
||||
send_broadcast
|
||||
end
|
||||
|
||||
def initialize
|
||||
initialize BotConfiguration.new
|
||||
end
|
||||
|
||||
private def initialize_db
|
||||
@db.exec "create table if not exists posts(id integer primary key, title text, url text unique)"
|
||||
@db.exec "create table if not exists recepient_posts(recepient integer, post integer, foreign key(post) references posts(id))"
|
||||
end
|
||||
|
||||
private def initialize_timers
|
||||
CronScheduler.define do
|
||||
at(@configuration.send_cron) { send_broadcast }
|
||||
at(@configuration.refresh_cron) { update_database }
|
||||
end
|
||||
end
|
||||
|
||||
private def initialize_telegram
|
||||
@telegram_bot.command "ping" do |update, args|
|
||||
@telegram_bot.send_message(update.message.as(Telepathy::Message).chat.id, "pong")
|
||||
end
|
||||
|
||||
@telegram_bot.command "pupper" do |update, args|
|
||||
command_chatid = update.message.as(Telepathy::Message).chat.id
|
||||
send_single command_chatid
|
||||
end
|
||||
|
||||
@telegram_bot.poll
|
||||
end
|
||||
|
||||
def send_single(chatid)
|
||||
unsent_query = "select id, title, url from posts where not exists (select * from recepient_posts where recepient=? and post=id) limit 1"
|
||||
|
||||
unless to_send = @db.query_one? unsent_query, chatid, as: { Int64, String, String }
|
||||
LOGGER.info "Unable to find a post to send to #{chatid}."
|
||||
return
|
||||
end
|
||||
|
||||
id, title, url = to_send
|
||||
LOGGER.info "Using URL #{url} for request from #{chatid}"
|
||||
@db.exec "insert into recepient_posts(recepient, post) values(?, ?)", chatid, id
|
||||
@telegram_bot.send_photo(chatid, url, title)
|
||||
end
|
||||
|
||||
def send_broadcast
|
||||
@configuration.recepients.each do |recepient|
|
||||
send_single recepient
|
||||
end
|
||||
end
|
||||
|
||||
def update_database
|
||||
unless response = RedditResponse.from_subreddits(@configuration.subreddits)
|
||||
LOGGER.info "Unable to find more posts for the database"
|
||||
return
|
||||
end
|
||||
|
||||
posts = response.data.posts_matching { |post| EXTENSIONS.any? { |it| post.url.ends_with? it } }
|
||||
posts.each do |post|
|
||||
LOGGER.info "Trying to save post #{post.title} #{post.url}"
|
||||
begin
|
||||
@db.exec "insert into posts(title, url) values(?, ?)", post.title, post.url
|
||||
rescue e
|
||||
puts e
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
botc = PupperBot.new
|
||||
|
||||
# Commands.
|
||||
bot.command "ping" do |update, args|
|
||||
bot.send_message(update.message.as(Telepathy::Message).chat.id, "pong")
|
||||
end
|
||||
|
||||
# Tasks
|
||||
def update_database(db)
|
||||
end
|
||||
|
||||
bot.command "pupper" do |update, args|
|
||||
url_tuple = get_reddit_post(subreddit, completed)
|
||||
if url_tuple
|
||||
url, title = url_tuple
|
||||
command_chatid = update.message.as(Telepathy::Message).chat.id
|
||||
logger.info "Using URL #{url} for request from #{command_chatid}"
|
||||
bot.send_photo(command_chatid, url, title)
|
||||
else
|
||||
logger.error "Unable to find a post to send."
|
||||
end
|
||||
end
|
||||
|
||||
spawn do
|
||||
loop do
|
||||
time = Time.now
|
||||
url_tuple = get_reddit_post(subreddit, completed) if (active_hours.includes? time.hour)
|
||||
if url_tuple
|
||||
url, title = url_tuple
|
||||
logger.info "Sending regular picture to #{chatid}."
|
||||
bot.send_photo(chatid.to_i64, url, title)
|
||||
else
|
||||
logger.error "Unable to find a post to send. (Or it's quiet hours)"
|
||||
end
|
||||
sleep delay
|
||||
end
|
||||
end
|
||||
|
||||
# Code to stop the bot on time.
|
||||
end_channel = Channel(Nil).new(1)
|
||||
|
||||
bot.poll_end do
|
||||
end_channel.send nil
|
||||
end
|
||||
|
||||
Signal::INT.trap do
|
||||
logger.info "Shutting down bot..."
|
||||
bot.end_poll
|
||||
end
|
||||
|
||||
bot.poll
|
||||
end_channel.receive
|
||||
sleep
|
||||
|
|
|
@ -45,16 +45,3 @@ class RedditResponse
|
|||
.select { |it| yield it }
|
||||
end
|
||||
end
|
||||
|
||||
def filter_reddit_json(json, completed, extensions = ["png", "jpeg"])
|
||||
json.data.posts_matching do |post|
|
||||
extensions.any? { |it| post.url.ends_with? it } && !completed.includes? post.url
|
||||
end
|
||||
end
|
||||
|
||||
def get_reddit_post(subreddit, completed)
|
||||
return nil unless json = RedditResponse.from_subreddit subreddit
|
||||
return nil unless post = filter_reddit_json(json, completed).first?
|
||||
completed.push(post.name)
|
||||
return { post.url, post.title }
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue
Block a user