Skip to content

Instantly share code, notes, and snippets.

@julik
Created March 11, 2025 12:39
Show Gist options
  • Save julik/a79665c2d441b426f01162f1f1c6ffd8 to your computer and use it in GitHub Desktop.
Save julik/a79665c2d441b426f01162f1f1c6ffd8 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'premailer'
gem 'nokogiri'
gem 'base64'
gem 'mail'
end
# Inline styles
premailer = Premailer.new($stdin, warn_level: Premailer::Warnings::SAFE)
Mail.defaults do
delivery_method :smtp,
address: "smtp.gmail.com",
port: 587,
user_name: "[email protected]",
authentication: "plain",
password: "right there"
end
def ingest_and_rewrite_images(html_string, into_mail_mime_part)
# Add an attachment as a multipart part, under the /related multipart part.
# Since it is related, these attachments will not show as downloadable attachments
# - but they will be usable within the same part!
# Once an image is attached to the part, we can get its URL (which uses a generated cid:)
# and replace the src in the HTML with that.
# https://stackoverflow.com/a/46468212/153886
noko_doc = Nokogiri::HTML(html_string)
noko_doc.css("img").map do |image_node|
image_relative_path = image_node["src"]
raise "Referenced image #{image_relative_path.inspect} not found" unless File.exist?(image_relative_path)
fn = File.basename(image_relative_path)
into_mail_mime_part.attachments[fn] = {filename: image_relative_path}
cid_url = into_mail_mime_part.attachments[fn].url
image_node["src"] = cid_url
end
noko_doc.to_html
end
mail = Mail.new
mail.part :content_type => "multipart/mixed" do |p1|
p1.part :content_type => "multipart/related" do |p2|
html_with_cids = ingest_and_rewrite_images(premailer.to_inline_css, p2)
p2.part :content_type => "multipart/alternative", :content_disposition => "inline" do |p3|
p3.part :content_type => "text/plain; charset=utf-8", :body => premailer.to_plain_text
p3.part :content_type => "text/html; charset=utf-8", :body => html_with_cids
end
end
end
mail.from "Julik <[email protected]>"
mail.to "[email protected]"
mail.subject "Musherator HTML test #{Time.now.strftime("%Y-%m-%d %H:%M")}"
test_email_filename = "test.eml"
File.open(test_email_filename, "wb") { |fo| fo.write(mail.to_s) }
`open #{test_email_filename}` # Mail.app opens .emls
#mail.deliver!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment