commit f52cfe1117633bb7d533c1257b9cf96d007d0937 Author: Guido Schweizer Date: Sat Mar 1 10:01:07 2025 +0100 init diff --git a/.env.template b/.env.template new file mode 100644 index 0000000..23e0734 --- /dev/null +++ b/.env.template @@ -0,0 +1,13 @@ + +DB_USER= +DB_PASSWORD= +DB_HOST= +DB_PORT= +DB_NAME= + +SMTP_SERVER= +SMTP_PORT= +SMTP_USERNAME= +SMTP_PASSWORD= + +HUGGINGFACE_API_TOKEN= diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..7437a51 --- /dev/null +++ b/Gemfile @@ -0,0 +1,7 @@ +source 'https://rubygems.org' + +gem 'pg' +gem 'net-smtp' +gem 'httparty' +gem 'dotenv' +gem 'erb' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..be0a88a --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,36 @@ +GEM + remote: https://rubygems.org/ + specs: + bigdecimal (3.1.9) + cgi (0.4.2) + csv (3.3.2) + dotenv (3.1.7) + erb (4.0.4) + cgi (>= 0.3.3) + httparty (0.22.0) + csv + mini_mime (>= 1.0.0) + multi_xml (>= 0.5.2) + mini_mime (1.1.5) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + pg (1.5.9) + timeout (0.4.3) + +PLATFORMS + arm64-darwin-24 + ruby + +DEPENDENCIES + dotenv + erb + httparty + net-smtp + pg + +BUNDLED WITH + 2.6.2 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/mailer.rb b/mailer.rb new file mode 100644 index 0000000..413337e --- /dev/null +++ b/mailer.rb @@ -0,0 +1,114 @@ +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_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 = 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 diff --git a/template/mail.html.erb b/template/mail.html.erb new file mode 100644 index 0000000..6474869 --- /dev/null +++ b/template/mail.html.erb @@ -0,0 +1,38 @@ + + + + + + Weekly listening report <%= Date.today.to_s %> + + + +
+
Your listening report for <%= Date.today.to_s %>
+
+

Heyo!

+

Total plays <%= total_plays %>

+

<%= body %>

+ Listen Now +
+ +
+ + \ No newline at end of file