paubox 0.3.2 → 1.1.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 +4 -4
- data/.github/scripts/assert_specs_ran.rb +40 -0
- data/.github/scripts/route-check.sh +43 -0
- data/.github/workflows/ci.yml +61 -0
- data/.github/workflows/pr-title.yml +36 -0
- data/.github/workflows/release-please.yml +88 -0
- data/.gitignore +4 -1
- data/.release-please-manifest.json +3 -0
- data/CHANGELOG.md +86 -0
- data/CLAUDE.md +114 -0
- data/README.md +255 -12
- data/api.md +283 -0
- data/lib/paubox/client.rb +52 -5
- data/lib/paubox/dynamic_templates.rb +58 -0
- data/lib/paubox/form.rb +51 -0
- data/lib/paubox/form_submission.rb +34 -0
- data/lib/paubox/forms_client.rb +211 -0
- data/lib/paubox/version.rb +1 -1
- data/lib/paubox.rb +10 -2
- data/paubox_ruby.gemspec +4 -0
- data/release-please-config.json +14 -0
- metadata +45 -7
- data/.travis.yml +0 -5
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paubox
|
|
4
|
+
class DynamicTemplates
|
|
5
|
+
|
|
6
|
+
attr_accessor :id, :name, :api_customer_id, :body
|
|
7
|
+
|
|
8
|
+
def initialize(args = {})
|
|
9
|
+
@id = args['id']
|
|
10
|
+
@name = args['name']
|
|
11
|
+
@api_customer_id = args['api_customer_id']
|
|
12
|
+
@body = args['body']
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def update(template_file_path, template_name = nil)
|
|
16
|
+
path = "dynamic_templates/#{id}"
|
|
17
|
+
payload = {
|
|
18
|
+
data: {
|
|
19
|
+
name: template_name,
|
|
20
|
+
body: File.new(template_file_path)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Paubox::Client.new.send_request(method: :patch, payload: payload, path: path)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def delete
|
|
28
|
+
path = "dynamic_templates/#{id}"
|
|
29
|
+
Paubox::Client.new.send_request(method: :delete, path: path)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class << self
|
|
33
|
+
def create(template_name, template_file_path)
|
|
34
|
+
path = "dynamic_templates"
|
|
35
|
+
payload = {
|
|
36
|
+
data: {
|
|
37
|
+
name: template_name,
|
|
38
|
+
body: File.new(template_file_path)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
Paubox::Client.new.send_request(method: :post, payload: payload, path: path)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def find(template_id)
|
|
45
|
+
path = "dynamic_templates/#{template_id.to_s}"
|
|
46
|
+
response = Paubox::Client.new.send_request(method: :get, path: path)
|
|
47
|
+
data = JSON.parse(response.body)
|
|
48
|
+
Paubox::DynamicTemplates.new(data)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def list
|
|
52
|
+
path = "dynamic_templates"
|
|
53
|
+
response = Paubox::Client.new.send_request(method: :get, path: path)
|
|
54
|
+
JSON.parse(response.body)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
data/lib/paubox/form.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paubox
|
|
4
|
+
class Form
|
|
5
|
+
attr_reader :id, :title, :description, :form_html, :form_json, :form_css,
|
|
6
|
+
:vanity_url, :version, :active, :customer_id, :signable,
|
|
7
|
+
:signature_confirmation_label, :submission_count, :type,
|
|
8
|
+
:deleted, :archived, :created_at, :updated_at,
|
|
9
|
+
:recipient, :subscription_list_id, :old_form_id
|
|
10
|
+
|
|
11
|
+
def initialize(args = {})
|
|
12
|
+
@id = args['id']
|
|
13
|
+
@title = args['title']
|
|
14
|
+
@description = args['description']
|
|
15
|
+
@form_html = args['form_html']
|
|
16
|
+
@form_json = args['form_json']
|
|
17
|
+
@form_css = args['form_css']
|
|
18
|
+
@vanity_url = args['vanity_url']
|
|
19
|
+
@version = args['version']
|
|
20
|
+
@active = args['active']
|
|
21
|
+
@customer_id = args['customer_id']
|
|
22
|
+
@signable = args['signable']
|
|
23
|
+
@signature_confirmation_label = args['signature_confirmation_label']
|
|
24
|
+
@submission_count = args['submission_count']
|
|
25
|
+
@type = args['type']
|
|
26
|
+
@deleted = args['deleted']
|
|
27
|
+
@archived = args['archived']
|
|
28
|
+
@created_at = args['created_at']
|
|
29
|
+
@updated_at = args['updated_at']
|
|
30
|
+
@recipient = args['recipient']
|
|
31
|
+
@subscription_list_id = args['subscription_list_id']
|
|
32
|
+
@old_form_id = args['old_form_id']
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def active?
|
|
36
|
+
@active
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def deleted?
|
|
40
|
+
@deleted
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def archived?
|
|
44
|
+
@archived
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def signable?
|
|
48
|
+
@signable
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Paubox
|
|
4
|
+
class FormSubmission
|
|
5
|
+
attr_reader :id, :form_id, :form_data, :storage_type, :storage_url,
|
|
6
|
+
:submitter_email, :recipients, :attachment_name,
|
|
7
|
+
:attachment_url, :attachment_type, :created_at
|
|
8
|
+
|
|
9
|
+
def initialize(args = {})
|
|
10
|
+
@id = args['id']
|
|
11
|
+
@form_id = args['form_id']
|
|
12
|
+
@form_data = parse_form_data(args['form_data'])
|
|
13
|
+
@storage_type = args['storage_type']
|
|
14
|
+
@storage_url = args['storage_url']
|
|
15
|
+
@submitter_email = args['submitter_email']
|
|
16
|
+
@recipients = args['recipients']
|
|
17
|
+
@attachment_name = args['attachment_name']
|
|
18
|
+
@attachment_url = args['attachment_url']
|
|
19
|
+
@attachment_type = args['attachment_type']
|
|
20
|
+
@created_at = args['created_at']
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def parse_form_data(form_data)
|
|
26
|
+
return {} if form_data.nil?
|
|
27
|
+
return form_data if form_data.is_a?(Hash)
|
|
28
|
+
|
|
29
|
+
JSON.parse(form_data)
|
|
30
|
+
rescue JSON::ParserError
|
|
31
|
+
{}
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'cgi'
|
|
4
|
+
require 'rest-client'
|
|
5
|
+
|
|
6
|
+
module Paubox
|
|
7
|
+
class FormsClient
|
|
8
|
+
FORMS_HOST = 'api.paubox.com'
|
|
9
|
+
FORMS_PROTOCOL = 'https://'
|
|
10
|
+
FORMS_BASE = '/v1/forms'
|
|
11
|
+
|
|
12
|
+
TIMEOUT_SECONDS = 30
|
|
13
|
+
|
|
14
|
+
UUID_RE = /\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
|
|
15
|
+
|
|
16
|
+
LIST_FORMS_PARAMS = %i[customer_id form_id search order order_by
|
|
17
|
+
archived active page items].freeze
|
|
18
|
+
LIST_SUBMISSIONS_PARAMS = %i[submission_id order_by order page items].freeze
|
|
19
|
+
|
|
20
|
+
# Raised on any non-2xx response from the Forms API. Carries only
|
|
21
|
+
# status_code / url / response_body so error reporters that capture
|
|
22
|
+
# raising-frame locals never see the Authorization header or api_key.
|
|
23
|
+
class Error < StandardError
|
|
24
|
+
attr_reader :status_code, :url, :response_body
|
|
25
|
+
|
|
26
|
+
def initialize(message, status_code: nil, url: nil, response_body: nil)
|
|
27
|
+
super(message)
|
|
28
|
+
@status_code = status_code
|
|
29
|
+
@url = url
|
|
30
|
+
@response_body = response_body
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize(args = {})
|
|
35
|
+
@host = args[:host] || FORMS_HOST
|
|
36
|
+
@protocol = args[:protocol] || FORMS_PROTOCOL
|
|
37
|
+
@base = args[:base] || FORMS_BASE
|
|
38
|
+
@api_key = args[:api_key] ||
|
|
39
|
+
(Paubox.configuration && Paubox.configuration.forms_api_key)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def get_form(form_id)
|
|
43
|
+
assert_uuid!(form_id, 'form_id')
|
|
44
|
+
url = "#{@protocol}#{@host}#{@base}/public/form_data/#{encode_segment(form_id)}"
|
|
45
|
+
response = request(method: :get, url: url, headers: { accept: :json })
|
|
46
|
+
Paubox::Form.new(JSON.parse(response.body))
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def submit_form(form_id, form_data:, attachments: [])
|
|
50
|
+
assert_uuid!(form_id, 'form_id')
|
|
51
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}/submissions"
|
|
52
|
+
payload = { form_data: form_data }
|
|
53
|
+
payload[:attachments] = attachments unless attachments.empty?
|
|
54
|
+
request(method: :post, url: url, payload: payload.to_json,
|
|
55
|
+
headers: { content_type: :json, accept: :json })
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def list_forms(params = {})
|
|
59
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms"
|
|
60
|
+
query = params.transform_keys(&:to_sym)
|
|
61
|
+
.select { |k, _v| LIST_FORMS_PARAMS.include?(k) }
|
|
62
|
+
if query[:customer_id].nil?
|
|
63
|
+
raise ArgumentError, 'customer_id is required for list_forms and must ' \
|
|
64
|
+
"match the API key's customer, e.g. " \
|
|
65
|
+
'client.list_forms(customer_id: 123)'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
response = request(method: :get, url: url,
|
|
69
|
+
headers: auth_headers.merge(params: query))
|
|
70
|
+
body = JSON.parse(response.body)
|
|
71
|
+
forms = (body['results'] || []).map { |form| Paubox::Form.new(form) }
|
|
72
|
+
{ forms: forms, page_info: body['page_info'] }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def create_form(attrs)
|
|
76
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms"
|
|
77
|
+
response = request(method: :post, url: url, payload: attrs.to_json,
|
|
78
|
+
headers: auth_headers.merge(content_type: :json))
|
|
79
|
+
JSON.parse(response.body)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def find_form(form_id)
|
|
83
|
+
assert_uuid!(form_id, 'form_id')
|
|
84
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}"
|
|
85
|
+
response = request(method: :get, url: url, headers: auth_headers)
|
|
86
|
+
Paubox::Form.new(JSON.parse(response.body)['data'])
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def update_form(form_id, attrs)
|
|
90
|
+
assert_uuid!(form_id, 'form_id')
|
|
91
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}"
|
|
92
|
+
response = request(method: :put, url: url, payload: attrs.to_json,
|
|
93
|
+
headers: auth_headers.merge(content_type: :json))
|
|
94
|
+
JSON.parse(response.body)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def archive_form(form_id)
|
|
98
|
+
assert_uuid!(form_id, 'form_id')
|
|
99
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}/archive"
|
|
100
|
+
response = request(method: :post, url: url, payload: '{}',
|
|
101
|
+
headers: auth_headers.merge(content_type: :json))
|
|
102
|
+
JSON.parse(response.body)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def unarchive_form(form_id)
|
|
106
|
+
assert_uuid!(form_id, 'form_id')
|
|
107
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}/unarchive"
|
|
108
|
+
response = request(method: :post, url: url, payload: '{}',
|
|
109
|
+
headers: auth_headers.merge(content_type: :json))
|
|
110
|
+
JSON.parse(response.body)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def copy_form(form_id, title:)
|
|
114
|
+
assert_uuid!(form_id, 'form_id')
|
|
115
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/copy"
|
|
116
|
+
payload = { form_id: form_id, title: title }
|
|
117
|
+
response = request(method: :post, url: url, payload: payload.to_json,
|
|
118
|
+
headers: auth_headers.merge(content_type: :json))
|
|
119
|
+
Paubox::Form.new(JSON.parse(response.body))
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def form_stats(customer_id: nil)
|
|
123
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/stats"
|
|
124
|
+
headers = auth_headers
|
|
125
|
+
headers = headers.merge(params: { customer_id: customer_id }) unless customer_id.nil?
|
|
126
|
+
response = request(method: :get, url: url, headers: headers)
|
|
127
|
+
JSON.parse(response.body)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def list_submissions(form_id, params = {})
|
|
131
|
+
assert_uuid!(form_id, 'form_id')
|
|
132
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}/submissions"
|
|
133
|
+
query = params.transform_keys(&:to_sym)
|
|
134
|
+
.select { |k, _v| LIST_SUBMISSIONS_PARAMS.include?(k) }
|
|
135
|
+
response = request(method: :get, url: url,
|
|
136
|
+
headers: auth_headers.merge(params: query))
|
|
137
|
+
body = JSON.parse(response.body)
|
|
138
|
+
submissions = (body['data'] || []).map { |s| Paubox::FormSubmission.new(s) }
|
|
139
|
+
{ submissions: submissions, total: body['total'], page: body['page'],
|
|
140
|
+
items: body['items'] }
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def submissions_csv(form_id, submission_id: nil)
|
|
144
|
+
assert_uuid!(form_id, 'form_id')
|
|
145
|
+
base = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}" \
|
|
146
|
+
'/submissions/submission-csv'
|
|
147
|
+
url = if submission_id.nil?
|
|
148
|
+
base
|
|
149
|
+
else
|
|
150
|
+
assert_uuid!(submission_id, 'submission_id')
|
|
151
|
+
"#{base}/#{encode_segment(submission_id)}"
|
|
152
|
+
end
|
|
153
|
+
request(method: :get, url: url, headers: auth_headers(accept: 'text/csv')).body
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def submission_pdf(form_id, submission_id)
|
|
157
|
+
assert_uuid!(form_id, 'form_id')
|
|
158
|
+
assert_uuid!(submission_id, 'submission_id')
|
|
159
|
+
url = "#{@protocol}#{@host}#{@base}/api/forms/#{encode_segment(form_id)}/submissions/" \
|
|
160
|
+
"#{encode_segment(submission_id)}/submission-pdf"
|
|
161
|
+
request(method: :get, url: url, headers: auth_headers(accept: 'application/pdf')).body
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
private
|
|
165
|
+
|
|
166
|
+
def auth_headers(accept: :json)
|
|
167
|
+
if @api_key.nil? || @api_key.to_s.empty?
|
|
168
|
+
raise ArgumentError, "api_key is required for this endpoint. Pass a scoped " \
|
|
169
|
+
"API key with the 'forms' scope: " \
|
|
170
|
+
'Paubox::FormsClient.new(api_key: ...)'
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
{ authorization: "Bearer #{@api_key}", accept: accept }
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def assert_uuid!(value, name)
|
|
177
|
+
return if value.is_a?(String) && value.match?(UUID_RE)
|
|
178
|
+
|
|
179
|
+
raise ArgumentError, "#{name} must be a UUID string (received #{value.inspect})"
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def encode_segment(value)
|
|
183
|
+
CGI.escape(value.to_s)
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Funnels every request through RestClient::Request.execute so we can
|
|
187
|
+
# always set an explicit timeout (rest-client's default is nil) and
|
|
188
|
+
# translate ExceptionWithResponse into Paubox::FormsClient::Error,
|
|
189
|
+
# which carries only status_code / url / response_body — never the
|
|
190
|
+
# Authorization header or api_key. Keeps the Bearer token out of any
|
|
191
|
+
# error reporter that captures raising-frame locals.
|
|
192
|
+
def request(method:, url:, headers: {}, payload: nil)
|
|
193
|
+
RestClient::Request.execute(
|
|
194
|
+
method: method,
|
|
195
|
+
url: url,
|
|
196
|
+
payload: payload,
|
|
197
|
+
headers: headers,
|
|
198
|
+
timeout: TIMEOUT_SECONDS
|
|
199
|
+
)
|
|
200
|
+
rescue RestClient::ExceptionWithResponse => e
|
|
201
|
+
response = e.response
|
|
202
|
+
raise Error.new(
|
|
203
|
+
"Paubox Forms API request failed: #{e.class.name.split('::').last} " \
|
|
204
|
+
"(status #{response && response.code || 'unknown'})",
|
|
205
|
+
status_code: response && response.code,
|
|
206
|
+
url: url,
|
|
207
|
+
response_body: response && response.body
|
|
208
|
+
)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
data/lib/paubox/version.rb
CHANGED
data/lib/paubox.rb
CHANGED
|
@@ -2,11 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
require 'paubox/version'
|
|
4
4
|
require 'paubox/client'
|
|
5
|
+
require 'paubox/dynamic_templates'
|
|
5
6
|
require 'paubox/format_helper'
|
|
6
7
|
require 'paubox/mail_to_message'
|
|
7
8
|
require 'paubox/message'
|
|
8
9
|
require 'paubox/templated_message'
|
|
9
10
|
require 'paubox/email_disposition'
|
|
11
|
+
require 'paubox/form'
|
|
12
|
+
require 'paubox/form_submission'
|
|
13
|
+
require 'paubox/forms_client'
|
|
10
14
|
require 'mail/paubox'
|
|
11
15
|
|
|
12
16
|
module Paubox
|
|
@@ -20,6 +24,10 @@ module Paubox
|
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
class Configuration
|
|
23
|
-
attr_accessor :api_key, :
|
|
27
|
+
attr_accessor :api_key, :forms_api_key
|
|
28
|
+
|
|
29
|
+
# Deprecated: api_user is no longer used by the Email API client.
|
|
30
|
+
# Kept only for backward compatibility; it has no effect on requests.
|
|
31
|
+
attr_accessor :api_user
|
|
24
32
|
end
|
|
25
|
-
end
|
|
33
|
+
end
|
data/paubox_ruby.gemspec
CHANGED
|
@@ -29,6 +29,10 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
spec.add_development_dependency 'rspec', '~> 3.2'
|
|
30
30
|
spec.add_development_dependency 'webmock', '~> 2.1'
|
|
31
31
|
|
|
32
|
+
# base64 and ostruct left the default gems (base64 in Ruby 3.4, ostruct in
|
|
33
|
+
# 4.0). lib/ requires both, so they must be declared or the gem fails to load.
|
|
34
|
+
spec.add_dependency 'base64'
|
|
35
|
+
spec.add_dependency 'ostruct'
|
|
32
36
|
spec.add_dependency 'mail', '>= 2.5'
|
|
33
37
|
spec.add_dependency 'rest-client', '~> 2.0', '>= 2.0.2'
|
|
34
38
|
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
3
|
+
"packages": {
|
|
4
|
+
".": {
|
|
5
|
+
"release-type": "ruby",
|
|
6
|
+
"package-name": "paubox",
|
|
7
|
+
"version-file": "lib/paubox/version.rb",
|
|
8
|
+
"include-component-in-tag": false,
|
|
9
|
+
"include-v-in-tag": true,
|
|
10
|
+
"draft": false,
|
|
11
|
+
"prerelease": false
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: paubox
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paubox
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: bundler
|
|
@@ -80,6 +79,34 @@ dependencies:
|
|
|
80
79
|
- - "~>"
|
|
81
80
|
- !ruby/object:Gem::Version
|
|
82
81
|
version: '2.1'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: base64
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - ">="
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '0'
|
|
89
|
+
type: :runtime
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - ">="
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: ostruct
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - ">="
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '0'
|
|
103
|
+
type: :runtime
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '0'
|
|
83
110
|
- !ruby/object:Gem::Dependency
|
|
84
111
|
name: mail
|
|
85
112
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -121,31 +148,43 @@ executables: []
|
|
|
121
148
|
extensions: []
|
|
122
149
|
extra_rdoc_files: []
|
|
123
150
|
files:
|
|
151
|
+
- ".github/scripts/assert_specs_ran.rb"
|
|
152
|
+
- ".github/scripts/route-check.sh"
|
|
153
|
+
- ".github/workflows/ci.yml"
|
|
154
|
+
- ".github/workflows/pr-title.yml"
|
|
155
|
+
- ".github/workflows/release-please.yml"
|
|
124
156
|
- ".gitignore"
|
|
157
|
+
- ".release-please-manifest.json"
|
|
125
158
|
- ".rspec"
|
|
126
|
-
-
|
|
159
|
+
- CHANGELOG.md
|
|
160
|
+
- CLAUDE.md
|
|
127
161
|
- Gemfile
|
|
128
162
|
- LICENSE.txt
|
|
129
163
|
- README.md
|
|
130
164
|
- Rakefile
|
|
165
|
+
- api.md
|
|
131
166
|
- bin/console
|
|
132
167
|
- bin/setup
|
|
133
168
|
- lib/mail/paubox.rb
|
|
134
169
|
- lib/paubox.rb
|
|
135
170
|
- lib/paubox/client.rb
|
|
171
|
+
- lib/paubox/dynamic_templates.rb
|
|
136
172
|
- lib/paubox/email_disposition.rb
|
|
173
|
+
- lib/paubox/form.rb
|
|
174
|
+
- lib/paubox/form_submission.rb
|
|
137
175
|
- lib/paubox/format_helper.rb
|
|
176
|
+
- lib/paubox/forms_client.rb
|
|
138
177
|
- lib/paubox/mail_to_message.rb
|
|
139
178
|
- lib/paubox/message.rb
|
|
140
179
|
- lib/paubox/templated_message.rb
|
|
141
180
|
- lib/paubox/version.rb
|
|
142
181
|
- lib/paubox_ruby.rb
|
|
143
182
|
- paubox_ruby.gemspec
|
|
183
|
+
- release-please-config.json
|
|
144
184
|
homepage: https://www.paubox.com
|
|
145
185
|
licenses:
|
|
146
186
|
- Apache-2.0
|
|
147
187
|
metadata: {}
|
|
148
|
-
post_install_message:
|
|
149
188
|
rdoc_options: []
|
|
150
189
|
require_paths:
|
|
151
190
|
- lib
|
|
@@ -160,8 +199,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
160
199
|
- !ruby/object:Gem::Version
|
|
161
200
|
version: '0'
|
|
162
201
|
requirements: []
|
|
163
|
-
rubygems_version: 3.
|
|
164
|
-
signing_key:
|
|
202
|
+
rubygems_version: 3.6.9
|
|
165
203
|
specification_version: 4
|
|
166
204
|
summary: Paubox's Official Ruby SDK
|
|
167
205
|
test_files: []
|