blastengine 0.4.1 → 0.5.1
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 +4 -4
- data/README.md +61 -3
- data/lib/blastengine/base.rb +63 -0
- data/lib/blastengine/bulk.rb +43 -1
- data/lib/blastengine/client.rb +1 -0
- data/lib/blastengine/download.rb +1 -0
- data/lib/blastengine/email.rb +2 -0
- data/lib/blastengine/job.rb +2 -0
- data/lib/blastengine/log.rb +28 -0
- data/lib/blastengine/mail.rb +105 -0
- data/lib/blastengine/report.rb +2 -0
- data/lib/blastengine/transaction.rb +13 -1
- data/lib/blastengine/usage.rb +2 -0
- data/lib/blastengine/version.rb +1 -1
- data/lib/blastengine.rb +2 -0
- metadata +5 -4
- data/blastengine.gemspec +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02bc35ccd669b289c2a0f988b9b45eb234b340ebe56f95f24b8428774edefa65
|
4
|
+
data.tar.gz: 9311a00bbbd6b704f5dcb7317ad80122606326519c4a929ba484f026a17e3e4f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43416c93510d316fff59df714bc0e086539989d227691875fe34dc6579786d18ae85dc34c01db07065ab214d0ce9ad2b96a097b61ea626c2d7538c915fc1225c
|
7
|
+
data.tar.gz: 4e25b0934cf68ea34f62b6a671f2d79db388e50a1fbf47e0de4337a616363f57df8d15a9b277571c491bf964a00b71e87d248f5af71a68b53943cf62e9d6a1b1
|
data/README.md
CHANGED
@@ -28,13 +28,71 @@ APIキーとユーザー名はblastengineのサイトで取得してください
|
|
28
28
|
client = Blastengine.initialize api_key: "API_KEY", user_name: "YOUR_USER_NAME"
|
29
29
|
```
|
30
30
|
|
31
|
+
### メール送信
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
mail = Blastengine::Mail.new
|
35
|
+
mail.from email: "admin@example.com", name: "Administrator"
|
36
|
+
mail.addTo email: config["to"], insert_code: { name1: "name 1" }
|
37
|
+
mail.subject = "Test email"
|
38
|
+
mail.text_part = "This is a test email __name1__"
|
39
|
+
mail.html_part = "<html><body>This is a test email __name1__</body></html>"
|
40
|
+
mail.attachments << "README.md"
|
41
|
+
bol = mail.send
|
42
|
+
expect(bol).to be true
|
43
|
+
delivery_id = mail.delivery_id
|
44
|
+
expect(delivery_id).to be_an(Integer)
|
45
|
+
```
|
46
|
+
|
47
|
+
送信先は制限なく登録できます。
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
mail = Blastengine::Mail.new
|
51
|
+
mail.from email: "admin@example.com", name: "Administrator"
|
52
|
+
10000.times do |i|
|
53
|
+
mail.addTo email: "bulk#{i}@example.jp", insert_code: { name1: "name #{i}" }
|
54
|
+
end
|
55
|
+
mail.subject = "Test email"
|
56
|
+
mail.text_part = "This is a test email __name1__"
|
57
|
+
mail.html_part = "<html><body>This is a test email __name1__</body></html>"
|
58
|
+
mail.attachments << "README.md"
|
59
|
+
bol = mail.send
|
60
|
+
expect(bol).to be true
|
61
|
+
delivery_id = mail.delivery_id
|
62
|
+
expect(delivery_id).to be_an(Integer)
|
63
|
+
```
|
64
|
+
|
65
|
+
### メール検索
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
params = {
|
69
|
+
"delivery_start": Time.now - 60 * 60 * 24 * 30,
|
70
|
+
"delivery_end": Time.now,
|
71
|
+
"delivery_type": ["BULK"],
|
72
|
+
"status": ["EDIT", "SENT"]
|
73
|
+
}
|
74
|
+
ary = Blastengine::Mail.find params
|
75
|
+
ary[0].delivery_type # BULK
|
76
|
+
ary[0].status # SENT
|
77
|
+
```
|
78
|
+
|
79
|
+
### 配信ログ検索
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
params = {
|
83
|
+
"delivery_type": ["BULK"],
|
84
|
+
"status": ["EDIT", "SENT"]
|
85
|
+
}
|
86
|
+
ary = Blastengine::Log.find params
|
87
|
+
```
|
88
|
+
|
31
89
|
### トランザクションメール
|
32
90
|
|
33
91
|
#### テキストメール
|
34
92
|
|
35
93
|
```ruby
|
36
94
|
transaction = Blastengine::Transaction.new
|
37
|
-
transaction.from "admin@example.com", "Administrator"
|
95
|
+
transaction.from email: "admin@example.com", name: "Administrator"
|
38
96
|
transaction.to = "user@example.jp"
|
39
97
|
transaction.subject = "Test subject"
|
40
98
|
transaction.text_part = "This is a test email"
|
@@ -67,8 +125,8 @@ bulk.text_part = "This is a test email to __name__"
|
|
67
125
|
bulk.register
|
68
126
|
|
69
127
|
# Add address
|
70
|
-
bulk.
|
71
|
-
bulk.
|
128
|
+
bulk.addTo "test1@example.jp", {name: "User 1"}
|
129
|
+
bulk.addTo "test2@example.jp", {name: "User 2"}
|
72
130
|
bulk.update
|
73
131
|
|
74
132
|
# Send email immediately
|
data/lib/blastengine/base.rb
CHANGED
@@ -1,9 +1,72 @@
|
|
1
|
+
require "date"
|
2
|
+
|
1
3
|
module Blastengine
|
2
4
|
class Base
|
3
5
|
include Blastengine
|
4
6
|
attr_accessor :delivery_id, :status, :delivery_time, :delivery_type, :open_count,
|
5
7
|
:created_time, :updated_time, :hard_error_count, :soft_error_count, :drop_count, :sent_count, :total_count
|
6
8
|
|
9
|
+
def self.client
|
10
|
+
base = Base.new
|
11
|
+
base.client
|
12
|
+
end
|
13
|
+
|
14
|
+
def client
|
15
|
+
@@client
|
16
|
+
end
|
17
|
+
|
18
|
+
def sets(params)
|
19
|
+
params.each do |key, value|
|
20
|
+
self.set(key, value)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def set(key, value)
|
25
|
+
case key
|
26
|
+
when "delivery_id"
|
27
|
+
@delivery_id = value
|
28
|
+
when "status"
|
29
|
+
@status = value
|
30
|
+
when "delivery_time"
|
31
|
+
@delivery_time = Date.parse(value) if value != nil
|
32
|
+
when "delivery_type"
|
33
|
+
@delivery_type = value
|
34
|
+
when "open_count"
|
35
|
+
@open_count = value
|
36
|
+
when "created_time"
|
37
|
+
@created_time = Date.parse(value) if value != nil
|
38
|
+
when "updated_time"
|
39
|
+
@updated_time = Date.parse(value) if value != nil
|
40
|
+
when "hard_error_count"
|
41
|
+
@hard_error_count = value
|
42
|
+
when "soft_error_count"
|
43
|
+
@soft_error_count = value
|
44
|
+
when "drop_count"
|
45
|
+
@drop_count = value
|
46
|
+
when "sent_count"
|
47
|
+
@sent_count = value
|
48
|
+
when "total_count"
|
49
|
+
@total_count = value
|
50
|
+
when "from"
|
51
|
+
@_from = value
|
52
|
+
when "reservation_time"
|
53
|
+
@reservation_time = Date.parse(value) if value != nil
|
54
|
+
when "maillog_id"
|
55
|
+
@maillog_id = value
|
56
|
+
when "email"
|
57
|
+
@to = value
|
58
|
+
when "last_response_code"
|
59
|
+
@last_response_code = value
|
60
|
+
when "last_response_message"
|
61
|
+
@last_response_message = value
|
62
|
+
when "subject"
|
63
|
+
@subject = value
|
64
|
+
when "open_time"
|
65
|
+
@open_time = Date.parse(value) if value != nil
|
66
|
+
end
|
67
|
+
self
|
68
|
+
end
|
69
|
+
|
7
70
|
def get
|
8
71
|
# APIリクエスト用のパス
|
9
72
|
path = "/deliveries/#{@delivery_id}"
|
data/lib/blastengine/bulk.rb
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
require "time"
|
2
|
+
require "tempfile"
|
3
|
+
require "csv"
|
4
|
+
require "date"
|
2
5
|
|
3
6
|
module Blastengine
|
4
7
|
class Bulk < Base
|
@@ -40,7 +43,7 @@ module Blastengine
|
|
40
43
|
#
|
41
44
|
# 受信者の追加
|
42
45
|
#
|
43
|
-
def
|
46
|
+
def addTo(email, params = {})
|
44
47
|
@to << {
|
45
48
|
email: email,
|
46
49
|
insert_code: params.map{|key, value| {
|
@@ -54,6 +57,14 @@ module Blastengine
|
|
54
57
|
# バルクメールの更新
|
55
58
|
#
|
56
59
|
def update
|
60
|
+
if @to.size > 50
|
61
|
+
return self.csv_update
|
62
|
+
else
|
63
|
+
return self.normal_update
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def normal_update
|
57
68
|
# APIリクエスト用のパス
|
58
69
|
path = "/deliveries/bulk/update/#{@delivery_id}"
|
59
70
|
data = {
|
@@ -69,6 +80,36 @@ module Blastengine
|
|
69
80
|
return res["delivery_id"]
|
70
81
|
end
|
71
82
|
|
83
|
+
def csv_update
|
84
|
+
f = Tempfile.create(['blastengine', '.csv'])
|
85
|
+
f.close
|
86
|
+
csv = CSV.open(f.path, "w")
|
87
|
+
# ヘッダーの作成
|
88
|
+
headers = ["email"]
|
89
|
+
@to.each do |to|
|
90
|
+
to[:insert_code].each do |insert_code|
|
91
|
+
headers << insert_code[:key] if headers.index(insert_code[:key]) == nil
|
92
|
+
end
|
93
|
+
end
|
94
|
+
csv.puts headers
|
95
|
+
@to.each do |to|
|
96
|
+
lines = [to[:email]]
|
97
|
+
headers.each do |header|
|
98
|
+
next if header == "email"
|
99
|
+
insert_code = to[:insert_code].find{|insert_code| insert_code[:key] == header}
|
100
|
+
lines << insert_code[:value] if insert_code != nil
|
101
|
+
end
|
102
|
+
csv.puts lines
|
103
|
+
end
|
104
|
+
csv.close
|
105
|
+
job = self.import f.path
|
106
|
+
while !job.finish?
|
107
|
+
sleep 1
|
108
|
+
end
|
109
|
+
File.unlink f.path
|
110
|
+
@delivery_id
|
111
|
+
end
|
112
|
+
|
72
113
|
#
|
73
114
|
# バルクメールの送信
|
74
115
|
#
|
@@ -82,6 +123,7 @@ module Blastengine
|
|
82
123
|
# API実行
|
83
124
|
res = @@client.patch path, data
|
84
125
|
# エラーがあったら例外を投げるので、この場合は通常終了
|
126
|
+
@delivery_id = res["delivery_id"]
|
85
127
|
return res["delivery_id"]
|
86
128
|
end
|
87
129
|
|
data/lib/blastengine/client.rb
CHANGED
data/lib/blastengine/download.rb
CHANGED
data/lib/blastengine/email.rb
CHANGED
data/lib/blastengine/job.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Blastengine
|
4
|
+
class Log < Base
|
5
|
+
include Blastengine
|
6
|
+
attr_accessor :cc, :bcc, :subject, :text_part, :encode, :html_part, :attachments, :delivery_id, :job
|
7
|
+
|
8
|
+
def self.from_hash(params)
|
9
|
+
log = Log.new
|
10
|
+
log.sets(params)
|
11
|
+
log
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.find(params = {})
|
15
|
+
Hash[ params.map{|k,v| [k.to_sym, v] } ]
|
16
|
+
if params[:delivery_start] != nil
|
17
|
+
params[:delivery_start] = params[:delivery_start].iso8601
|
18
|
+
end
|
19
|
+
if params[:delivery_end] != nil
|
20
|
+
params[:delivery_end] = params[:delivery_end].iso8601
|
21
|
+
end
|
22
|
+
query_string = URI.encode_www_form(params)
|
23
|
+
url = "/logs/mails/results?#{query_string}";
|
24
|
+
res = Mail.client.get url
|
25
|
+
return res['data'].map {|params| Log.from_hash params }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Blastengine
|
4
|
+
class Mail < Base
|
5
|
+
include Blastengine
|
6
|
+
attr_accessor :to, :cc, :bcc, :subject, :text_part, :encode, :html_part, :attachments, :delivery_id
|
7
|
+
def initialize
|
8
|
+
@to = []
|
9
|
+
@cc = []
|
10
|
+
@bcc = []
|
11
|
+
@attachments = []
|
12
|
+
@encode = "UTF-8"
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# 送信主の追加
|
17
|
+
#
|
18
|
+
def from(email:, name: "")
|
19
|
+
@_from = {email: email, name: name}
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# 受信者の追加
|
24
|
+
#
|
25
|
+
def addTo(email:, insert_code: {})
|
26
|
+
@to << {
|
27
|
+
email: email,
|
28
|
+
insert_code: insert_code
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def send(date = nil)
|
33
|
+
# CCまたはBCCがある場合はTransaction × Toの分
|
34
|
+
# Toが複数の場合はBulk、Toが1つの場合はTransaction
|
35
|
+
if @cc.size > 0 || @bcc.size > 0
|
36
|
+
# CCまたはBCCがある場合は、指定時刻送信はできない
|
37
|
+
raise "CC or BCC is not supported when sending at a specified time." if date != nil
|
38
|
+
raise "CC or BCC is not supported when sending to multiple recipients." if @to.size > 1
|
39
|
+
end
|
40
|
+
if date != nil || @to.size == 1
|
41
|
+
return self.sendTransaction();
|
42
|
+
end
|
43
|
+
return self.sendBulk(date)
|
44
|
+
end
|
45
|
+
|
46
|
+
def sendBulk(date = nil)
|
47
|
+
bulk = Bulk.new
|
48
|
+
bulk.from email: @_from[:email], name: @_from[:name]
|
49
|
+
bulk.subject = @subject
|
50
|
+
bulk.encode = @encode
|
51
|
+
bulk.text_part = @text_part
|
52
|
+
bulk.html_part = @html_part
|
53
|
+
if @attachments.size > 0
|
54
|
+
bulk.attachments = @attachments
|
55
|
+
end
|
56
|
+
bulk.register
|
57
|
+
@to.each do |to|
|
58
|
+
bulk.addTo(to[:email], to[:insert_code])
|
59
|
+
end
|
60
|
+
bulk.update
|
61
|
+
bulk.send date
|
62
|
+
@delivery_id = bulk.delivery_id
|
63
|
+
return true;
|
64
|
+
end
|
65
|
+
|
66
|
+
def sendTransaction
|
67
|
+
transaction = Transaction.new
|
68
|
+
transaction.from email: @_from[:email], name: @_from[:name]
|
69
|
+
transaction.subject = @subject
|
70
|
+
transaction.encode = @encode
|
71
|
+
transaction.text_part = @text_part
|
72
|
+
transaction.html_part = @html_part
|
73
|
+
transaction.to = @to[0][:email]
|
74
|
+
transaction.insert_code = @to[0][:insert_code] if @to[0][:insert_code].size > 0
|
75
|
+
transaction.cc = @cc if @cc.size > 0
|
76
|
+
transaction.bcc = @bcc if @bcc.size > 0
|
77
|
+
if @attachments.size > 0
|
78
|
+
transaction.attachments = @attachments
|
79
|
+
end
|
80
|
+
transaction.send
|
81
|
+
@delivery_id = transaction.delivery_id
|
82
|
+
return true;
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.from_hash(params)
|
86
|
+
mail = params["delivery_type"] == "TRANSACTION" ? Transaction.new : Bulk.new
|
87
|
+
mail.sets(params);
|
88
|
+
mail
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.find(params = {})
|
92
|
+
Hash[ params.map{|k,v| [k.to_sym, v] } ]
|
93
|
+
if params[:delivery_start] != nil
|
94
|
+
params[:delivery_start] = params[:delivery_start].iso8601
|
95
|
+
end
|
96
|
+
if params[:delivery_end] != nil
|
97
|
+
params[:delivery_end] = params[:delivery_end].iso8601
|
98
|
+
end
|
99
|
+
query_string = URI.encode_www_form(params)
|
100
|
+
url = "/deliveries?#{query_string}";
|
101
|
+
res = Mail.client.get url
|
102
|
+
return res['data'].map {|params| Mail.from_hash params }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
data/lib/blastengine/report.rb
CHANGED
@@ -1,13 +1,16 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
1
3
|
module Blastengine
|
2
4
|
class Transaction < Base
|
3
5
|
include Blastengine
|
4
|
-
attr_accessor :to, :cc, :bcc, :subject, :text_part, :encode, :html_part, :attachments
|
6
|
+
attr_accessor :to, :cc, :bcc, :subject, :text_part, :encode, :html_part, :attachments, :insert_code
|
5
7
|
def initialize
|
6
8
|
@to = ""
|
7
9
|
@cc = []
|
8
10
|
@bcc = []
|
9
11
|
@attachments = []
|
10
12
|
@encode = "UTF-8"
|
13
|
+
@insert_code = {}
|
11
14
|
end
|
12
15
|
|
13
16
|
#
|
@@ -35,9 +38,18 @@ module Blastengine
|
|
35
38
|
}
|
36
39
|
# HTMLパートがある場合は追加
|
37
40
|
data[:html_part] = @html_part unless @html_part.nil?
|
41
|
+
if @insert_code != nil
|
42
|
+
data[:insert_code] = @insert_code.map do |key, value|
|
43
|
+
{
|
44
|
+
key: "__#{key}__",
|
45
|
+
value: value
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
38
49
|
# API実行
|
39
50
|
res = @@client.post path, data, @attachments
|
40
51
|
# エラーがあったら例外を投げるので、この場合は通常終了
|
52
|
+
@delivery_id = res["delivery_id"]
|
41
53
|
return res["delivery_id"]
|
42
54
|
end
|
43
55
|
end
|
data/lib/blastengine/usage.rb
CHANGED
data/lib/blastengine/version.rb
CHANGED
data/lib/blastengine.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blastengine
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Atsushi Nakatsugawa
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: This is a SDK for sending email by blastengine.
|
14
14
|
email:
|
@@ -25,7 +25,6 @@ files:
|
|
25
25
|
- LICENSE
|
26
26
|
- README.md
|
27
27
|
- Rakefile
|
28
|
-
- blastengine.gemspec
|
29
28
|
- lib/blastengine.rb
|
30
29
|
- lib/blastengine/base.rb
|
31
30
|
- lib/blastengine/bulk.rb
|
@@ -33,6 +32,8 @@ files:
|
|
33
32
|
- lib/blastengine/download.rb
|
34
33
|
- lib/blastengine/email.rb
|
35
34
|
- lib/blastengine/job.rb
|
35
|
+
- lib/blastengine/log.rb
|
36
|
+
- lib/blastengine/mail.rb
|
36
37
|
- lib/blastengine/report.rb
|
37
38
|
- lib/blastengine/transaction.rb
|
38
39
|
- lib/blastengine/usage.rb
|
@@ -60,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '0'
|
62
63
|
requirements: []
|
63
|
-
rubygems_version: 3.
|
64
|
+
rubygems_version: 3.4.9
|
64
65
|
signing_key:
|
65
66
|
specification_version: 4
|
66
67
|
summary: SDK for sending email by blastengine
|
data/blastengine.gemspec
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative "lib/blastengine/version"
|
4
|
-
|
5
|
-
Gem::Specification.new do |spec|
|
6
|
-
spec.name = "blastengine"
|
7
|
-
spec.version = Blastengine::VERSION
|
8
|
-
spec.authors = ["Atsushi Nakatsugawa"]
|
9
|
-
spec.email = ["atsushi@moongift.jp"]
|
10
|
-
|
11
|
-
spec.summary = "SDK for sending email by blastengine"
|
12
|
-
spec.description = "This is a SDK for sending email by blastengine."
|
13
|
-
spec.homepage = "https://blastengine.jp/"
|
14
|
-
spec.license = "MIT"
|
15
|
-
spec.required_ruby_version = ">= 2.6.0"
|
16
|
-
|
17
|
-
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
18
|
-
|
19
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
20
|
-
spec.metadata["source_code_uri"] = "https://github.com/blastengineMania/blastengine-ruby"
|
21
|
-
spec.metadata["changelog_uri"] = "https://github.com/blastengineMania/blastengine-ruby/CHANGELOG.md"
|
22
|
-
|
23
|
-
# Specify which files should be added to the gem when it is released.
|
24
|
-
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
25
|
-
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
26
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
27
|
-
(f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
|
28
|
-
end
|
29
|
-
end
|
30
|
-
spec.bindir = "exe"
|
31
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
|
-
spec.require_paths = ["lib"]
|
33
|
-
|
34
|
-
# Uncomment to register a new dependency of your gem
|
35
|
-
# spec.add_dependency "example-gem", "~> 1.0"
|
36
|
-
|
37
|
-
# For more information and examples about making a new gem, check out our
|
38
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
39
|
-
end
|