mailshake-ruby 0.1.0 → 0.2.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/README.md +80 -19
- data/lib/mailshake/activity.rb +14 -7
- data/lib/mailshake/campaigns.rb +10 -5
- data/lib/mailshake/client.rb +2 -1
- data/lib/mailshake/leads.rb +6 -3
- data/lib/mailshake/models/add_recipients_request.rb +8 -0
- data/lib/mailshake/models/added_recipients.rb +8 -0
- data/lib/mailshake/models/base_model.rb +79 -0
- data/lib/mailshake/models/campaign.rb +10 -0
- data/lib/mailshake/models/campaign_export.rb +8 -0
- data/lib/mailshake/models/campaign_export_request.rb +8 -0
- data/lib/mailshake/models/click.rb +11 -0
- data/lib/mailshake/models/created_leads.rb +8 -0
- data/lib/mailshake/models/lead.rb +11 -0
- data/lib/mailshake/models/lead_status.rb +8 -0
- data/lib/mailshake/models/list.rb +30 -0
- data/lib/mailshake/models/message.rb +8 -0
- data/lib/mailshake/models/open.rb +11 -0
- data/lib/mailshake/models/recipient.rb +8 -0
- data/lib/mailshake/models/reply.rb +11 -0
- data/lib/mailshake/models/sender.rb +8 -0
- data/lib/mailshake/models/sent_message.rb +11 -0
- data/lib/mailshake/models/user.rb +8 -0
- data/lib/mailshake/recipients.rb +8 -4
- data/lib/mailshake/senders.rb +2 -1
- data/lib/mailshake/team.rb +2 -1
- data/lib/mailshake.rb +21 -0
- data/spec/examples.txt +86 -60
- data/spec/mailshake/activity_spec.rb +4 -2
- data/spec/mailshake/campaigns_spec.rb +10 -4
- data/spec/mailshake/client_spec.rb +1 -0
- data/spec/mailshake/leads_spec.rb +5 -2
- data/spec/mailshake/models/base_model_spec.rb +118 -0
- data/spec/mailshake/models/list_spec.rb +103 -0
- data/spec/mailshake/push_spec.rb +1 -0
- data/spec/mailshake/recipients_spec.rb +7 -3
- data/spec/mailshake/senders_spec.rb +2 -1
- data/spec/mailshake/team_spec.rb +2 -1
- metadata +24 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 173cfe60415683c55435fdd081c79a9824daa162b7dee69738ea74940326d36b
|
|
4
|
+
data.tar.gz: 6e7324f62f055eb0d7482c4e93cec793a033d291d5a3ecc0a6ff2557cfb9a779
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 7531e6410d2417febd4142731dab363e37d8fe9986c2bc06866153ff589a057fc63b8539ce0b8d17372f9c59864e51a303875cfb05eddf48ccc6e48af2415e86
|
|
7
|
+
data.tar.gz: ef2a7a8450785b67d28e1266135343418eca95af48f5674feed3e0779bc757a4ddb2f3506e188a95fafa752e597a665343949a6cf1a0c6a4a17bbb7eb5b3a260
|
data/README.md
CHANGED
|
@@ -32,18 +32,29 @@ end
|
|
|
32
32
|
|
|
33
33
|
## Usage
|
|
34
34
|
|
|
35
|
+
All API responses return model objects with snake_case accessors and nested model hydration. Hash-style access (`result["key"]`) is still supported for backwards compatibility.
|
|
36
|
+
|
|
35
37
|
### Campaigns
|
|
36
38
|
|
|
37
39
|
```ruby
|
|
38
40
|
campaigns = Mailshake::Campaigns.new
|
|
39
41
|
|
|
40
|
-
campaigns.list(search: "onboarding", per_page: 10)
|
|
41
|
-
|
|
42
|
+
list = campaigns.list(search: "onboarding", per_page: 10)
|
|
43
|
+
list.each { |c| puts c.title }
|
|
44
|
+
|
|
45
|
+
campaign = campaigns.get(campaign_id: 1)
|
|
46
|
+
campaign.title # => "Q2 Outreach"
|
|
47
|
+
campaign.is_paused # => false
|
|
48
|
+
campaign.sender.email_address # => "sales@company.com"
|
|
49
|
+
campaign.messages.first.subject # => "Hey {{first}}"
|
|
50
|
+
|
|
42
51
|
campaigns.create(title: "Q2 Outreach", sender_id: 5)
|
|
43
52
|
campaigns.pause(campaign_id: 1)
|
|
44
53
|
campaigns.unpause(campaign_id: 1)
|
|
45
|
-
|
|
46
|
-
campaigns.
|
|
54
|
+
|
|
55
|
+
export = campaigns.export(campaign_ids: [1, 2], export_type: "csv", timezone: "US/Pacific")
|
|
56
|
+
status = campaigns.export_status(status_id: export.check_status_id)
|
|
57
|
+
puts status.csv_download_url if status.is_finished
|
|
47
58
|
```
|
|
48
59
|
|
|
49
60
|
### Recipients
|
|
@@ -51,10 +62,16 @@ campaigns.export_status(status_id: 42)
|
|
|
51
62
|
```ruby
|
|
52
63
|
recipients = Mailshake::Recipients.new
|
|
53
64
|
|
|
54
|
-
recipients.add(campaign_id: 1, addresses: [{ emailAddress: "john@example.com" }])
|
|
55
|
-
recipients.add_status(status_id:
|
|
56
|
-
|
|
57
|
-
recipients.
|
|
65
|
+
result = recipients.add(campaign_id: 1, addresses: [{ emailAddress: "john@example.com" }])
|
|
66
|
+
status = recipients.add_status(status_id: result.check_status_id)
|
|
67
|
+
|
|
68
|
+
list = recipients.list(campaign_id: 1, filter: "active", per_page: 25)
|
|
69
|
+
list.each { |r| puts "#{r.full_name} <#{r.email_address}>" }
|
|
70
|
+
|
|
71
|
+
recipient = recipients.get(recipient_id: 100)
|
|
72
|
+
recipient.email_address # => "john@example.com"
|
|
73
|
+
recipient.is_paused # => false
|
|
74
|
+
|
|
58
75
|
recipients.pause(campaign_id: 1, email_address: "john@example.com")
|
|
59
76
|
recipients.unpause(campaign_id: 1, email_address: "john@example.com")
|
|
60
77
|
recipients.unsubscribe(email_addresses: ["john@example.com"])
|
|
@@ -65,10 +82,18 @@ recipients.unsubscribe(email_addresses: ["john@example.com"])
|
|
|
65
82
|
```ruby
|
|
66
83
|
activity = Mailshake::Activity.new
|
|
67
84
|
|
|
68
|
-
activity.sent(campaign_id: 1, per_page: 50)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
activity.
|
|
85
|
+
sent = activity.sent(campaign_id: 1, per_page: 50)
|
|
86
|
+
sent.each { |msg| puts "#{msg.subject} -> #{msg.recipient.email_address}" }
|
|
87
|
+
|
|
88
|
+
opens = activity.opens(campaign_id: 1, exclude_duplicates: true)
|
|
89
|
+
opens.each { |o| puts "#{o.recipient.email_address} opened at #{o.action_date}" }
|
|
90
|
+
|
|
91
|
+
clicks = activity.clicks(campaign_id: 1, match_url: "https://example.com")
|
|
92
|
+
clicks.each { |c| puts "#{c.recipient.email_address} clicked #{c.link}" }
|
|
93
|
+
|
|
94
|
+
replies = activity.replies(campaign_id: 1, reply_type: "reply")
|
|
95
|
+
replies.each { |r| puts "#{r.recipient.email_address}: #{r.plain_text_body}" }
|
|
96
|
+
|
|
72
97
|
activity.created_leads(campaign_id: 1, since: "2026-01-01")
|
|
73
98
|
activity.lead_assignments(campaign_id: 1)
|
|
74
99
|
activity.lead_status_changes(campaign_id: 1)
|
|
@@ -79,8 +104,17 @@ activity.lead_status_changes(campaign_id: 1)
|
|
|
79
104
|
```ruby
|
|
80
105
|
leads = Mailshake::Leads.new
|
|
81
106
|
|
|
82
|
-
leads.list(campaign_id: 1, status: "open")
|
|
83
|
-
|
|
107
|
+
list = leads.list(campaign_id: 1, status: "open")
|
|
108
|
+
list.each do |lead|
|
|
109
|
+
puts "#{lead.recipient.email_address} - #{lead.status}"
|
|
110
|
+
puts " assigned to: #{lead.assigned_to&.full_name}"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
lead = leads.get(lead_id: 42)
|
|
114
|
+
lead.status # => "open"
|
|
115
|
+
lead.recipient.email_address # => "john@example.com"
|
|
116
|
+
lead.campaign.title # => "Q2 Outreach"
|
|
117
|
+
|
|
84
118
|
leads.create(campaign_id: 1, email_addresses: ["john@example.com"])
|
|
85
119
|
leads.close(lead_id: 42, status: "won")
|
|
86
120
|
leads.ignore(lead_id: 42)
|
|
@@ -92,7 +126,8 @@ leads.reopen(lead_id: 42)
|
|
|
92
126
|
```ruby
|
|
93
127
|
team = Mailshake::Team.new
|
|
94
128
|
|
|
95
|
-
team.list_members(search: "john", per_page: 10)
|
|
129
|
+
members = team.list_members(search: "john", per_page: 10)
|
|
130
|
+
members.each { |u| puts "#{u.full_name} <#{u.email_address}>" }
|
|
96
131
|
```
|
|
97
132
|
|
|
98
133
|
### Senders
|
|
@@ -100,7 +135,8 @@ team.list_members(search: "john", per_page: 10)
|
|
|
100
135
|
```ruby
|
|
101
136
|
senders = Mailshake::Senders.new
|
|
102
137
|
|
|
103
|
-
senders.list(search: "sales", per_page: 10)
|
|
138
|
+
list = senders.list(search: "sales", per_page: 10)
|
|
139
|
+
list.each { |s| puts "#{s.from_name} <#{s.email_address}>" }
|
|
104
140
|
```
|
|
105
141
|
|
|
106
142
|
### Push/Webhooks
|
|
@@ -116,16 +152,41 @@ push.delete(target_url: "https://example.com/webhook")
|
|
|
116
152
|
|
|
117
153
|
```ruby
|
|
118
154
|
client = Mailshake.client
|
|
119
|
-
client.me
|
|
155
|
+
user = client.me
|
|
156
|
+
user.full_name # => "Eduardo Souza"
|
|
157
|
+
user.email_address # => "eduardo@example.com"
|
|
158
|
+
user.is_team_admin # => true
|
|
120
159
|
```
|
|
121
160
|
|
|
161
|
+
## Models
|
|
162
|
+
|
|
163
|
+
All responses are wrapped in model objects under `Mailshake::Models`. Models provide:
|
|
164
|
+
|
|
165
|
+
- **Snake_case accessors** - `campaign.is_paused` instead of `campaign["isPaused"]`
|
|
166
|
+
- **Nested model hydration** - `lead.recipient.email_address` returns a `Recipient` model
|
|
167
|
+
- **Backwards compatibility** - `campaign["title"]` still works
|
|
168
|
+
- **`to_h`** - convert back to the original hash
|
|
169
|
+
|
|
170
|
+
See the [full model reference](https://github.com/ESouza/mailshake-ruby/wiki/Models) in the wiki.
|
|
171
|
+
|
|
122
172
|
## Pagination
|
|
123
173
|
|
|
124
|
-
|
|
174
|
+
List endpoints return a `Models::List` object with `Enumerable` support:
|
|
125
175
|
|
|
126
176
|
```ruby
|
|
127
177
|
result = campaigns.list(per_page: 10)
|
|
128
|
-
|
|
178
|
+
result.each { |c| puts c.title }
|
|
179
|
+
result.map(&:title)
|
|
180
|
+
|
|
181
|
+
# Paginate through all results
|
|
182
|
+
all = []
|
|
183
|
+
result = campaigns.list(per_page: 25)
|
|
184
|
+
all.concat(result.results)
|
|
185
|
+
|
|
186
|
+
while result.next_token
|
|
187
|
+
result = campaigns.list(per_page: 25, next_token: result.next_token)
|
|
188
|
+
all.concat(result.results)
|
|
189
|
+
end
|
|
129
190
|
```
|
|
130
191
|
|
|
131
192
|
## Error Handling
|
data/lib/mailshake/activity.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Mailshake
|
|
4
4
|
class Activity < Base
|
|
5
5
|
def sent(message_type: nil, campaign_message_type: nil, campaign_id: nil, recipient_email_address: nil, exclude_body: nil, next_token: nil, per_page: nil)
|
|
6
|
-
client.get("/activity/sent", camelize_params(
|
|
6
|
+
response = client.get("/activity/sent", camelize_params(
|
|
7
7
|
message_type: message_type,
|
|
8
8
|
campaign_message_type: campaign_message_type,
|
|
9
9
|
campaign_id: campaign_id,
|
|
@@ -12,10 +12,11 @@ module Mailshake
|
|
|
12
12
|
next_token: next_token,
|
|
13
13
|
per_page: per_page
|
|
14
14
|
))
|
|
15
|
+
Models::List.new(response, Models::SentMessage)
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
def opens(campaign_id: nil, exclude_duplicates: nil, recipient_email_address: nil, next_token: nil, per_page: nil, since: nil)
|
|
18
|
-
client.get("/activity/opens", camelize_params(
|
|
19
|
+
response = client.get("/activity/opens", camelize_params(
|
|
19
20
|
campaign_id: campaign_id,
|
|
20
21
|
exclude_duplicates: exclude_duplicates,
|
|
21
22
|
recipient_email_address: recipient_email_address,
|
|
@@ -23,10 +24,11 @@ module Mailshake
|
|
|
23
24
|
per_page: per_page,
|
|
24
25
|
since: since
|
|
25
26
|
))
|
|
27
|
+
Models::List.new(response, Models::Open)
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
def clicks(campaign_id: nil, exclude_duplicates: nil, match_url: nil, recipient_email_address: nil, next_token: nil, per_page: nil, since: nil)
|
|
29
|
-
client.get("/activity/clicks", camelize_params(
|
|
31
|
+
response = client.get("/activity/clicks", camelize_params(
|
|
30
32
|
campaign_id: campaign_id,
|
|
31
33
|
exclude_duplicates: exclude_duplicates,
|
|
32
34
|
match_url: match_url,
|
|
@@ -35,20 +37,22 @@ module Mailshake
|
|
|
35
37
|
per_page: per_page,
|
|
36
38
|
since: since
|
|
37
39
|
))
|
|
40
|
+
Models::List.new(response, Models::Click)
|
|
38
41
|
end
|
|
39
42
|
|
|
40
43
|
def replies(reply_type: nil, campaign_id: nil, recipient_email_address: nil, next_token: nil, per_page: nil)
|
|
41
|
-
client.get("/activity/replies", camelize_params(
|
|
44
|
+
response = client.get("/activity/replies", camelize_params(
|
|
42
45
|
reply_type: reply_type,
|
|
43
46
|
campaign_id: campaign_id,
|
|
44
47
|
recipient_email_address: recipient_email_address,
|
|
45
48
|
next_token: next_token,
|
|
46
49
|
per_page: per_page
|
|
47
50
|
))
|
|
51
|
+
Models::List.new(response, Models::Reply)
|
|
48
52
|
end
|
|
49
53
|
|
|
50
54
|
def created_leads(campaign_id: nil, recipient_email_address: nil, assigned_to_email_address: nil, next_token: nil, per_page: nil, since: nil)
|
|
51
|
-
client.get("/activity/created-leads", camelize_params(
|
|
55
|
+
response = client.get("/activity/created-leads", camelize_params(
|
|
52
56
|
campaign_id: campaign_id,
|
|
53
57
|
recipient_email_address: recipient_email_address,
|
|
54
58
|
assigned_to_email_address: assigned_to_email_address,
|
|
@@ -56,19 +60,21 @@ module Mailshake
|
|
|
56
60
|
per_page: per_page,
|
|
57
61
|
since: since
|
|
58
62
|
))
|
|
63
|
+
Models::List.new(response, Models::Lead)
|
|
59
64
|
end
|
|
60
65
|
|
|
61
66
|
def lead_assignments(campaign_id: nil, next_token: nil, per_page: nil, since: nil)
|
|
62
|
-
client.get("/activity/lead-assignments", camelize_params(
|
|
67
|
+
response = client.get("/activity/lead-assignments", camelize_params(
|
|
63
68
|
campaign_id: campaign_id,
|
|
64
69
|
next_token: next_token,
|
|
65
70
|
per_page: per_page,
|
|
66
71
|
since: since
|
|
67
72
|
))
|
|
73
|
+
Models::List.new(response, Models::Lead)
|
|
68
74
|
end
|
|
69
75
|
|
|
70
76
|
def lead_status_changes(campaign_id: nil, recipient_email_address: nil, assigned_to_email_address: nil, next_token: nil, per_page: nil, since: nil)
|
|
71
|
-
client.get("/activity/lead-status-changes", camelize_params(
|
|
77
|
+
response = client.get("/activity/lead-status-changes", camelize_params(
|
|
72
78
|
campaign_id: campaign_id,
|
|
73
79
|
recipient_email_address: recipient_email_address,
|
|
74
80
|
assigned_to_email_address: assigned_to_email_address,
|
|
@@ -76,6 +82,7 @@ module Mailshake
|
|
|
76
82
|
per_page: per_page,
|
|
77
83
|
since: since
|
|
78
84
|
))
|
|
85
|
+
Models::List.new(response, Models::LeadStatus)
|
|
79
86
|
end
|
|
80
87
|
end
|
|
81
88
|
end
|
data/lib/mailshake/campaigns.rb
CHANGED
|
@@ -3,15 +3,18 @@
|
|
|
3
3
|
module Mailshake
|
|
4
4
|
class Campaigns < Base
|
|
5
5
|
def list(search: nil, next_token: nil, per_page: nil)
|
|
6
|
-
client.get("/campaigns/list", camelize_params(search: search, next_token: next_token, per_page: per_page))
|
|
6
|
+
response = client.get("/campaigns/list", camelize_params(search: search, next_token: next_token, per_page: per_page))
|
|
7
|
+
Models::List.new(response, Models::Campaign)
|
|
7
8
|
end
|
|
8
9
|
|
|
9
10
|
def get(campaign_id:)
|
|
10
|
-
client.get("/campaigns/get", camelize_params(campaign_id: campaign_id))
|
|
11
|
+
response = client.get("/campaigns/get", camelize_params(campaign_id: campaign_id))
|
|
12
|
+
Models::Campaign.new(response)
|
|
11
13
|
end
|
|
12
14
|
|
|
13
15
|
def create(title:, sender_id: nil)
|
|
14
|
-
client.post("/campaigns/create", camelize_params(title: title, sender_id: sender_id))
|
|
16
|
+
response = client.post("/campaigns/create", camelize_params(title: title, sender_id: sender_id))
|
|
17
|
+
Models::Campaign.new(response)
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def pause(campaign_id:)
|
|
@@ -23,11 +26,13 @@ module Mailshake
|
|
|
23
26
|
end
|
|
24
27
|
|
|
25
28
|
def export(campaign_ids: nil, export_type: nil, timezone: nil)
|
|
26
|
-
client.post("/campaigns/export", camelize_params(campaign_ids: campaign_ids, export_type: export_type, timezone: timezone))
|
|
29
|
+
response = client.post("/campaigns/export", camelize_params(campaign_ids: campaign_ids, export_type: export_type, timezone: timezone))
|
|
30
|
+
Models::CampaignExportRequest.new(response)
|
|
27
31
|
end
|
|
28
32
|
|
|
29
33
|
def export_status(status_id:)
|
|
30
|
-
client.get("/campaigns/export-status", camelize_params(status_id: status_id))
|
|
34
|
+
response = client.get("/campaigns/export-status", camelize_params(status_id: status_id))
|
|
35
|
+
Models::CampaignExport.new(response)
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
end
|
data/lib/mailshake/client.rb
CHANGED
data/lib/mailshake/leads.rb
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Mailshake
|
|
4
4
|
class Leads < Base
|
|
5
5
|
def list(campaign_id: nil, status: nil, assigned_to_email_address: nil, search: nil, next_token: nil, per_page: nil)
|
|
6
|
-
client.get("/leads/list", camelize_params(
|
|
6
|
+
response = client.get("/leads/list", camelize_params(
|
|
7
7
|
campaign_id: campaign_id,
|
|
8
8
|
status: status,
|
|
9
9
|
assigned_to_email_address: assigned_to_email_address,
|
|
@@ -11,23 +11,26 @@ module Mailshake
|
|
|
11
11
|
next_token: next_token,
|
|
12
12
|
per_page: per_page
|
|
13
13
|
))
|
|
14
|
+
Models::List.new(response, Models::Lead)
|
|
14
15
|
end
|
|
15
16
|
|
|
16
17
|
def get(lead_id: nil, recipient_id: nil, campaign_id: nil, email_address: nil)
|
|
17
|
-
client.get("/leads/get", camelize_params(
|
|
18
|
+
response = client.get("/leads/get", camelize_params(
|
|
18
19
|
lead_id: lead_id,
|
|
19
20
|
recipient_id: recipient_id,
|
|
20
21
|
campaign_id: campaign_id,
|
|
21
22
|
email_address: email_address
|
|
22
23
|
))
|
|
24
|
+
Models::Lead.new(response)
|
|
23
25
|
end
|
|
24
26
|
|
|
25
27
|
def create(campaign_id:, email_addresses: nil, recipient_ids: nil)
|
|
26
|
-
client.post("/leads/create", camelize_params(
|
|
28
|
+
response = client.post("/leads/create", camelize_params(
|
|
27
29
|
campaign_id: campaign_id,
|
|
28
30
|
email_addresses: email_addresses,
|
|
29
31
|
recipient_ids: recipient_ids
|
|
30
32
|
))
|
|
33
|
+
Models::CreatedLeads.new(response)
|
|
31
34
|
end
|
|
32
35
|
|
|
33
36
|
def close(lead_id: nil, campaign_id: nil, email_address: nil, recipient_id: nil, status: nil)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mailshake
|
|
4
|
+
module Models
|
|
5
|
+
class BaseModel
|
|
6
|
+
class << self
|
|
7
|
+
def has_one(field, klass)
|
|
8
|
+
nested_one[field.to_s] = klass
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def has_many(field, klass)
|
|
12
|
+
nested_many[field.to_s] = klass
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def nested_one
|
|
16
|
+
@nested_one ||= {}
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def nested_many
|
|
20
|
+
@nested_many ||= {}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
attr_reader :data
|
|
25
|
+
|
|
26
|
+
def initialize(data = {})
|
|
27
|
+
@data = data || {}
|
|
28
|
+
define_accessors
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def [](key)
|
|
32
|
+
@data[key]
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_h
|
|
36
|
+
@data
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
40
|
+
@accessors&.key?(method_name.to_s) || super
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def define_accessors
|
|
46
|
+
@accessors = {}
|
|
47
|
+
@data.each do |key, value|
|
|
48
|
+
snake_key = underscore(key.to_s)
|
|
49
|
+
hydrated = hydrate(snake_key, value)
|
|
50
|
+
@accessors[snake_key] = hydrated
|
|
51
|
+
|
|
52
|
+
define_singleton_method(snake_key) { @accessors[snake_key] }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def hydrate(snake_key, value)
|
|
57
|
+
one_klass = self.class.nested_one[snake_key]
|
|
58
|
+
many_klass = self.class.nested_many[snake_key]
|
|
59
|
+
|
|
60
|
+
if one_klass && value.is_a?(Hash)
|
|
61
|
+
one_klass.new(value)
|
|
62
|
+
elsif many_klass && value.is_a?(Array)
|
|
63
|
+
value.map { |item| item.is_a?(Hash) ? many_klass.new(item) : item }
|
|
64
|
+
else
|
|
65
|
+
value
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def underscore(camel_cased_word)
|
|
70
|
+
word = camel_cased_word.to_s.dup
|
|
71
|
+
word.gsub!(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
|
72
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
|
73
|
+
word.tr!("-", "_")
|
|
74
|
+
word.downcase!
|
|
75
|
+
word
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mailshake
|
|
4
|
+
module Models
|
|
5
|
+
class List
|
|
6
|
+
include Enumerable
|
|
7
|
+
|
|
8
|
+
attr_reader :results, :next_token, :data
|
|
9
|
+
|
|
10
|
+
def initialize(data, model_class)
|
|
11
|
+
@data = data || {}
|
|
12
|
+
raw_results = @data["results"] || []
|
|
13
|
+
@results = raw_results.map { |item| item.is_a?(Hash) ? model_class.new(item) : item }
|
|
14
|
+
@next_token = @data["nextToken"]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def each(&block)
|
|
18
|
+
@results.each(&block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def [](key)
|
|
22
|
+
@data[key]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def to_h
|
|
26
|
+
@data
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|