joann-pupper-bot/src/joann-pupper-bot.cr

113 lines
3.0 KiB
Crystal

require "./joann-pupper-bot/*"
require "logger"
require "telepathy"
require "time"
require "sqlite3"
require "cron_scheduler"
# Chat IDs
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)
class BotConfiguration
JSON.mapping(
subreddits: Array(String),
send_cron: String,
refresh_cron: String,
recepients: Array(Int64))
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
end
end
end
end
botc = PupperBot.new
sleep