ahoy_email 1.1.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,9 +9,15 @@ module AhoyEmail
9
9
  def perform
10
10
  Safely.safely do
11
11
  # perform_deliveries check still needed in observer
12
- if message.perform_deliveries && message.ahoy_data
13
- data = message.ahoy_data.merge(message: message)
14
- message.ahoy_message = AhoyEmail.track_method.call(data)
12
+ if message.perform_deliveries
13
+ if message.ahoy_data
14
+ data = message.ahoy_data.merge(message: message)
15
+ message.ahoy_message = AhoyEmail.track_method.call(data)
16
+ end
17
+
18
+ if message.ahoy_options && message.ahoy_options[:click]
19
+ Utils.publish(:send, message.ahoy_options.slice(:campaign))
20
+ end
15
21
  end
16
22
  end
17
23
  end
@@ -0,0 +1,35 @@
1
+ module AhoyEmail
2
+ class Utils
3
+ OPTION_KEYS = {
4
+ message: %i(message mailer user extra),
5
+ utm_params: %i(utm_source utm_medium utm_term utm_content utm_campaign),
6
+ click: %i(campaign url_options unsubscribe_links)
7
+ }
8
+
9
+ class << self
10
+ def signature(token:, campaign:, url:)
11
+ # encode and join with a character outside encoding
12
+ data = [token, campaign, url].map { |v| Base64.strict_encode64(v.to_s) }.join("|")
13
+
14
+ Base64.urlsafe_encode64(OpenSSL::HMAC.digest("SHA256", secret_token, data), padding: false)
15
+ end
16
+
17
+ def publish(name, event)
18
+ method_name = "track_#{name}"
19
+ AhoyEmail.subscribers.each do |subscriber|
20
+ subscriber = subscriber.new if subscriber.is_a?(Class)
21
+ if subscriber.respond_to?(method_name)
22
+ subscriber.send(method_name, event.dup)
23
+ elsif name == :click && subscriber.respond_to?(:click)
24
+ # legacy
25
+ subscriber.send(:click, event.dup)
26
+ end
27
+ end
28
+ end
29
+
30
+ def secret_token
31
+ AhoyEmail.secret_token || (raise "Secret token is empty")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module AhoyEmail
2
- VERSION = "1.1.1"
2
+ VERSION = "2.0.0"
3
3
  end
@@ -0,0 +1,40 @@
1
+ require "rails/generators/active_record"
2
+
3
+ module Ahoy
4
+ module Generators
5
+ module Messages
6
+ class ActiverecordGenerator < Rails::Generators::Base
7
+ include ActiveRecord::Generators::Migration
8
+ source_root File.join(__dir__, "templates")
9
+
10
+ class_option :unencrypted, type: :boolean
11
+
12
+ def copy_migration
13
+ migration_template "migration.rb", "db/migrate/create_ahoy_messages.rb", migration_version: migration_version
14
+ end
15
+
16
+ def copy_template
17
+ if encrypted?
18
+ template "model_encrypted.rb", "app/models/ahoy/message.rb"
19
+ end
20
+ end
21
+
22
+ def migration_version
23
+ "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
24
+ end
25
+
26
+ def to_column
27
+ if encrypted?
28
+ "t.text :to_ciphertext\n t.string :to_bidx, index: true"
29
+ else
30
+ "t.string :to, index: true"
31
+ end
32
+ end
33
+
34
+ def encrypted?
35
+ !options[:unencrypted]
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,21 @@
1
+ require "rails/generators"
2
+
3
+ module Ahoy
4
+ module Generators
5
+ module Messages
6
+ class MongoidGenerator < Rails::Generators::Base
7
+ source_root File.join(__dir__, "templates")
8
+
9
+ class_option :unencrypted, type: :boolean
10
+
11
+ def copy_templates
12
+ if options[:unencrypted]
13
+ template "mongoid.rb", "app/models/ahoy/message.rb"
14
+ else
15
+ template "mongoid_encrypted.rb", "app/models/ahoy/message.rb"
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,7 +2,7 @@ class <%= migration_class_name %> < ActiveRecord::Migration<%= migration_version
2
2
  def change
3
3
  create_table :ahoy_messages do |t|
4
4
  t.references :user, polymorphic: true
5
- t.text :to
5
+ <%= to_column %>
6
6
  t.string :mailer
7
7
  t.text :subject
8
8
  t.datetime :sent_at
@@ -0,0 +1,8 @@
1
+ class Ahoy::Message < ActiveRecord::Base
2
+ self.table_name = "ahoy_messages"
3
+
4
+ belongs_to :user, polymorphic: true, optional: true
5
+
6
+ encrypts :to
7
+ blind_index :to
8
+ end
@@ -0,0 +1,12 @@
1
+ class Ahoy::Message
2
+ include Mongoid::Document
3
+
4
+ belongs_to :user, polymorphic: true, optional: true, index: true
5
+
6
+ field :to, type: String
7
+ field :mailer, type: String
8
+ field :subject, type: String
9
+ field :sent_at, type: Time
10
+
11
+ index({to: 1})
12
+ end
@@ -0,0 +1,16 @@
1
+ class Ahoy::Message
2
+ include Mongoid::Document
3
+
4
+ belongs_to :user, polymorphic: true, optional: true, index: true
5
+
6
+ field :to_ciphertext, type: String
7
+ field :to_bidx, type: String
8
+ field :mailer, type: String
9
+ field :subject, type: String
10
+ field :sent_at, type: Time
11
+
12
+ index({to_bidx: 1})
13
+
14
+ encrypts :to
15
+ blind_index :to
16
+ end
@@ -0,0 +1,41 @@
1
+ require "rails/generators"
2
+
3
+ module Ahoy
4
+ module Generators
5
+ class MessagesGenerator < Rails::Generators::Base
6
+ source_root File.join(__dir__, "templates")
7
+
8
+ class_option :unencrypted, type: :boolean
9
+
10
+ def copy_templates
11
+ activerecord = defined?(ActiveRecord)
12
+ mongoid = defined?(Mongoid)
13
+
14
+ selection =
15
+ if activerecord && mongoid
16
+ puts <<-MSG
17
+
18
+ Which data store would you like to use?
19
+ 1. Active Record (default)
20
+ 2. Mongoid
21
+ MSG
22
+
23
+ ask(">")
24
+ elsif activerecord
25
+ "1"
26
+ else
27
+ "2"
28
+ end
29
+
30
+ case selection
31
+ when "", "1"
32
+ invoke "ahoy:messages:activerecord"
33
+ when "2"
34
+ invoke "ahoy:messages:mongoid"
35
+ else
36
+ abort "Error: must enter a number [1-2]"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ahoy_email
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Kane
@@ -66,90 +66,6 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: 0.1.1
69
- - !ruby/object:Gem::Dependency
70
- name: bundler
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: rake
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: minitest
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
- - !ruby/object:Gem::Dependency
112
- name: activerecord
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
- - !ruby/object:Gem::Dependency
126
- name: combustion
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - ">="
130
- - !ruby/object:Gem::Version
131
- version: '0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - ">="
137
- - !ruby/object:Gem::Version
138
- version: '0'
139
- - !ruby/object:Gem::Dependency
140
- name: sqlite3
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '0'
146
- type: :development
147
- prerelease: false
148
- version_requirements: !ruby/object:Gem::Requirement
149
- requirements:
150
- - - ">="
151
- - !ruby/object:Gem::Version
152
- version: '0'
153
69
  description:
154
70
  email: andrew@ankane.org
155
71
  executables: []
@@ -166,12 +82,20 @@ files:
166
82
  - lib/ahoy_email.rb
167
83
  - lib/ahoy_email/engine.rb
168
84
  - lib/ahoy_email/mailer.rb
85
+ - lib/ahoy_email/message_subscriber.rb
169
86
  - lib/ahoy_email/observer.rb
170
87
  - lib/ahoy_email/processor.rb
88
+ - lib/ahoy_email/redis_subscriber.rb
171
89
  - lib/ahoy_email/tracker.rb
90
+ - lib/ahoy_email/utils.rb
172
91
  - lib/ahoy_email/version.rb
173
- - lib/generators/ahoy_email/install_generator.rb
174
- - lib/generators/ahoy_email/templates/install.rb.tt
92
+ - lib/generators/ahoy/messages/activerecord_generator.rb
93
+ - lib/generators/ahoy/messages/mongoid_generator.rb
94
+ - lib/generators/ahoy/messages/templates/migration.rb.tt
95
+ - lib/generators/ahoy/messages/templates/model_encrypted.rb.tt
96
+ - lib/generators/ahoy/messages/templates/mongoid.rb.tt
97
+ - lib/generators/ahoy/messages/templates/mongoid_encrypted.rb.tt
98
+ - lib/generators/ahoy/messages_generator.rb
175
99
  homepage: https://github.com/ankane/ahoy_email
176
100
  licenses:
177
101
  - MIT
@@ -184,7 +108,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
184
108
  requirements:
185
109
  - - ">="
186
110
  - !ruby/object:Gem::Version
187
- version: '2.4'
111
+ version: '2.6'
188
112
  required_rubygems_version: !ruby/object:Gem::Requirement
189
113
  requirements:
190
114
  - - ">="
@@ -1,18 +0,0 @@
1
- require "rails/generators/active_record"
2
-
3
- module AhoyEmail
4
- module Generators
5
- class InstallGenerator < Rails::Generators::Base
6
- include ActiveRecord::Generators::Migration
7
- source_root File.join(__dir__, "templates")
8
-
9
- def copy_migration
10
- migration_template "install.rb", "db/migrate/create_ahoy_messages.rb", migration_version: migration_version
11
- end
12
-
13
- def migration_version
14
- "[#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}]"
15
- end
16
- end
17
- end
18
- end