Skip to content

Commit b659d2e

Browse files
committed
Add migration and model for EmailAttempt
1 parent 4eb1b6b commit b659d2e

File tree

3 files changed

+151
-1
lines changed

3 files changed

+151
-1
lines changed

app/models/email_attempt.rb

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# == Schema Information
2+
#
3+
# Table name: email_attempts
4+
#
5+
# id :uuid not null, primary key
6+
# bcc :string
7+
# cc :string
8+
# created_by_type :string
9+
# delivered :boolean
10+
# from :string
11+
# postmark_stream :string
12+
# postmark_template_alias :string
13+
# postmark_template_model :jsonb
14+
# provider :integer
15+
# reply_to :string
16+
# response_body :jsonb
17+
# response_status :integer
18+
# to :string
19+
# created_at :datetime not null
20+
# updated_at :datetime not null
21+
# created_by_id :uuid
22+
#
23+
# Indexes
24+
#
25+
# index_email_attempts_on_created_by (created_by_type,created_by_id)
26+
# index_email_attempts_on_response_body (response_body) USING gin
27+
#
28+
class EmailAttempt < ApplicationRecord
29+
# The record which created this EmailAttempt
30+
belongs_to :created_by, polymorphic: true, optional: true
31+
32+
# The provider which will send the email for us.
33+
# Rails cannot send emails. It only delegates them.
34+
# enum :provider, { postmark: 0, sendgrid: 1 }, scopes: true
35+
36+
after_save :send_email
37+
38+
private
39+
40+
def blocker
41+
return 'no to' if to.nil?
42+
return 'no from' if from.nil?
43+
return 'no postmark_stream' if postmark_stream.nil?
44+
return 'no postmark_template_alias' if postmark_template_alias.nil?
45+
return 'no postmark_template_model' if postmark_template_model.nil?
46+
return 'model is not a hash' unless postmark_template_model.is_a? Hash
47+
48+
# Never deliver an email twice
49+
# This also allows admins to edit and retry until delivered
50+
return 'already delivered' if delivered == true
51+
52+
nil
53+
end
54+
55+
def send_email
56+
log.info "✅ saved EmailAttempt #{id}"
57+
58+
if blocker.present?
59+
log.warn "🔥 #{blocker}"
60+
return
61+
end
62+
63+
log.info '✅ sending ...'
64+
65+
ap from
66+
ap to
67+
ap postmark_template_alias
68+
ap postmark_template_model
69+
70+
api = Postmark::Api.new(server_token: ENV['POSTMARK_SERVER_TOKEN'])
71+
72+
response = api.send_email_with_template(
73+
message_stream: postmark_stream,
74+
template_alias: postmark_template_alias,
75+
template_model: postmark_template_model,
76+
from: from,
77+
to: to,
78+
cc: cc,
79+
bcc: bcc,
80+
reply_to: reply_to
81+
)
82+
83+
if response.status == 200
84+
log.info '✅ success'
85+
else
86+
log.info '❌ fail'
87+
end
88+
89+
ap response.status
90+
ap response.body
91+
92+
self.response_status = response.status
93+
self.response_body = JSON.parse(response.body) if response.body.present?
94+
self.delivered = response.status == 200
95+
96+
save!
97+
98+
log.info '✅ done'
99+
end
100+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
class CreateEmailAttempt < ActiveRecord::Migration[6.1]
2+
def change
3+
create_table :email_attempts, id: :uuid do |t|
4+
t.references :created_by, polymorphic: true, type: :uuid
5+
6+
t.string :from
7+
t.string :to
8+
t.string :cc
9+
t.string :bcc
10+
t.string :reply_to
11+
12+
t.integer :provider
13+
14+
t.string :postmark_stream
15+
t.string :postmark_template_alias
16+
t.jsonb :postmark_template_model, default: {}
17+
18+
# When storing JSONB
19+
# https://dev.to/kputra/rails-postgresql-jsonb-part-1-4ibg
20+
t.jsonb :response_body, default: {}
21+
t.integer :response_status
22+
t.boolean :delivered
23+
24+
t.timestamps
25+
end
26+
27+
add_index :email_attempts, :response_body, using: :gin
28+
end
29+
end

db/schema.rb

+22-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema.define(version: 2024_04_07_010227) do
13+
ActiveRecord::Schema.define(version: 2024_04_18_113914) do
1414

1515
# These are extensions that must be enabled in order to support this database
1616
enable_extension "pgcrypto"
@@ -214,6 +214,27 @@
214214
t.boolean "public", default: false
215215
end
216216

217+
create_table "email_attempts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
218+
t.string "created_by_type"
219+
t.uuid "created_by_id"
220+
t.string "from"
221+
t.string "to"
222+
t.string "cc"
223+
t.string "bcc"
224+
t.string "reply_to"
225+
t.integer "provider"
226+
t.string "postmark_stream"
227+
t.string "postmark_template_alias"
228+
t.jsonb "postmark_template_model", default: {}
229+
t.jsonb "response_body", default: {}
230+
t.integer "response_status"
231+
t.boolean "delivered"
232+
t.datetime "created_at", precision: 6, null: false
233+
t.datetime "updated_at", precision: 6, null: false
234+
t.index ["created_by_type", "created_by_id"], name: "index_email_attempts_on_created_by"
235+
t.index ["response_body"], name: "index_email_attempts_on_response_body", using: :gin
236+
end
237+
217238
create_table "employees", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
218239
t.uuid "company_id"
219240
t.uuid "person_id"

0 commit comments

Comments
 (0)