Skip to content

Commit 9871da8

Browse files
committed
Add Contacts API functionality
1 parent 8dc916f commit 9871da8

File tree

7 files changed

+721
-0
lines changed

7 files changed

+721
-0
lines changed

examples/contact.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
require 'mailtrap'
2+
account_id = 1_111_111
3+
client = Mailtrap::Client.new(api_key: 'your-api-key')
4+
5+
contact_list = Mailtrap::ContactListsAPI.new(account_id, client)
6+
list = contact_list.create(name: 'Test List')
7+
8+
contacts = Mailtrap::ContactsAPI.new(account_id, client)
9+
contact = contacts.create(email: '[email protected]', fields: { first_name: 'John Doe' }, list_ids: [list.id])
10+
puts "Created Contact: #{contact.id}"
11+
12+
contact = contacts.get(contact.id)
13+
puts "Contact: #{contact.email}"
14+
15+
contact = contacts.update(contact.id, email: '[email protected]', fields: { first_name: 'Jane Doe' }, list_ids: [2])
16+
puts "Updated Contact: #{contact.data.email}"
17+
18+
contacts.delete(contact.data.id)
19+
puts 'Contact deleted'
20+
21+
lists = contact_list.list
22+
puts "Contact Lists: #{lists}"
23+
24+
contact_list.update(list.id, name: 'Test List Updated')
25+
26+
list = contact_list.get(list.id)
27+
puts "Contact List: #{list.name}"
28+
29+
contact_list.delete(list.id)
30+
puts 'Contact List deleted'

lib/mailtrap.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33
require_relative 'mailtrap/action_mailer' if defined? ActionMailer
44
require_relative 'mailtrap/mail'
55
require_relative 'mailtrap/errors'
6+
require_relative 'mailtrap/api'
67
require_relative 'mailtrap/version'
78
require_relative 'mailtrap/template'
9+
require_relative 'mailtrap/contact'
10+
require_relative 'mailtrap/contact_list'
811

912
module Mailtrap; end

lib/mailtrap/api.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
module Mailtrap
2+
module API
3+
private
4+
5+
def prepare_request(request, request_class)
6+
normalised = request.is_a?(request_class) ? request : build_entity(request, request_class)
7+
normalised.to_h
8+
end
9+
10+
def build_entity(options, response_class)
11+
response_class.new(options.slice(*response_class.members))
12+
end
13+
end
14+
end

lib/mailtrap/contact.rb

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# frozen_string_literal: true
2+
3+
module Mailtrap
4+
# Data Transfer Object for Contact Create Request
5+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/284bcc8fd846f-contact-create-request
6+
# @attr_reader email [String] The contact's email address (required)
7+
# @attr_reader fields [Hash] Object of fields with merge tags
8+
# @attr_reader list_ids [Array<Integer>] Array of list IDs
9+
ContactCreateRequest = Struct.new(:email, :fields, :list_ids, keyword_init: true) do
10+
# @return [Hash] The contact request attributes as a hash
11+
def to_h
12+
super.compact
13+
end
14+
end
15+
16+
# Data Transfer Object for Contact Update Request
17+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/d3efb09dbeda8-contact-update-request
18+
# @attr_reader email [String] The contact's email address (required)
19+
# @attr_reader fields [Hash] Object of fields with merge tags
20+
# @attr_reader list_ids_included [Array<Integer>] Array of list IDs to include
21+
# @attr_reader list_ids_excluded [Array<Integer>] Array of list IDs to exclude
22+
# @attr_reader unsubscribed [Boolean] Whether to unsubscribe the contact
23+
ContactUpdateRequest = Struct.new(:email, :fields, :list_ids_included, :list_ids_excluded, :unsubscribed,
24+
keyword_init: true) do
25+
# @return [Hash] The contact request attributes as a hash
26+
def to_h
27+
super.compact
28+
end
29+
end
30+
31+
# Data Transfer Object for Contact
32+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/220a54e31e5ca-contact
33+
# @attr_reader id [String] The contact ID
34+
# @attr_reader email [String] The contact's email address
35+
# @attr_reader fields [Hash] Object of fields with merge tags
36+
# @attr_reader list_ids [Array<Integer>] Array of list IDs
37+
# @attr_reader status [String] The contact status (subscribed/unsubscribed)
38+
# @attr_reader created_at [Integer] The creation timestamp
39+
# @attr_reader updated_at [Integer] The last update timestamp
40+
Contact = Struct.new(
41+
:id,
42+
:email,
43+
:fields,
44+
:list_ids,
45+
:status,
46+
:created_at,
47+
:updated_at,
48+
keyword_init: true
49+
) do
50+
# @return [Hash] The contact attributes as a hash
51+
def to_h
52+
super.compact
53+
end
54+
end
55+
56+
# Data Transfer Object for Contact Update Response
57+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/16eab4fff9740-contact-update-response
58+
# @attr_reader action [String] The performed action (created/updated)
59+
# @attr_reader data [Contact] The contact data
60+
ContactUpdateResponse = Struct.new(:action, :data, keyword_init: true) do
61+
def initialize(*)
62+
super
63+
self.data = Contact.new(data) if data.is_a?(Hash)
64+
end
65+
66+
# @return [Hash] The response attributes as a hash
67+
def to_h
68+
super.compact
69+
end
70+
end
71+
72+
class ContactsAPI
73+
include Mailtrap::API
74+
75+
def initialize(account_id, client = Mailtrap::Client.new)
76+
@account_id = account_id
77+
@client = client
78+
end
79+
80+
# Retrieves a specific contact
81+
# @param contact_id [String] The contact identifier, which can be either a UUID or an email address
82+
# @return [Contact] Contact object
83+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
84+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
85+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
86+
# @raise [Mailtrap::RateLimitError] If too many requests are made
87+
def get(contact_id)
88+
response = @client.get("#{base_path}/#{contact_id}")
89+
build_entity(response[:data], Contact)
90+
end
91+
92+
# Creates a new contact
93+
# @param request [ContactCreateRequest, Hash] The contact create request object or a hash with the same attributes
94+
# @return [Contact] Created contact object
95+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
96+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
97+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
98+
# @raise [Mailtrap::RateLimitError] If too many requests are made
99+
def create(request)
100+
response = @client.post(base_path, { contact: prepare_request(request, ContactCreateRequest) })
101+
build_entity(response[:data], Contact)
102+
end
103+
104+
# Updates an existing contact
105+
# @param contact_id [String] The contact ID
106+
# @param request [ContactUpdateRequest, Hash] The contact update request object or a hash with the same attributes
107+
# @return [ContactUpdateResponse] Response containing the action performed and contact data
108+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
109+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
110+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
111+
# @raise [Mailtrap::RateLimitError] If too many requests are made
112+
def update(contact_id, request)
113+
response = @client.patch(
114+
"#{base_path}/#{contact_id}",
115+
{ contact: prepare_request(request, ContactUpdateRequest) }
116+
)
117+
build_entity(response, ContactUpdateResponse)
118+
end
119+
120+
# Deletes a contact
121+
# @param contact_id [String] The contact ID
122+
# @return nil
123+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
124+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
125+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
126+
# @raise [Mailtrap::RateLimitError] If too many requests are made
127+
def delete(contact_id)
128+
@client.delete("#{base_path}/#{contact_id}")
129+
end
130+
131+
private
132+
133+
def base_path
134+
"/api/accounts/#{@account_id}/contacts"
135+
end
136+
end
137+
end

lib/mailtrap/contact_list.rb

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# frozen_string_literal: true
2+
3+
module Mailtrap
4+
# Data Transfer Object for Contact List Create Request
5+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/e3bba0bfa185e-create-contact-list
6+
# @attr_reader name [String] The name of the contact list (required)
7+
ContactListRequest = Struct.new(:name, keyword_init: true) do
8+
# @return [Hash] The contact list request attributes as a hash
9+
def to_h
10+
super.compact
11+
end
12+
end
13+
14+
# Data Transfer Object for Contact List
15+
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/6ec7a37234af2-contact-list
16+
# @attr_reader id [Integer] The contact list ID
17+
# @attr_reader name [String] The name of the contact list
18+
ContactList = Struct.new(:id, :name, keyword_init: true) do
19+
# @return [Hash] The contact list attributes as a hash
20+
def to_h
21+
super.compact
22+
end
23+
end
24+
25+
class ContactListsAPI
26+
include Mailtrap::API
27+
28+
def initialize(account_id, client = Mailtrap::Client.new)
29+
@account_id = account_id
30+
@client = client
31+
end
32+
33+
# Retrieves a specific contact list
34+
# @param list_id [Integer] The contact list identifier
35+
# @return [ContactList] Contact list object
36+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
37+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
38+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
39+
# @raise [Mailtrap::RateLimitError] If too many requests are made
40+
def get(list_id)
41+
response = @client.get("#{base_path}/#{list_id}")
42+
build_entity(response, ContactList)
43+
end
44+
45+
# Creates a new contact list
46+
# @param request [ContactListRequest, Hash] The contact list create request object or a hash
47+
# @return [ContactList] Created contact list object
48+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
49+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
50+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
51+
# @raise [Mailtrap::RateLimitError] If too many requests are made
52+
def create(request)
53+
response = @client.post(base_path, prepare_request(request, ContactListRequest))
54+
build_entity(response, ContactList)
55+
end
56+
57+
# Updates an existing contact list
58+
# @param list_id [Integer] The contact list ID
59+
# @param request [ContactListRequest, Hash] The contact list update request object or a hash
60+
# @return [ContactList] Updated contact list object
61+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
62+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
63+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
64+
# @raise [Mailtrap::RateLimitError] If too many requests are made
65+
def update(list_id, request)
66+
response = @client.patch(
67+
"#{base_path}/#{list_id}", prepare_request(request, ContactListRequest)
68+
)
69+
build_entity(response, ContactList)
70+
end
71+
72+
# Deletes a contact list
73+
# @param list_id [Integer] The contact list ID
74+
# @return nil
75+
# @raise [Mailtrap::Error] If the API request fails with a client or server error
76+
# @raise [Mailtrap::AuthorizationError] If the API key is invalid
77+
# @raise [Mailtrap::RejectionError] If the server refuses to process the request
78+
# @raise [Mailtrap::RateLimitError] If too many requests are made
79+
def delete(list_id)
80+
@client.delete("#{base_path}/#{list_id}")
81+
end
82+
83+
# Lists all contact lists for the account
84+
# @return [Array<ContactList>] Array of contact list objects
85+
def list
86+
response = @client.get(base_path)
87+
response.map { |list| build_entity(list, ContactList) }
88+
end
89+
90+
private
91+
92+
def base_path
93+
"/api/accounts/#{@account_id}/contacts/lists"
94+
end
95+
end
96+
end

0 commit comments

Comments
 (0)