express_pigeon 1.0.4 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (96) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +1 -0
  3. data/.gitignore +19 -16
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +17 -0
  6. data/.rubocop_todo.yml +15 -0
  7. data/.ruby-gemset +1 -0
  8. data/.ruby-version +1 -0
  9. data/CONTRIBUTING.md +21 -0
  10. data/Gemfile +13 -8
  11. data/Guardfile +56 -0
  12. data/LICENSE +9 -2
  13. data/README.md +4 -124
  14. data/Rakefile +1 -2
  15. data/express_pigeon.gemspec +31 -16
  16. data/lib/express_pigeon/api/campaigns.rb +62 -0
  17. data/lib/express_pigeon/api/contacts.rb +42 -0
  18. data/lib/express_pigeon/api/lists.rb +49 -0
  19. data/lib/express_pigeon/api/messages.rb +56 -0
  20. data/lib/express_pigeon/api.rb +66 -0
  21. data/lib/express_pigeon/autoresponders.rb +0 -0
  22. data/lib/express_pigeon/contacts.rb +71 -0
  23. data/lib/express_pigeon/lists.rb +111 -0
  24. data/lib/express_pigeon/meta_hash.rb +20 -0
  25. data/lib/express_pigeon/templates.rb +4 -0
  26. data/lib/express_pigeon/transactional_emails.rb +4 -0
  27. data/lib/express_pigeon/version.rb +1 -1
  28. data/lib/express_pigeon.rb +16 -442
  29. data/spec/express_pigeon/api/campaigns_spec.rb +100 -0
  30. data/spec/express_pigeon/api/contacts_spec.rb +146 -0
  31. data/spec/express_pigeon/api/lists_spec.rb +23 -0
  32. data/spec/express_pigeon/api/messages_spec.rb +36 -0
  33. data/spec/express_pigeon/contacts_spec.rb +111 -0
  34. data/spec/express_pigeon/lists_spec.rb +131 -0
  35. data/spec/fixtures/contacts.csv +2 -0
  36. data/spec/fixtures/contacts.csv.zip +0 -0
  37. data/spec/spec_helper.rb +100 -12
  38. data/vendor/cache/ast-2.0.0.gem +0 -0
  39. data/vendor/cache/astrolabe-1.3.0.gem +0 -0
  40. data/vendor/cache/awesome_print-1.2.0.gem +0 -0
  41. data/vendor/cache/byebug-3.5.1.gem +0 -0
  42. data/vendor/cache/celluloid-0.16.0.gem +0 -0
  43. data/vendor/cache/coderay-1.1.0.gem +0 -0
  44. data/vendor/cache/colorize-0.7.5.gem +0 -0
  45. data/vendor/cache/columnize-0.9.0.gem +0 -0
  46. data/vendor/cache/debugger-linecache-1.2.0.gem +0 -0
  47. data/vendor/cache/diff-lcs-1.2.5.gem +0 -0
  48. data/vendor/cache/docile-1.1.5.gem +0 -0
  49. data/vendor/cache/dotenv-1.0.2.gem +0 -0
  50. data/vendor/cache/ffi-1.9.6.gem +0 -0
  51. data/vendor/cache/formatador-0.2.5.gem +0 -0
  52. data/vendor/cache/guard-2.10.5.gem +0 -0
  53. data/vendor/cache/guard-compat-1.2.0.gem +0 -0
  54. data/vendor/cache/guard-rspec-4.5.0.gem +0 -0
  55. data/vendor/cache/hitimes-1.2.2.gem +0 -0
  56. data/vendor/cache/httmultiparty-0.3.16.gem +0 -0
  57. data/vendor/cache/httparty-0.13.3.gem +0 -0
  58. data/vendor/cache/json-1.8.1.gem +0 -0
  59. data/vendor/cache/listen-2.8.4.gem +0 -0
  60. data/vendor/cache/lumberjack-1.0.9.gem +0 -0
  61. data/vendor/cache/method_source-0.8.2.gem +0 -0
  62. data/vendor/cache/mimemagic-0.2.1.gem +0 -0
  63. data/vendor/cache/multi_json-1.10.1.gem +0 -0
  64. data/vendor/cache/multi_xml-0.5.5.gem +0 -0
  65. data/vendor/cache/multipart-post-2.0.0.gem +0 -0
  66. data/vendor/cache/nenv-0.1.1.gem +0 -0
  67. data/vendor/cache/parser-2.2.0.pre.8.gem +0 -0
  68. data/vendor/cache/powerpack-0.0.9.gem +0 -0
  69. data/vendor/cache/pry-0.10.1.gem +0 -0
  70. data/vendor/cache/pry-byebug-2.0.0.gem +0 -0
  71. data/vendor/cache/rainbow-2.0.0.gem +0 -0
  72. data/vendor/cache/rake-10.4.2.gem +0 -0
  73. data/vendor/cache/rb-fsevent-0.9.4.gem +0 -0
  74. data/vendor/cache/rb-inotify-0.9.5.gem +0 -0
  75. data/vendor/cache/rspec-3.1.0.gem +0 -0
  76. data/vendor/cache/rspec-core-3.1.7.gem +0 -0
  77. data/vendor/cache/rspec-expectations-3.1.2.gem +0 -0
  78. data/vendor/cache/rspec-mocks-3.1.3.gem +0 -0
  79. data/vendor/cache/rspec-support-3.1.2.gem +0 -0
  80. data/vendor/cache/rubocop-0.28.0.gem +0 -0
  81. data/vendor/cache/ruby-progressbar-1.7.1.gem +0 -0
  82. data/vendor/cache/simplecov-0.9.1.gem +0 -0
  83. data/vendor/cache/simplecov-html-0.8.0.gem +0 -0
  84. data/vendor/cache/slop-3.6.0.gem +0 -0
  85. data/vendor/cache/thor-0.19.1.gem +0 -0
  86. data/vendor/cache/timers-4.0.1.gem +0 -0
  87. metadata +183 -53
  88. data/.rvmrc +0 -52
  89. data/.travis.yml +0 -8
  90. data/CHANGELOG +0 -6
  91. data/bin/console +0 -12
  92. data/express_pigeon-rb.yml +0 -10
  93. data/lib/active_model/validations/date_format_validator.rb +0 -20
  94. data/script/lint +0 -6
  95. data/script/multispec +0 -23
  96. data/spec/web_forms_spec.rb +0 -164
@@ -0,0 +1,66 @@
1
+ # require_relative 'api/campaign'
2
+ # require_relative 'api/contact'
3
+ # require_relative 'api/list'
4
+ # require_relative 'api/message'
5
+ #
6
+ # module ExpressPigeon
7
+ # module API
8
+ # def http(path, method, params = {})
9
+ # uri = URI.parse "#{ROOT}#{path}"
10
+ # req = Net::HTTP.const_get("#{method}").new "#{ROOT}#{path}"
11
+ # req['X-auth-key'] = AUTH_KEY
12
+ # if params
13
+ # req.body = params.to_json
14
+ # req['Content-type'] = 'application/json'
15
+ # end
16
+ #
17
+ # if block_given?
18
+ # Net::HTTP.start(uri.host, uri.port, use_ssl: USE_SSL) do |http|
19
+ # http.request req do |res|
20
+ # res.read_body do |seg|
21
+ # yield seg
22
+ # end
23
+ # end
24
+ # end
25
+ # else
26
+ # resp = Net::HTTP.start(uri.host, uri.port, use_ssl: USE_SSL) do |http|
27
+ # http.request req
28
+ # end
29
+ # parsed = JSON.parse(resp.body)
30
+ # if parsed.is_a? Hash
31
+ # MetaHash.new parsed
32
+ # else
33
+ # parsed
34
+ # end
35
+ # end
36
+ # end
37
+ #
38
+ # def get(path, &block)
39
+ # http path, 'Get', nil, &block
40
+ # end
41
+ #
42
+ # def post(path, params = {})
43
+ # http path, 'Post', params
44
+ # end
45
+ #
46
+ # def del(path, params = {})
47
+ # http path, 'Delete', params
48
+ # end
49
+ #
50
+ # def self.campaigns
51
+ # Campaigns.new
52
+ # end
53
+ #
54
+ # def self.lists
55
+ # Lists.new
56
+ # end
57
+ #
58
+ # def self.contacts
59
+ # Contacts.new
60
+ # end
61
+ #
62
+ # def self.messages
63
+ # Messages.new
64
+ # end
65
+ # end
66
+ # end
File without changes
@@ -0,0 +1,71 @@
1
+ module ExpressPigeon
2
+ # Contacts
3
+ #
4
+ # Contacts end point allows you to create, read, update and delete contacts
5
+ # on your lists. A contact consists of required email and various standard
6
+ # and custom fields.
7
+ class Contacts
8
+ include HTTParty
9
+
10
+ base_uri('https://api.expresspigeon.com/contacts')
11
+ debug_output(nil)
12
+
13
+ def initialize(auth_key)
14
+ self.class.headers('X-auth-key' => auth_key)
15
+ end
16
+
17
+ # Read a single contact by email
18
+ #
19
+ # GET https://api.expresspigeon.com/contacts
20
+ def find(email_address)
21
+ self.class.get('/', query: { email: email_address })
22
+ end
23
+
24
+ # Create or update contacts
25
+ #
26
+ # POST https://api.expresspigeon.com/contacts
27
+ def create(list_id, contacts)
28
+ fail "Contacts must be an Array received #{contacts.class.name}." unless contacts.is_a?(Array)
29
+
30
+ options = {
31
+ 'list_id' => list_id,
32
+ 'contacts' => contacts
33
+ }
34
+
35
+ self.class.post(
36
+ '/',
37
+ body: options.to_json,
38
+ headers: {
39
+ 'Content-Type' => 'application/json'
40
+ }
41
+ )
42
+ end
43
+ alias_method :update, :create
44
+
45
+ # Delete a single contact
46
+ #
47
+ # DELETE https://api.expresspigeon.com/contacts
48
+ def delete(_email_address)
49
+ end
50
+
51
+ # Move contacts between lists
52
+ #
53
+ # POST https://api.expresspigeon.com/contacts/move
54
+ def move(source_list_id, target_list_id, email_addresses)
55
+ fail "Email address must be an Array received #{email_addresses.class.name}." unless email_addresses.is_a?(Array)
56
+
57
+ options = {}
58
+ options['source_list'] = source_list_id
59
+ options['target_list'] = target_list_id
60
+ options['contacts'] = email_addresses
61
+
62
+ self.class.post(
63
+ '/move',
64
+ body: options.to_json,
65
+ headers: {
66
+ 'Content-Type' => 'application/json'
67
+ }
68
+ )
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,111 @@
1
+ module ExpressPigeon
2
+ # Lists
3
+ #
4
+ # Lists are sets of contacts a campaign can be sent to. A list consists of
5
+ # name, from name, reply-to fields and physical address that will be
6
+ # displayed in newsletter. Lists can be created, read, updated, deleted and
7
+ # filled up with contacts.
8
+ #
9
+ # Note: each list has properties, including physical address. Such address
10
+ # is merged into footers of newsletters when campaigns are sent to a list.
11
+ # It allows to send to different lists of contacts and display different
12
+ # physical addresses at the bottom of newsletters depending which list such
13
+ # email was sent to. This is a useful feature for agencies who manage email
14
+ # marketing campaigns on behalf of their clients.
15
+ class Lists
16
+ include HTTMultiParty
17
+
18
+ base_uri('https://api.expresspigeon.com/lists')
19
+ debug_output(nil)
20
+
21
+ def initialize(auth_key)
22
+ self.class.headers('X-auth-key' => auth_key)
23
+ end
24
+
25
+ # Create a new list
26
+ # POST https://api.expresspigeon.com/lists
27
+ #
28
+ # name: Name of a newly created list
29
+ # from_name: Default "from" name used when sending campaigns to this list
30
+ # reply_to: Default reply To email address used when sending campaigns to this list
31
+ def create(name:, from_name:, reply_to:)
32
+ self.class.post(
33
+ '/',
34
+ body: {
35
+ name: name,
36
+ from_name: from_name,
37
+ reply_to: reply_to
38
+ }.to_json,
39
+ headers: {
40
+ 'Content-Type' => 'application/json'
41
+ }
42
+ )
43
+ end
44
+
45
+ # Check the status of list upload
46
+ # GET https://api.expresspigeon.com/lists/upload_status/{upload_id}
47
+ def upload_status(upload_id)
48
+ self.class.get("/upload_status/#{upload_id}")
49
+ end
50
+
51
+ # Get all lists
52
+ # GET https://api.expresspigeon.com/lists
53
+ def index
54
+ self.class.get('/')
55
+ end
56
+
57
+ # Upload contacts to list
58
+ # POST https://api.expresspigeon.com/lists/{list_id}/upload
59
+ def upload(list_id, path)
60
+ fail "No file found at '#{path}'." unless File.exist?(path)
61
+
62
+ self.class.post(
63
+ "/#{list_id}/upload",
64
+ query: { contacts_file: File.new(path, 'r') },
65
+ detect_mime_type: true
66
+ )
67
+ end
68
+
69
+ # Delete a list
70
+ # DELETE https://api.expresspigeon.com/lists/{list_id}
71
+ def delete(list_id)
72
+ self.class.delete("/#{list_id}")
73
+ end
74
+
75
+ # Download contacts from list
76
+ # GET https://api.expresspigeon.com/lists/{list_id}/csv
77
+ def download_csv(list_id, download_path)
78
+ fail "File found at '#{download_path}' but will not overwrite." if File.exist?(download_path)
79
+
80
+ response = self.class.get("/#{list_id}/csv")
81
+
82
+ File.open(download_path, 'wb') do |f|
83
+ f.write response.body
84
+ end
85
+
86
+ response
87
+ end
88
+
89
+ # Update existing list
90
+ # PUT https://api.expresspigeon.com/lists
91
+ def update(list_id, name: nil, from_name: nil, reply_to: nil)
92
+ options = {}
93
+ options['name'] = name unless name.nil?
94
+ options['from_name'] = from_name unless from_name.nil?
95
+ options['reply_to'] = reply_to unless reply_to.nil?
96
+
97
+ # if we didn't provide any options then it's a NOOP
98
+ return nil if options.empty?
99
+
100
+ options['id'] = list_id
101
+
102
+ self.class.put(
103
+ '/',
104
+ body: options.to_json,
105
+ headers: {
106
+ 'Content-Type' => 'application/json'
107
+ }
108
+ )
109
+ end
110
+ end
111
+ end
@@ -0,0 +1,20 @@
1
+ # class MetaHash < Hash
2
+ # def initialize(delegate)
3
+ # super
4
+ # @delegate = delegate
5
+ # @delegate.each_key do |k|
6
+ # v = @delegate[k] # lets go only one level down for now
7
+ # if v.is_a? Hash
8
+ # @delegate[k] = MetaHash.new(v)
9
+ # end
10
+ # end
11
+ # end
12
+ #
13
+ # def method_missing(m, *_args, &_block)
14
+ # @delegate[m.to_s]
15
+ # end
16
+ #
17
+ # def to_s
18
+ # @delegate.to_s
19
+ # end
20
+ # end
@@ -0,0 +1,4 @@
1
+ module ExpressPigeon
2
+ class Templates
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module ExpressPigeon
2
+ class TransactionalEmails
3
+ end
4
+ end
@@ -1,3 +1,3 @@
1
1
  module ExpressPigeon
2
- VERSION = "1.0.4"
2
+ VERSION = '2.0.0'.freeze
3
3
  end