sevk 0.1.0 → 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/LICENSE +21 -0
- data/README.md +6 -10
- data/lib/sevk/client.rb +148 -58
- data/lib/sevk/error.rb +38 -5
- data/lib/sevk/markup/document_parser.rb +83 -0
- data/lib/sevk/markup/html_document.rb +82 -0
- data/lib/sevk/markup/number_formatting.rb +40 -0
- data/lib/sevk/markup/render_limits.rb +52 -0
- data/lib/sevk/markup/renderer.rb +282 -351
- data/lib/sevk/markup/style_helpers.rb +131 -0
- data/lib/sevk/markup/syntax_highlighting.rb +227 -0
- data/lib/sevk/markup/tag_scanner.rb +112 -0
- data/lib/sevk/markup/template_engine.rb +247 -0
- data/lib/sevk/resources/activity.rb +23 -0
- data/lib/sevk/resources/audiences.rb +30 -11
- data/lib/sevk/resources/base.rb +15 -3
- data/lib/sevk/resources/broadcasts.rb +91 -3
- data/lib/sevk/resources/contacts.rb +39 -12
- data/lib/sevk/resources/domains.rb +41 -3
- data/lib/sevk/resources/emails.rb +91 -9
- data/lib/sevk/resources/inbound.rb +123 -0
- data/lib/sevk/resources/outbound.rb +55 -0
- data/lib/sevk/resources/segments.rb +37 -15
- data/lib/sevk/resources/subscriptions.rb +18 -11
- data/lib/sevk/resources/templates.rb +20 -8
- data/lib/sevk/resources/topics.rb +37 -14
- data/lib/sevk/resources/usage.rb +15 -0
- data/lib/sevk/resources/webhooks.rb +52 -0
- data/lib/sevk/version.rb +1 -1
- data/lib/sevk/webhook_verifier.rb +91 -0
- data/lib/sevk.rb +24 -192
- metadata +25 -82
- data/Rakefile +0 -42
- data/sevk.gemspec +0 -40
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'json'
|
|
5
|
+
require 'openssl'
|
|
6
|
+
|
|
7
|
+
module Sevk
|
|
8
|
+
class WebhookVerificationError < StandardError; end
|
|
9
|
+
|
|
10
|
+
# Verifier for sevk webhook deliveries.
|
|
11
|
+
#
|
|
12
|
+
# sevk uses the Svix-compatible signature scheme (svix-id, svix-timestamp,
|
|
13
|
+
# svix-signature headers), so this helper or the official `svix` gem can be
|
|
14
|
+
# used. sevk issues canonical whsec_ base64 secrets that can be passed
|
|
15
|
+
# directly to either verifier.
|
|
16
|
+
class WebhookVerifier
|
|
17
|
+
TOLERANCE_SECONDS = 5 * 60
|
|
18
|
+
|
|
19
|
+
# Prepares a verifier with the signing secret issued for a webhook.
|
|
20
|
+
def initialize(secret)
|
|
21
|
+
raise WebhookVerificationError, 'Webhook secret is required' if secret.nil? || secret.empty?
|
|
22
|
+
|
|
23
|
+
@key = if secret.start_with?('whsec_')
|
|
24
|
+
begin
|
|
25
|
+
decoded = Base64.strict_decode64(secret[6..])
|
|
26
|
+
raise ArgumentError if decoded.empty?
|
|
27
|
+
|
|
28
|
+
decoded
|
|
29
|
+
rescue ArgumentError
|
|
30
|
+
raise WebhookVerificationError, 'Invalid base64 secret'
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
secret
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Verifies the delivery signature and timestamp, then parses its JSON payload.
|
|
38
|
+
def verify(payload, headers)
|
|
39
|
+
msg_id = lookup(headers, 'svix-id')
|
|
40
|
+
msg_timestamp = lookup(headers, 'svix-timestamp')
|
|
41
|
+
msg_signature = lookup(headers, 'svix-signature')
|
|
42
|
+
|
|
43
|
+
if msg_id.nil? || msg_id.empty? || msg_timestamp.nil? || msg_signature.nil?
|
|
44
|
+
raise WebhookVerificationError, 'Missing required svix headers'
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
raise WebhookVerificationError, 'Invalid timestamp header' unless msg_timestamp.match?(/\A[0-9]+\z/)
|
|
48
|
+
|
|
49
|
+
timestamp = Integer(msg_timestamp, 10)
|
|
50
|
+
now = Time.now.to_i
|
|
51
|
+
if timestamp < now - TOLERANCE_SECONDS || timestamp > now + TOLERANCE_SECONDS
|
|
52
|
+
raise WebhookVerificationError, 'Timestamp outside tolerance window'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
to_sign = "#{msg_id}.#{msg_timestamp}.#{payload}"
|
|
56
|
+
digest = OpenSSL::HMAC.digest('SHA256', @key, to_sign)
|
|
57
|
+
expected = "v1,#{Base64.strict_encode64(digest)}"
|
|
58
|
+
|
|
59
|
+
msg_signature.split.each do |candidate|
|
|
60
|
+
next unless secure_compare(expected, candidate)
|
|
61
|
+
|
|
62
|
+
begin
|
|
63
|
+
return JSON.parse(payload)
|
|
64
|
+
rescue JSON::ParserError
|
|
65
|
+
raise WebhookVerificationError, 'Invalid JSON payload'
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
raise WebhookVerificationError, 'Signature mismatch'
|
|
70
|
+
rescue ArgumentError
|
|
71
|
+
raise WebhookVerificationError, 'Invalid timestamp header'
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
def lookup(headers, name)
|
|
77
|
+
headers.each do |key, value|
|
|
78
|
+
normalized = key.to_s.downcase.tr('_', '-').sub(/\Ahttp-/, '')
|
|
79
|
+
return value unless value.nil? || normalized != name
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def secure_compare(expected, candidate)
|
|
86
|
+
return false unless expected.bytesize == candidate.bytesize
|
|
87
|
+
|
|
88
|
+
OpenSSL.fixed_length_secure_compare(expected, candidate)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
data/lib/sevk.rb
CHANGED
|
@@ -1,26 +1,31 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
require_relative
|
|
8
|
-
require_relative
|
|
9
|
-
require_relative
|
|
10
|
-
require_relative
|
|
11
|
-
require_relative
|
|
12
|
-
require_relative
|
|
13
|
-
require_relative
|
|
14
|
-
require_relative
|
|
15
|
-
require_relative
|
|
16
|
-
require_relative
|
|
17
|
-
require_relative
|
|
18
|
-
require_relative
|
|
19
|
-
require_relative
|
|
20
|
-
require_relative
|
|
3
|
+
require 'faraday'
|
|
4
|
+
require 'json'
|
|
5
|
+
|
|
6
|
+
require_relative 'sevk/version'
|
|
7
|
+
require_relative 'sevk/error'
|
|
8
|
+
require_relative 'sevk/client'
|
|
9
|
+
require_relative 'sevk/resources/base'
|
|
10
|
+
require_relative 'sevk/resources/contacts'
|
|
11
|
+
require_relative 'sevk/resources/audiences'
|
|
12
|
+
require_relative 'sevk/resources/templates'
|
|
13
|
+
require_relative 'sevk/resources/broadcasts'
|
|
14
|
+
require_relative 'sevk/resources/domains'
|
|
15
|
+
require_relative 'sevk/resources/topics'
|
|
16
|
+
require_relative 'sevk/resources/segments'
|
|
17
|
+
require_relative 'sevk/resources/subscriptions'
|
|
18
|
+
require_relative 'sevk/resources/emails'
|
|
19
|
+
require_relative 'sevk/resources/webhooks'
|
|
20
|
+
require_relative 'sevk/resources/activity'
|
|
21
|
+
require_relative 'sevk/resources/inbound'
|
|
22
|
+
require_relative 'sevk/resources/outbound'
|
|
23
|
+
require_relative 'sevk/resources/usage'
|
|
24
|
+
require_relative 'sevk/webhook_verifier'
|
|
25
|
+
require_relative 'sevk/markup/renderer'
|
|
21
26
|
|
|
22
27
|
module Sevk
|
|
23
|
-
DEFAULT_BASE_URL =
|
|
28
|
+
DEFAULT_BASE_URL = 'https://api.sevk.io'
|
|
24
29
|
|
|
25
30
|
class << self
|
|
26
31
|
attr_accessor :api_key, :base_url
|
|
@@ -37,177 +42,4 @@ module Sevk
|
|
|
37
42
|
@client = nil
|
|
38
43
|
end
|
|
39
44
|
end
|
|
40
|
-
|
|
41
|
-
# Class-based API
|
|
42
|
-
module Contacts
|
|
43
|
-
class << self
|
|
44
|
-
def list(params = {})
|
|
45
|
-
Sevk.client.contacts.list(**params)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def get(id)
|
|
49
|
-
Sevk.client.contacts.get(id)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def create(params)
|
|
53
|
-
Sevk.client.contacts.create(**params)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def update(id, params)
|
|
57
|
-
Sevk.client.contacts.update(id, **params)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def delete(id)
|
|
61
|
-
Sevk.client.contacts.delete(id)
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
module Audiences
|
|
67
|
-
class << self
|
|
68
|
-
def list(params = {})
|
|
69
|
-
Sevk.client.audiences.list(**params)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def get(id)
|
|
73
|
-
Sevk.client.audiences.get(id)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def create(params)
|
|
77
|
-
Sevk.client.audiences.create(**params)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def update(id, params)
|
|
81
|
-
Sevk.client.audiences.update(id, **params)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
def delete(id)
|
|
85
|
-
Sevk.client.audiences.delete(id)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def add_contacts(id, contact_ids)
|
|
89
|
-
Sevk.client.audiences.add_contacts(id, contact_ids)
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
module Templates
|
|
95
|
-
class << self
|
|
96
|
-
def list(params = {})
|
|
97
|
-
Sevk.client.templates.list(**params)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def get(id)
|
|
101
|
-
Sevk.client.templates.get(id)
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
def create(params)
|
|
105
|
-
Sevk.client.templates.create(**params)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def update(id, params)
|
|
109
|
-
Sevk.client.templates.update(id, **params)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
def delete(id)
|
|
113
|
-
Sevk.client.templates.delete(id)
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def duplicate(id)
|
|
117
|
-
Sevk.client.templates.duplicate(id)
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
module Broadcasts
|
|
123
|
-
class << self
|
|
124
|
-
def list(params = {})
|
|
125
|
-
Sevk.client.broadcasts.list(**params)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def get(id)
|
|
129
|
-
Sevk.client.broadcasts.get(id)
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
module Domains
|
|
135
|
-
class << self
|
|
136
|
-
def list(params = {})
|
|
137
|
-
Sevk.client.domains.list(**params)
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
def get(id)
|
|
141
|
-
Sevk.client.domains.get(id)
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
end
|
|
145
|
-
|
|
146
|
-
module Topics
|
|
147
|
-
class << self
|
|
148
|
-
def list(audience_id, params = {})
|
|
149
|
-
Sevk.client.topics.list(audience_id, **params)
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def get(audience_id, topic_id)
|
|
153
|
-
Sevk.client.topics.get(audience_id, topic_id)
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
def create(audience_id, params)
|
|
157
|
-
Sevk.client.topics.create(audience_id, **params)
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
def update(audience_id, topic_id, params)
|
|
161
|
-
Sevk.client.topics.update(audience_id, topic_id, **params)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def delete(audience_id, topic_id)
|
|
165
|
-
Sevk.client.topics.delete(audience_id, topic_id)
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
module Segments
|
|
171
|
-
class << self
|
|
172
|
-
def list(audience_id, params = {})
|
|
173
|
-
Sevk.client.segments.list(audience_id, **params)
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
def get(audience_id, segment_id)
|
|
177
|
-
Sevk.client.segments.get(audience_id, segment_id)
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def create(audience_id, params)
|
|
181
|
-
Sevk.client.segments.create(audience_id, **params)
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def update(audience_id, segment_id, params)
|
|
185
|
-
Sevk.client.segments.update(audience_id, segment_id, **params)
|
|
186
|
-
end
|
|
187
|
-
|
|
188
|
-
def delete(audience_id, segment_id)
|
|
189
|
-
Sevk.client.segments.delete(audience_id, segment_id)
|
|
190
|
-
end
|
|
191
|
-
end
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
module Subscriptions
|
|
195
|
-
class << self
|
|
196
|
-
def subscribe(params)
|
|
197
|
-
Sevk.client.subscriptions.subscribe(**params)
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
def unsubscribe(params)
|
|
201
|
-
Sevk.client.subscriptions.unsubscribe(**params)
|
|
202
|
-
end
|
|
203
|
-
end
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
module Emails
|
|
207
|
-
class << self
|
|
208
|
-
def send(params)
|
|
209
|
-
Sevk.client.emails.send(**params)
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
end
|
|
213
45
|
end
|
metadata
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sevk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sevk
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
|
-
name:
|
|
13
|
+
name: base64
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
16
|
- - "~>"
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '2
|
|
18
|
+
version: '0.2'
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - "~>"
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '2
|
|
25
|
+
version: '0.2'
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
|
-
name: faraday
|
|
27
|
+
name: faraday
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
@@ -38,89 +38,19 @@ dependencies:
|
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
39
|
version: '2.0'
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
|
-
name:
|
|
41
|
+
name: rouge
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
43
43
|
requirements:
|
|
44
44
|
- - "~>"
|
|
45
45
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: '
|
|
46
|
+
version: '4.0'
|
|
47
47
|
type: :runtime
|
|
48
48
|
prerelease: false
|
|
49
49
|
version_requirements: !ruby/object:Gem::Requirement
|
|
50
50
|
requirements:
|
|
51
51
|
- - "~>"
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
|
-
version: '
|
|
54
|
-
- !ruby/object:Gem::Dependency
|
|
55
|
-
name: bundler
|
|
56
|
-
requirement: !ruby/object:Gem::Requirement
|
|
57
|
-
requirements:
|
|
58
|
-
- - "~>"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '2.0'
|
|
61
|
-
type: :development
|
|
62
|
-
prerelease: false
|
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - "~>"
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: '2.0'
|
|
68
|
-
- !ruby/object:Gem::Dependency
|
|
69
|
-
name: rake
|
|
70
|
-
requirement: !ruby/object:Gem::Requirement
|
|
71
|
-
requirements:
|
|
72
|
-
- - "~>"
|
|
73
|
-
- !ruby/object:Gem::Version
|
|
74
|
-
version: '13.0'
|
|
75
|
-
type: :development
|
|
76
|
-
prerelease: false
|
|
77
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
-
requirements:
|
|
79
|
-
- - "~>"
|
|
80
|
-
- !ruby/object:Gem::Version
|
|
81
|
-
version: '13.0'
|
|
82
|
-
- !ruby/object:Gem::Dependency
|
|
83
|
-
name: rspec
|
|
84
|
-
requirement: !ruby/object:Gem::Requirement
|
|
85
|
-
requirements:
|
|
86
|
-
- - "~>"
|
|
87
|
-
- !ruby/object:Gem::Version
|
|
88
|
-
version: '3.0'
|
|
89
|
-
type: :development
|
|
90
|
-
prerelease: false
|
|
91
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
-
requirements:
|
|
93
|
-
- - "~>"
|
|
94
|
-
- !ruby/object:Gem::Version
|
|
95
|
-
version: '3.0'
|
|
96
|
-
- !ruby/object:Gem::Dependency
|
|
97
|
-
name: webmock
|
|
98
|
-
requirement: !ruby/object:Gem::Requirement
|
|
99
|
-
requirements:
|
|
100
|
-
- - "~>"
|
|
101
|
-
- !ruby/object:Gem::Version
|
|
102
|
-
version: '3.0'
|
|
103
|
-
type: :development
|
|
104
|
-
prerelease: false
|
|
105
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
-
requirements:
|
|
107
|
-
- - "~>"
|
|
108
|
-
- !ruby/object:Gem::Version
|
|
109
|
-
version: '3.0'
|
|
110
|
-
- !ruby/object:Gem::Dependency
|
|
111
|
-
name: rubocop
|
|
112
|
-
requirement: !ruby/object:Gem::Requirement
|
|
113
|
-
requirements:
|
|
114
|
-
- - "~>"
|
|
115
|
-
- !ruby/object:Gem::Version
|
|
116
|
-
version: '1.0'
|
|
117
|
-
type: :development
|
|
118
|
-
prerelease: false
|
|
119
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
120
|
-
requirements:
|
|
121
|
-
- - "~>"
|
|
122
|
-
- !ruby/object:Gem::Version
|
|
123
|
-
version: '1.0'
|
|
53
|
+
version: '4.0'
|
|
124
54
|
description: Ruby SDK for interacting with the Sevk API. Send emails, manage contacts,
|
|
125
55
|
audiences, templates, and more.
|
|
126
56
|
email:
|
|
@@ -129,31 +59,44 @@ executables: []
|
|
|
129
59
|
extensions: []
|
|
130
60
|
extra_rdoc_files: []
|
|
131
61
|
files:
|
|
62
|
+
- LICENSE
|
|
132
63
|
- README.md
|
|
133
|
-
- Rakefile
|
|
134
64
|
- lib/sevk.rb
|
|
135
65
|
- lib/sevk/client.rb
|
|
136
66
|
- lib/sevk/error.rb
|
|
67
|
+
- lib/sevk/markup/document_parser.rb
|
|
68
|
+
- lib/sevk/markup/html_document.rb
|
|
69
|
+
- lib/sevk/markup/number_formatting.rb
|
|
70
|
+
- lib/sevk/markup/render_limits.rb
|
|
137
71
|
- lib/sevk/markup/renderer.rb
|
|
72
|
+
- lib/sevk/markup/style_helpers.rb
|
|
73
|
+
- lib/sevk/markup/syntax_highlighting.rb
|
|
74
|
+
- lib/sevk/markup/tag_scanner.rb
|
|
75
|
+
- lib/sevk/markup/template_engine.rb
|
|
76
|
+
- lib/sevk/resources/activity.rb
|
|
138
77
|
- lib/sevk/resources/audiences.rb
|
|
139
78
|
- lib/sevk/resources/base.rb
|
|
140
79
|
- lib/sevk/resources/broadcasts.rb
|
|
141
80
|
- lib/sevk/resources/contacts.rb
|
|
142
81
|
- lib/sevk/resources/domains.rb
|
|
143
82
|
- lib/sevk/resources/emails.rb
|
|
83
|
+
- lib/sevk/resources/inbound.rb
|
|
84
|
+
- lib/sevk/resources/outbound.rb
|
|
144
85
|
- lib/sevk/resources/segments.rb
|
|
145
86
|
- lib/sevk/resources/subscriptions.rb
|
|
146
87
|
- lib/sevk/resources/templates.rb
|
|
147
88
|
- lib/sevk/resources/topics.rb
|
|
89
|
+
- lib/sevk/resources/usage.rb
|
|
90
|
+
- lib/sevk/resources/webhooks.rb
|
|
148
91
|
- lib/sevk/version.rb
|
|
149
|
-
- sevk.
|
|
92
|
+
- lib/sevk/webhook_verifier.rb
|
|
150
93
|
homepage: https://sevk.io
|
|
151
94
|
licenses:
|
|
152
95
|
- MIT
|
|
153
96
|
metadata:
|
|
154
97
|
homepage_uri: https://sevk.io
|
|
155
98
|
source_code_uri: https://github.com/sevk-io/sevk-ruby
|
|
156
|
-
|
|
99
|
+
rubygems_mfa_required: 'true'
|
|
157
100
|
rdoc_options: []
|
|
158
101
|
require_paths:
|
|
159
102
|
- lib
|
data/Rakefile
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "bundler/gem_tasks"
|
|
4
|
-
require "rspec/core/rake_task"
|
|
5
|
-
|
|
6
|
-
RSpec::Core::RakeTask.new(:spec)
|
|
7
|
-
|
|
8
|
-
task default: :spec
|
|
9
|
-
|
|
10
|
-
desc "Update all dependencies to latest versions"
|
|
11
|
-
task :update do
|
|
12
|
-
sh "bundle update"
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
desc "Update dependencies and show outdated gems"
|
|
16
|
-
task :outdated do
|
|
17
|
-
sh "bundle outdated"
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
desc "Run tests"
|
|
21
|
-
task :test => :spec
|
|
22
|
-
|
|
23
|
-
desc "Build the gem"
|
|
24
|
-
task :build do
|
|
25
|
-
sh "gem build sevk.gemspec"
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
desc "Install the gem locally"
|
|
29
|
-
task :install => :build do
|
|
30
|
-
sh "gem install sevk-*.gem"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
desc "Release the gem to RubyGems"
|
|
34
|
-
task :release => :build do
|
|
35
|
-
sh "gem push sevk-*.gem"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
desc "Clean up build artifacts"
|
|
39
|
-
task :clean do
|
|
40
|
-
FileUtils.rm_f Dir.glob("sevk-*.gem")
|
|
41
|
-
FileUtils.rm_rf "pkg"
|
|
42
|
-
end
|
data/sevk.gemspec
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "lib/sevk/version"
|
|
4
|
-
|
|
5
|
-
Gem::Specification.new do |spec|
|
|
6
|
-
spec.name = "sevk"
|
|
7
|
-
spec.version = Sevk::VERSION
|
|
8
|
-
spec.authors = ["Sevk"]
|
|
9
|
-
spec.email = ["dev@sevk.io"]
|
|
10
|
-
|
|
11
|
-
spec.summary = "Ruby SDK for Sevk API"
|
|
12
|
-
spec.description = "Ruby SDK for interacting with the Sevk API. Send emails, manage contacts, audiences, templates, and more."
|
|
13
|
-
spec.homepage = "https://sevk.io"
|
|
14
|
-
spec.license = "MIT"
|
|
15
|
-
spec.required_ruby_version = ">= 3.0.0"
|
|
16
|
-
|
|
17
|
-
spec.metadata["homepage_uri"] = spec.homepage
|
|
18
|
-
spec.metadata["source_code_uri"] = "https://github.com/sevk-io/sevk-ruby"
|
|
19
|
-
spec.metadata["changelog_uri"] = "https://github.com/sevk-io/sevk-ruby/blob/main/CHANGELOG.md"
|
|
20
|
-
|
|
21
|
-
spec.files = Dir.chdir(__dir__) do
|
|
22
|
-
`git ls-files -z`.split("\x0").reject do |f|
|
|
23
|
-
(File.expand_path(f) == __FILE__) ||
|
|
24
|
-
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
spec.bindir = "exe"
|
|
28
|
-
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
29
|
-
spec.require_paths = ["lib"]
|
|
30
|
-
|
|
31
|
-
spec.add_dependency "faraday", "~> 2.0"
|
|
32
|
-
spec.add_dependency "faraday-retry", "~> 2.0"
|
|
33
|
-
spec.add_dependency "nokogiri", "~> 1.15"
|
|
34
|
-
|
|
35
|
-
spec.add_development_dependency "bundler", "~> 2.0"
|
|
36
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
|
37
|
-
spec.add_development_dependency "rspec", "~> 3.0"
|
|
38
|
-
spec.add_development_dependency "webmock", "~> 3.0"
|
|
39
|
-
spec.add_development_dependency "rubocop", "~> 1.0"
|
|
40
|
-
end
|