gogogibbon 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 67f93827920932b5384a0fd9554480650fcdeed698343cb2c022140992276f9d
4
+ data.tar.gz: 451d17a1a97d08e88fc44dd6c8f69edf9d9a372c322e536a3edf2501b05fe66b
5
+ SHA512:
6
+ metadata.gz: 6be359084aa1139bcc02d071bf68017a50132dfc025e054abda77cca37558c56b401c3a7ee9043c48e257225b7c22134b7de8811aa4c4ea0d60ebe62d7125ba7
7
+ data.tar.gz: f4465841d537ac0b149f4e7bc3dc18e58ec1486b6b31317d69e8d4db67fe1d62af11b649c7eadf1442cd64d15b45bb994645438c481940a7233c802483043981
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../lib/gogogibbon/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'gogogibbon'
5
+ s.version = GoGoGibbon::VERSION
6
+ s.summary = 'Useful helpers for Gibbon'
7
+ s.description = 'A wrapper for Gibbon containing useful helper methods.'
8
+ s.authors = ['GoGoCarl']
9
+ s.email = 'carl.scott@solertium.com'
10
+ s.files = Dir['lib/**/*'] + Dir['*.rb'] + ["gogogibbon.gemspec"]
11
+ s.require_paths = ["lib"]
12
+ s.homepage = 'http://github.com/GoGoCarl/gogogibbon'
13
+
14
+ s.add_dependency 'gibbon', '~> 2.2'
15
+ end
@@ -0,0 +1,42 @@
1
+ module GoGoGibbon
2
+
3
+ class Callbacks
4
+
5
+ def initialize opts={}
6
+ @options = { :thread => false }
7
+ @options.merge! opts
8
+ end
9
+
10
+ def after_create record
11
+ run do
12
+ GoGoGibbon.subscribe record
13
+ end
14
+ end
15
+
16
+ def after_update record
17
+ if record.email_changed? || record.first_name_changed? || record.last_name_changed?
18
+ run do
19
+ GoGoGibbon.update_subscription record.email_was, record
20
+ end
21
+ end
22
+ end
23
+
24
+ def after_destroy record
25
+ run do
26
+ GoGoGibbon.cancel_user record
27
+ end
28
+ end
29
+
30
+ def run &block
31
+ if @options[:thread] == true
32
+ Thread.new do
33
+ yield
34
+ end
35
+ else
36
+ yield
37
+ end
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,173 @@
1
+ require 'gibbon'
2
+
3
+ module GoGoGibbon
4
+ module Commands
5
+ class << self
6
+ # Store a hash of list name to ID
7
+ LIST_CACHE = {}
8
+
9
+ #
10
+ # Subscribe to the subscription list
11
+ #
12
+ def subscribe user, list_name=sub_list
13
+ result = false
14
+ sub_id = list list_name
15
+ unless sub_id.nil?
16
+ begin
17
+ body = {
18
+ 'email_address' => user.email,
19
+ 'status' => 'subscribed',
20
+ 'merge_fields' => { 'FNAME' => user.first_name, 'LNAME' => user.last_name }
21
+ }
22
+ result = chimp.lists(sub_id).members.create(body: body)
23
+ rescue Gibbon::MailChimpError => e
24
+ raise e unless e.body['status'] == 400 && e.body['title'] == 'Member Exists'
25
+ end
26
+ end
27
+ result
28
+ end
29
+
30
+ def subscribe_set users, list_name=sub_list
31
+ result = false
32
+
33
+ sub_id = list list_name
34
+ unless sub_id.nil?
35
+ batch = []
36
+
37
+ defaults = { 'method' => 'POST', 'path' => "lists/#{sub_id}/members" }
38
+ handler = lambda do |user|
39
+ batch << defaults.merge("body" => {
40
+ 'email_address' => user.email, 'status' => 'subscribed',
41
+ 'merge_fields' => { 'FNAME' => user.first_name, 'LNAME' => user.last_name }
42
+ }.to_json)
43
+ end
44
+
45
+ if users.respond_to? :find_each
46
+ users.find_each { |user| handler.call(user) }
47
+ else
48
+ users.each { |user| handler.call(user) }
49
+ end
50
+
51
+ body = { "operations" => batch }
52
+
53
+ result = chimp.batches.create(body: body)
54
+ batch_id = result['id']
55
+ attempts = 1, backoff = 2
56
+ while result['status'] != 'finished' && attempts <= 10
57
+ sleep attempts * backoff
58
+ result = chimp.batches(batch_id).retrieve
59
+ attempts += 1
60
+ end
61
+
62
+ if result['status'] == 'finished'
63
+ result = {
64
+ 'add_count' => result['finished_operations'],
65
+ 'update_count' => 0,
66
+ 'error_count' => result['errored_operations'],
67
+ 'total_count' => result['total_operations'],
68
+ 'errors' => []
69
+ }
70
+
71
+ else
72
+ result = false
73
+ end
74
+
75
+ end
76
+ result
77
+ end
78
+
79
+ def unsubscribe user, list_name=unsub_list
80
+ result = false
81
+
82
+ sub_id = list list_name
83
+ unless sub_id.nil?
84
+ begin
85
+ result = chimp.lists(sub_id).members(user_id(user.email)).delete
86
+ rescue Gibbon::MailChimpError => e
87
+ if e.body['status'] == 404
88
+ return true
89
+ else
90
+ raise e
91
+ end
92
+ end
93
+ end
94
+ result.nil?
95
+ end
96
+
97
+ #
98
+ # Unsubscribe from the subscription list,
99
+ # subscribe to the unsubscription list.
100
+ #
101
+ def cancel_user user
102
+ result = false
103
+ unsubscribe user, sub_list
104
+ result = subscribe user, unsub_list
105
+ result
106
+ end
107
+
108
+ def list list_name
109
+ return LIST_CACHE[list_name] if LIST_CACHE.key?(list_name)
110
+ items = lists
111
+ list = nil
112
+ if items
113
+ p = items.select { |i| i['name'] == list_name }
114
+ if p.any?
115
+ list = p.first['id']
116
+ end
117
+ end
118
+ list
119
+ end
120
+
121
+ def update_subscription old_email, user, list_name=sub_list
122
+ result = false
123
+
124
+ sub_id = list list_name
125
+ unless sub_id.nil?
126
+ if old_email != user.email
127
+ unsubscribe Struct.new(:email).new(old_email), list_name
128
+ end
129
+
130
+ body = {
131
+ 'email_address' => user.email, 'status' => 'subscribed',
132
+ 'merge_fields' => { 'FNAME' => user.first_name, 'LNAME' => user.last_name }
133
+ }
134
+
135
+ result = chimp.lists(sub_id).members(user_id(user.email)).upsert(body: body)
136
+ end
137
+ result
138
+ end
139
+
140
+ def lists
141
+ result = nil
142
+ begin
143
+ result = chimp.lists.retrieve(params: { "count" => 100, "fields" => "lists.id,lists.name" })["lists"]
144
+ result.each do |item|
145
+ LIST_CACHE[item['name']] = item['id']
146
+ end
147
+ rescue Gibbon::MailChimpError => e
148
+ puts e.detail
149
+ raise e unless e.body['status'] == 200
150
+ end
151
+ result
152
+ end
153
+
154
+ def chimp
155
+ GoGoGibbon::Config.chimp
156
+ end
157
+
158
+ def sub_list
159
+ GoGoGibbon::Config.subscribed
160
+ end
161
+
162
+ def unsub_list
163
+ GoGoGibbon::Config.unsubscribed
164
+ end
165
+
166
+ private
167
+
168
+ def user_id email
169
+ Digest::MD5.new.update(email.downcase).hexdigest
170
+ end
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,28 @@
1
+ require 'gibbon'
2
+
3
+ module GoGoGibbon
4
+ class Config
5
+ class << self
6
+
7
+ attr_accessor :subscribed, :unsubscribed, :api_key, :chimp, :errors, :on_fail
8
+
9
+ def api_key=(value)
10
+ @chimp = Gibbon::Request.new api_key: value
11
+ @api_key = value
12
+ end
13
+
14
+ def configured?
15
+ !(@api_key.nil? || @subscribed.nil?)
16
+ end
17
+
18
+ def fail!
19
+ msg = 'MailChimp Configuration not complete. Please specify an api_key and subscription list.'
20
+ if @on_fail == :error
21
+ raise Exception.new msg
22
+ else
23
+ puts msg unless @on_fail == :silent
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,48 @@
1
+ module GoGoGibbon
2
+ module Methods
3
+
4
+ def self.included base
5
+ base.send :extend, ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ #
10
+ # Options map can contain the following:
11
+ # * :thread -- true to run in a new thread, false otherwise (default false)
12
+ #
13
+
14
+ #
15
+ # When a user is created, subscribe that user to the mailing list
16
+ #
17
+ def mailchimp_on_create opts={}
18
+ after_create GoGoGibbon::Callbacks.new opts
19
+ end
20
+
21
+ #
22
+ # When a user is updated, update their profile, if necessary
23
+ #
24
+ def mailchimp_on_update opts={}
25
+ after_update GoGoGibbon::Callbacks.new opts
26
+ end
27
+
28
+ #
29
+ # When a user is deleted, cancel that user.
30
+ #
31
+ def mailchimp_on_destroy opts={}
32
+ after_destroy GoGoGibbon::Callbacks.new opts
33
+ end
34
+
35
+ #
36
+ # Return a list of users eligible to receive mail. Defaults to this class,
37
+ # but can return anything relation
38
+ #
39
+ def Mailable
40
+ self
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+
48
+ ActiveRecord::Base.send :include, GoGoGibbon::Methods
@@ -0,0 +1,3 @@
1
+ module GoGoGibbon
2
+ VERSION = '2.0.0'
3
+ end
data/lib/gogogibbon.rb ADDED
@@ -0,0 +1,59 @@
1
+ require 'gogogibbon/commands'
2
+ require 'gogogibbon/config'
3
+ require 'gogogibbon/version'
4
+ require 'gogogibbon/callbacks'
5
+ require 'gogogibbon/methods'
6
+
7
+ module GoGoGibbon
8
+ class << self
9
+
10
+ #
11
+ # Add a new user to the MailChimp subscription list
12
+ #
13
+ def subscribe user
14
+ execute { GoGoGibbon::Commands.subscribe user }
15
+ end
16
+
17
+ #
18
+ # Remove the user from the MailChimp subscription list. If there is
19
+ # a cancellation list configured, they will be subscribed to that.
20
+ #
21
+ def cancel_user user
22
+ execute { GoGoGibbon::Commands.cancel_user user }
23
+ end
24
+
25
+ #
26
+ # Update a user subscription given a user with the properties
27
+ # email, first_name, and last_name. You can always pass a struct
28
+ # with these properties if your user object has these fields named
29
+ # differently.
30
+ #
31
+ def update_subscription old_email, user
32
+ execute { GoGoGibbon::Commands.update_subscription old_email, user }
33
+ end
34
+
35
+ def execute &block
36
+ return unless ready?
37
+ yield
38
+ rescue Exception => e
39
+ if GoGoGibbon::Config.errors = :throw
40
+ raise e
41
+ else
42
+ return false
43
+ end
44
+ end
45
+
46
+ #
47
+ # Returns true if Gibbon has enough information to run, false otherwise.
48
+ # API Key and subscription list are minimally required.
49
+ #
50
+ def ready?
51
+ result = GoGoGibbon::Config.configured?
52
+ unless result
53
+ GoGoGibbon::Config.fail!
54
+ end
55
+ result
56
+ end
57
+
58
+ end
59
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gogogibbon
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - GoGoCarl
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-03-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gibbon
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.2'
27
+ description: A wrapper for Gibbon containing useful helper methods.
28
+ email: carl.scott@solertium.com
29
+ executables: []
30
+ extensions: []
31
+ extra_rdoc_files: []
32
+ files:
33
+ - gogogibbon.gemspec
34
+ - lib/gogogibbon.rb
35
+ - lib/gogogibbon/callbacks.rb
36
+ - lib/gogogibbon/commands.rb
37
+ - lib/gogogibbon/config.rb
38
+ - lib/gogogibbon/methods.rb
39
+ - lib/gogogibbon/version.rb
40
+ homepage: http://github.com/GoGoCarl/gogogibbon
41
+ licenses: []
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.7.6
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Useful helpers for Gibbon
63
+ test_files: []