1activity-mailer/mailer.rb

117 lines
3.2 KiB
Ruby

require 'bundler'
Bundler.require(:default)
require 'pg'
require 'net/smtp'
require 'httparty'
require 'json'
require 'dotenv'
require 'erb'
require 'date'
require 'tempfile'
# Load environment variables from.env file
Dotenv.load
DB_URL = ENV.fetch('DB_URL')
DB_USER = ENV.fetch('DB_USER')
DB_PASSWORD = ENV.fetch('DB_PASSWORD')
DB_HOST = ENV.fetch('DB_HOST')
DB_PORT = ENV.fetch('DB_PORT')
DB_NAME = ENV.fetch('DB_NAME')
SMTP_SERVER = ENV.fetch('SMTP_SERVER')
SMTP_PORT = ENV.fetch('SMTP_PORT').to_i
SMTP_USERNAME = ENV.fetch('SMTP_USERNAME')
SMTP_PASSWORD = ENV.fetch('SMTP_PASSWORD')
HUGGINGFACE_API_URL = 'https://router.huggingface.co/hf-inference/models/mistralai/Mixtral-8x7B-Instruct-v0.1/v1/chat/completions'
HUGGINGFACE_API_TOKEN = ENV.fetch('HUGGINGFACE_API_TOKEN')
MAIL_BODY_PROMPT = <<-END
Analyze my recent weeks listening history and suggest a movie/comic character or celebrity that embodies the mood and spirit of my diverse music choices. Please keep the response concise and engaging, suitable for a marketing email.
Here are the titles that were listened to this week
END
def fetch_titles_from_db()
one_week_ago = Date.today - 7
connection = DB_URL ? PG.connect(DB_URL) : PG.connect(:dbname => DB_NAME, :host => DB_HOST, :user => DB_USER, :password => DB_PASSWORD)
result = connection.exec_params("SELECT item_title FROM activities WHERE created_at >= $1 ORDER BY created_at DESC", [one_week_ago])
connection.close
results = []
results = result.map { |row| row['item_title']} if result.any?
return results
end
def generate_email_body(titles)
return "You didnt listen to any music this week :`(" unless titles
puts "Calling HF"
body = mistral_request_body(titles)
response = HTTParty.post(HUGGINGFACE_API_URL, headers: { 'Content-Type':'application/json','Authorization' => "Bearer #{HUGGINGFACE_API_TOKEN}" }, body: body)
JSON.parse(response.body)['choices'][0]['message']['content']
end
def mistral_request_body(titles)
formated_titles = titles.join(", ")
{
model: "mistralai/Mixtral-8x7B-Instruct-v0.1",
messages: [
{
role: "user",
content: "#{MAIL_BODY_PROMPT} #{formated_titles}"
}
],
max_tokens: 1000,
stream: false
}.to_json
end
def send_email(to, subject, body)
current_time = Time.now.utc
formatted_time = current_time.strftime("%a, %-d %b %Y %H:%M:%S %z")
msg = <<-END
Subject: #{subject}
From: Weekly 1activity <#{SMTP_USERNAME}>
To: #{to}
Date: #{formatted_time}
MIME-Version: 1.0
Content-Type: text/html; charset=utf-8
#{body}
END
smtp = Net::SMTP.new(SMTP_SERVER, SMTP_PORT)
smtp.enable_starttls_auto
smtp.start do |server|
a = server.authenticate(SMTP_USERNAME, SMTP_PASSWORD)
puts a.string
begin
a= server.send_message(msg, SMTP_USERNAME, to)
puts a.string
rescue Net::SMTPFatalError => e
puts e.message
end
end
end
def main
titles = fetch_titles_from_db
total_plays = titles.length
body = generate_email_body(titles)
puts "HF done"
template = ERB.new File.read('./template/mail.html.erb')
html_body = template.result_with_hash({body: body, total_plays: total_plays})
title = "Weekly listening report #{Date.today}"
send_email("listening@sgui.de", title, html_body)
puts "Email sent with subject: #{title}"
end
main