From c4f0c512263bda30d421f602328ca5ddf50f712a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Lecour?= Date: Wed, 28 Oct 2020 23:53:42 +0100 Subject: [PATCH] play with mail processing --- Gemfile | 1 + Gemfile.lock | 5 ++ app/mailboxes/in_mailbox.rb | 68 ++++++++++++++++++++++ app/models/email.rb | 2 + db/migrate/20201017104739_create_emails.rb | 20 +++++++ db/schema.rb | 20 ++++++- test/fixtures/emails.yml | 11 ++++ test/models/email_test.rb | 7 +++ 8 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 app/models/email.rb create mode 100644 db/migrate/20201017104739_create_emails.rb create mode 100644 test/fixtures/emails.yml create mode 100644 test/models/email_test.rb diff --git a/Gemfile b/Gemfile index e4443a4..d20d619 100644 --- a/Gemfile +++ b/Gemfile @@ -31,6 +31,7 @@ gem 'bootsnap', '>= 1.4.2', require: false group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] + gem 'pry' end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index dc657fa..5fb5756 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,6 +72,7 @@ GEM regexp_parser (~> 1.5) xpath (~> 3.2) childprocess (3.0.0) + coderay (1.1.3) concurrent-ruby (1.1.7) crass (1.0.6) erubi (1.9.0) @@ -101,6 +102,9 @@ GEM nio4r (2.5.4) nokogiri (1.10.10) mini_portile2 (~> 2.4.0) + pry (0.13.1) + coderay (~> 1.1) + method_source (~> 1.0) public_suffix (4.0.6) puma (4.3.6) nio4r (~> 2.0) @@ -203,6 +207,7 @@ DEPENDENCIES capybara (>= 2.15) jbuilder (~> 2.7) listen (~> 3.2) + pry puma (~> 4.1) rails (~> 6.0.3, >= 6.0.3.4) sass-rails (>= 6) diff --git a/app/mailboxes/in_mailbox.rb b/app/mailboxes/in_mailbox.rb index 987c2ed..8c4aaad 100644 --- a/app/mailboxes/in_mailbox.rb +++ b/app/mailboxes/in_mailbox.rb @@ -1,4 +1,72 @@ class InMailbox < ApplicationMailbox def process + binding.pry + + # email = Email.new( + # message_id: mail.message_id, + # subject: mail.subject, + # date: mail.date, + # to: mail.to, + # from: mail.from, + # plain_body: text_plain_body(mail), + # raw_headers: mail.header.raw_source, + # cron: sent_by_cron?(mail), + # mailing_list: mailing_list?(mail), + # clients: clients(mail), + # servers: servers(mail), + # tickets: tickets(mail) + # ) + # + # binding.pry + end + + def text_plain_body(mail) + if mail.parts.present? + mail.parts.detect(-> { mail.parts[0] }) { |part| + part.content_type =~ /text\/plain/ + }.body.decoded + else + mail.decoded + end + end + + def sent_by_cron?(mail) + mail.subject.match?(/cron/i) \ + || mail.header["X-Cron-Env"].present? + end + def mailing_list?(mail) + mail.header["List-Unsubscribe"].present? + end + + def clients(mail) + if mail.header["X-Client-ID"].present? + mail.header["X-Client-ID"].value + end + end + + def servers(mail) + if mail.header["X-Server-Name"].present? + mail.header["X-Server-Name"].value + else + matching_header = ["To", "Delivered-To", "From", "Subject"].detect { |header_name| + address_match_evolix_net?(mail.header[header_name].value) + } + extract_server_name_from_address(mail.header[matching_header].value) if matching_header + end + end + + def tickets(mail) + if mail.header["X-Ticket-ID"].present? + mail.header["X-Ticket-ID"].value + end + end + + def address_match_evolix_net?(address) + address.match?(/@(.+)\.evolix\.net/i) + end + def extract_server_name_from_address(address) + address.match(/@(.+)\.evolix\.net/i)[1] + end + end diff --git a/app/models/email.rb b/app/models/email.rb new file mode 100644 index 0000000..822e8dc --- /dev/null +++ b/app/models/email.rb @@ -0,0 +1,2 @@ +class Email < ApplicationRecord +end diff --git a/db/migrate/20201017104739_create_emails.rb b/db/migrate/20201017104739_create_emails.rb new file mode 100644 index 0000000..66f4e6d --- /dev/null +++ b/db/migrate/20201017104739_create_emails.rb @@ -0,0 +1,20 @@ +class CreateEmails < ActiveRecord::Migration[6.0] + def change + create_table :emails do |t| + t.string :message_id + t.string :subject + t.datetime :date + t.string :to + t.string :delivered_to + t.string :from + t.text :plain_body + t.text :raw_headers + t.boolean :cron + t.boolean :mailing_list + t.string :clients + t.string :servers + t.string :tickets + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 55ff3df..09b5cff 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_10_17_101818) do +ActiveRecord::Schema.define(version: 2020_10_17_104739) do create_table "action_mailbox_inbound_emails", force: :cascade do |t| t.integer "status", default: 0, null: false @@ -42,5 +42,23 @@ ActiveRecord::Schema.define(version: 2020_10_17_101818) do t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end + create_table "emails", force: :cascade do |t| + t.string "message_id" + t.string "subject" + t.datetime "date" + t.string "to" + t.string "delivered_to" + t.string "from" + t.text "plain_body" + t.text "raw_headers" + t.boolean "cron" + t.boolean "mailing_list" + t.string "clients" + t.string "servers" + t.string "tickets" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" end diff --git a/test/fixtures/emails.yml b/test/fixtures/emails.yml new file mode 100644 index 0000000..5181636 --- /dev/null +++ b/test/fixtures/emails.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the '{}' from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/models/email_test.rb b/test/models/email_test.rb new file mode 100644 index 0000000..dc054e5 --- /dev/null +++ b/test/models/email_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class EmailTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end