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('DATABASE_URL', nil) DB_USER = ENV.fetch('DB_USER', nil) DB_PASSWORD = ENV.fetch('DB_PASSWORD', nil) DB_HOST = ENV.fetch('DB_HOST', nil) DB_PORT = ENV.fetch('DB_PORT', nil) DB_NAME = ENV.fetch('DB_NAME', nil) 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() raise "Please set either DATABASE_URL or DB_USER..." if DB_USER.nil? && DB_URL.nil? one_week_ago = Date.today - 7 connection = !DB_URL.nil? ? 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