mailqun 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/mailqun +64 -71
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa92a4457288ba1a54a43c6d9921aa5cf119e642
|
4
|
+
data.tar.gz: 262bd8e2701d04312974ee84fac86f716d538553
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 75898450897035e70684127c56e576d6ba16521ab043bcd675760fed4b71465e9ca4abbc81364f8d215f762d4dc5f86802bfeef686d98e5ae711bd2d3f10ef68
|
7
|
+
data.tar.gz: 4edafe4f40b695d4ff1f78dd845dcead9e092f0bb4b7645957ccac4443e594c0b9a98b642dd09d28933f50c90990c52f554c8a1a079876038ab0f2beab3eaa6b
|
data/mailqun
CHANGED
@@ -3,27 +3,14 @@ require 'net/http'
|
|
3
3
|
require 'optparse'
|
4
4
|
require 'ostruct'
|
5
5
|
require 'json'
|
6
|
-
|
7
|
-
begin
|
8
|
-
require 'colorize'
|
9
|
-
rescue LoadError
|
10
|
-
class String
|
11
|
-
def method_missing(name)
|
12
|
-
if ['green', 'red'].include? name.to_s
|
13
|
-
self
|
14
|
-
else
|
15
|
-
super
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
6
|
+
require 'colorize'
|
20
7
|
|
21
8
|
def load_env
|
22
9
|
@domain = ENV['MAILGUN_DOMAIN']
|
23
10
|
@secret = ENV['MAILGUN_SECRET']
|
24
11
|
|
25
|
-
abort(
|
26
|
-
abort(
|
12
|
+
abort('Error: Set MAILGUN_DOMAIN') if @domain.nil?
|
13
|
+
abort('Error: Set MAILGUN_SECRET') if @secret.nil?
|
27
14
|
end
|
28
15
|
|
29
16
|
def load_uri
|
@@ -36,29 +23,29 @@ def load_uri
|
|
36
23
|
query = URI.encode_www_form(@options.to_h)
|
37
24
|
url = "https://api.mailgun.net/v3/#{@domain}/#{@query_type}?#{query}"
|
38
25
|
end
|
39
|
-
|
26
|
+
URI(url)
|
40
27
|
end
|
41
28
|
|
42
29
|
def request uri
|
43
30
|
response = nil
|
44
|
-
Net::HTTP.start(uri.host, uri.port, :
|
31
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
45
32
|
klass = Object.const_get("Net::HTTP::#{@verb.capitalize}")
|
46
33
|
request = klass.new uri.request_uri
|
47
34
|
request.basic_auth 'api', @secret
|
48
35
|
response = http.request request
|
49
36
|
end
|
50
|
-
|
37
|
+
response
|
51
38
|
end
|
52
39
|
|
53
|
-
def
|
40
|
+
def build_json_response
|
54
41
|
response = request load_uri
|
55
|
-
unless response.
|
42
|
+
unless response.is_a? Net::HTTPSuccess
|
56
43
|
abort("Error: Response code was #{response.code}\n#{response.body}")
|
57
44
|
end
|
58
45
|
JSON.parse(response.body)
|
59
46
|
end
|
60
47
|
|
61
|
-
def
|
48
|
+
def build_filename filename
|
62
49
|
filename.gsub!(/^.*(\\|\/)/, '')
|
63
50
|
filename.gsub!(/[^0-9A-Za-z.\-]/, '_')
|
64
51
|
"#{filename.strip}_#{Time.now.to_i}.html"
|
@@ -66,29 +53,37 @@ end
|
|
66
53
|
|
67
54
|
def pretty_print_event_item item
|
68
55
|
event = item['event'].upcase
|
69
|
-
pretty_line =
|
70
|
-
pretty_line = "#{pretty_line}\t[#{item['tags'].join(',')}]";
|
71
|
-
pretty_line = "#{pretty_line} #{item['recipient']}"
|
72
|
-
|
56
|
+
pretty_line = pretty_line_prefix item
|
73
57
|
if event == 'FAILED'
|
74
|
-
|
75
|
-
error_description = item['delivery-status']['message'] if error_description.empty?
|
76
|
-
pretty_line = "#{pretty_line}\t- #{item['delivery-status']['code']}"\
|
77
|
-
" - #{error_description}"
|
78
|
-
|
79
|
-
puts "#{pretty_line}".red
|
58
|
+
puts pretty_line_failed(pretty_line, item).to_s.red
|
80
59
|
elsif ['DELIVERED', 'OPENED'].include? event
|
81
|
-
puts
|
60
|
+
puts pretty_line.to_s.green
|
82
61
|
else
|
83
|
-
puts
|
62
|
+
puts pretty_line.to_s
|
84
63
|
end
|
85
64
|
end
|
86
65
|
|
66
|
+
def pretty_line_failed pretty_line, item
|
67
|
+
error_description = [
|
68
|
+
item['delivery-status']['description'],
|
69
|
+
item['delivery-status']['message']
|
70
|
+
].find { |m| !m.empty? }[0..70].gsub(/\s\w+$/, '...')
|
71
|
+
"#{pretty_line}\t- #{item['delivery-status']['code']} - #{error_description}"
|
72
|
+
end
|
73
|
+
|
74
|
+
def pretty_line_prefix item
|
75
|
+
"#{Time.at(item['timestamp'])}: " \
|
76
|
+
"[#{item['event'].upcase}]" \
|
77
|
+
"\t" \
|
78
|
+
"[#{item['tags'].join(',')}] " \
|
79
|
+
"#{item['recipient']}"
|
80
|
+
end
|
81
|
+
|
87
82
|
def pretty_print_bounce_item item
|
88
83
|
pretty_line = "#{item['created_at']}: #{item['address']}"
|
89
|
-
pretty_line = "#{pretty_line}\t- #{item['error'].red}"
|
84
|
+
pretty_line = "#{pretty_line}\t- #{item['error'].red}"
|
90
85
|
|
91
|
-
puts
|
86
|
+
puts pretty_line.to_s
|
92
87
|
end
|
93
88
|
|
94
89
|
def pretty_print_item item
|
@@ -115,8 +110,8 @@ def handle_fetch json_response
|
|
115
110
|
end
|
116
111
|
|
117
112
|
def handle_view json_response
|
118
|
-
filename =
|
119
|
-
open(
|
113
|
+
filename = build_filename json_response['subject']
|
114
|
+
File.open(filename.to_s, 'w') do |f|
|
120
115
|
f.puts json_response['body-html']
|
121
116
|
end
|
122
117
|
system "open #{filename}"
|
@@ -137,74 +132,72 @@ end
|
|
137
132
|
@verb = 'GET'
|
138
133
|
|
139
134
|
OptionParser.new do |opts|
|
140
|
-
opts.banner =
|
135
|
+
opts.banner = 'Usage: mailqun [options]'
|
141
136
|
|
142
|
-
opts.separator
|
143
|
-
opts.separator
|
137
|
+
opts.separator ''
|
138
|
+
opts.separator 'Common options:'
|
144
139
|
|
145
|
-
opts.on(
|
146
|
-
|
140
|
+
opts.on('-f [FROM]', '--from [FROM]', String,
|
141
|
+
'Address of the sender') do |f|
|
147
142
|
@options.from = f
|
148
143
|
end
|
149
144
|
|
150
|
-
opts.on(
|
151
|
-
|
145
|
+
opts.on('-t [TO]', '--to [TO]', String,
|
146
|
+
'Address of the receiver') do |t|
|
152
147
|
@options.to = t
|
153
148
|
end
|
154
149
|
|
155
|
-
opts.on(
|
156
|
-
|
150
|
+
opts.on('-s [SUBJECT]', '--subject [SUBJECT]', String,
|
151
|
+
'Subject of mail') do |s|
|
157
152
|
@options.subject = s
|
158
153
|
end
|
159
154
|
|
160
|
-
opts.on(
|
161
|
-
|
155
|
+
opts.on('-l [LIMIT]', '--limit [LIMIT]', Integer,
|
156
|
+
'Limit on number of results') do |l|
|
162
157
|
@options.limit = l
|
163
158
|
end
|
164
159
|
|
165
|
-
opts.on(
|
166
|
-
|
160
|
+
opts.on('--tags [TAG]', String,
|
161
|
+
'Value in X-Mailgun-Tag header') do |t|
|
167
162
|
@options.tags = t
|
168
163
|
end
|
169
164
|
|
170
|
-
opts.on(
|
171
|
-
|
165
|
+
opts.on('-e [EVENT]', '--event [EVENT]', String,
|
166
|
+
'Event being queried') do |e|
|
172
167
|
@options.event = e
|
173
168
|
end
|
174
169
|
|
175
|
-
opts.on(
|
176
|
-
|
170
|
+
opts.on('--raw',
|
171
|
+
'Gives raw json response, instead of summary') do |_e|
|
177
172
|
@options.pretty = false
|
178
173
|
end
|
179
174
|
|
180
|
-
opts.separator
|
181
|
-
opts.separator
|
175
|
+
opts.separator ''
|
176
|
+
opts.separator 'Bounce options:'
|
182
177
|
|
183
|
-
opts.on(
|
184
|
-
|
178
|
+
opts.on('--bounces',
|
179
|
+
'Add this option to query bounces instead of events') do |_e|
|
185
180
|
@query_type = 'bounces'
|
186
181
|
end
|
187
182
|
|
188
|
-
opts.on(
|
189
|
-
|
190
|
-
if @query_type == 'bounces'
|
191
|
-
@address = a
|
192
|
-
end
|
183
|
+
opts.on('-a [ADDRESS]', '--address [ADDRESS]', String,
|
184
|
+
'Bounced address, used with --bounces') do |a|
|
185
|
+
@address = a if @query_type == 'bounces'
|
193
186
|
end
|
194
187
|
|
195
|
-
opts.on(
|
196
|
-
|
188
|
+
opts.on('--delete [ADDRESS]', String,
|
189
|
+
'Delete address from bounces, used with --bounces') do |a|
|
197
190
|
if @query_type == 'bounces'
|
198
191
|
@address = a
|
199
192
|
@verb = 'DELETE'
|
200
193
|
end
|
201
194
|
end
|
202
195
|
|
203
|
-
opts.separator
|
204
|
-
opts.separator
|
196
|
+
opts.separator ''
|
197
|
+
opts.separator 'View options:'
|
205
198
|
|
206
|
-
opts.on(
|
207
|
-
|
199
|
+
opts.on('--view-body [URL]',
|
200
|
+
'Mailgun storage URL to fetch email body from') do |u|
|
208
201
|
@url = u
|
209
202
|
@query_type = 'view'
|
210
203
|
end
|
@@ -212,6 +205,6 @@ end.parse!
|
|
212
205
|
|
213
206
|
load_env
|
214
207
|
|
215
|
-
json_response =
|
208
|
+
json_response = build_json_response
|
216
209
|
|
217
210
|
build_output json_response
|