Skip to content

Commit 0a21de3

Browse files
committed
added ContactImportAPI
1 parent 825b934 commit 0a21de3

File tree

5 files changed

+218
-3
lines changed

5 files changed

+218
-3
lines changed

examples/contacts_api.rb

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
contact_lists = Mailtrap::ContactListsAPI.new 3229, client
55
contacts = Mailtrap::ContactsAPI.new 3229, client
66
contact_fields = Mailtrap::ContactFieldsAPI.new 3229, client
7+
contact_imports = Mailtrap::ContactImportsAPI.new 3229, client
78

89
# Set your API credentials as environment variables
910
# export MAILTRAP_API_KEY='your-api-key'
@@ -12,6 +13,7 @@
1213
# contact_lists = Mailtrap::ContactListsAPI.new
1314
# contacts = Mailtrap::ContactsAPI.new
1415
# contact_fields = Mailtrap::ContactFieldsAPI.new
16+
# contact_imports = Mailtrap::ContactImportsAPI.new
1517

1618
# Create new contact list
1719
list = contact_lists.create(name: 'Test List')
@@ -135,8 +137,41 @@
135137
# Delete contact
136138
contacts.delete(contact.id)
137139

138-
# Delete contact list
139-
contact_lists.delete(list.id)
140-
141140
# Delete contact field
142141
contact_fields.delete(field.id)
142+
143+
# Create a new contact import
144+
contact_import = contact_imports.create(
145+
[
146+
{
147+
email: 'imported@example.com',
148+
fields: {
149+
first_name: 'Jane',
150+
},
151+
list_ids_included: [list.id],
152+
list_ids_excluded: []
153+
}
154+
]
155+
)
156+
# => ContactImport.new(
157+
# id: 1,
158+
# status: 'created',
159+
# list_ids: [1],
160+
# created_contacts_count: 1,
161+
# updated_contacts_count: 0,
162+
# contacts_over_limit_count: 0
163+
# )
164+
165+
# Get a contact import by ID
166+
contact_imports.get(contact_import.id)
167+
# => ContactImport.new(
168+
# id: 1,
169+
# status: 'started',
170+
# list_ids: [1],
171+
# created_contacts_count: 1,
172+
# updated_contacts_count: 0,
173+
# contacts_over_limit_count: 0
174+
# )
175+
176+
# Delete contact list
177+
contact_lists.delete(list.id)

lib/mailtrap.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
require_relative 'mailtrap/contacts_api'
99
require_relative 'mailtrap/contact_lists_api'
1010
require_relative 'mailtrap/contact_fields_api'
11+
require_relative 'mailtrap/contact_imports_api'
1112

1213
module Mailtrap
1314
# @!macro api_errors

lib/mailtrap/contact_import.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# frozen_string_literal: true
2+
3+
module Mailtrap
4+
# Data Transfer Object for Contact Import
5+
# @attr_reader id [String] The contact import ID
6+
# @attr_reader status [String] The status of the import (created, started, finished, failed)
7+
# @attr_reader created_contacts_count [Integer, nil] Number of contacts created in this import
8+
# @attr_reader updated_contacts_count [Integer, nil] Number of contacts updated in this import
9+
# @attr_reader contacts_over_limit_count [Integer, nil] Number of contacts over the allowed limit
10+
ContactImport = Struct.new(
11+
:id,
12+
:status,
13+
:created_contacts_count,
14+
:updated_contacts_count,
15+
:contacts_over_limit_count,
16+
keyword_init: true
17+
) do
18+
# @return [Hash] The contact attributes as a hash
19+
def to_h
20+
super.compact
21+
end
22+
end
23+
end

lib/mailtrap/contact_imports_api.rb

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# frozen_string_literal: true
2+
3+
require_relative 'contact_import'
4+
5+
module Mailtrap
6+
class ContactImportsAPI
7+
include BaseAPI
8+
9+
self.supported_options = %i[email fields list_ids_included list_ids_excluded]
10+
11+
self.response_class = ContactImport
12+
13+
# Retrieves a specific contact import
14+
# @param import_id [String] The contact import identifier
15+
# @return [ContactImport] Contact import object
16+
# @!macro api_errors
17+
def get(import_id)
18+
base_get(import_id)
19+
end
20+
21+
# Create contacts import
22+
# @param contacts [Array<Hash>] Array of contact objects to import
23+
# Each contact object should have the following keys:
24+
# - email [String] The contact's email address
25+
# - fields [Hash] Object of fields in the format: field_merge_tag => String, Integer, Float, Boolean, or ISO-8601 date string (yyyy-mm-dd) # rubocop:disable Layout/LineLength
26+
# - list_ids_included [Array<Integer>] List IDs to include the contact in
27+
# - list_ids_excluded [Array<Integer>] List IDs to exclude the contact from
28+
# @return [ContactImport] Created contact list object
29+
# @!macro api_errors
30+
# @raise [ArgumentError] If invalid options are provided
31+
def create(contacts)
32+
contacts.each do |contact|
33+
validate_options!(contact, supported_options)
34+
end
35+
response = client.post(base_path, contacts:)
36+
handle_response(response)
37+
end
38+
39+
private
40+
41+
def base_path
42+
"/api/accounts/#{account_id}/contacts/imports"
43+
end
44+
end
45+
end
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe Mailtrap::ContactImportsAPI do
4+
let(:client) { described_class.new('1111111', Mailtrap::Client.new(api_key: 'correct-api-key')) }
5+
let(:base_url) { 'https://mailtrap.io/api/accounts/1111111' }
6+
7+
describe '#get' do
8+
let(:import_id) { 'import-123' }
9+
let(:expected_response) do
10+
{
11+
'id' => 'import-123',
12+
'status' => 'finished',
13+
'created_contacts_count' => 10,
14+
'updated_contacts_count' => 2,
15+
'contacts_over_limit_count' => 0
16+
}
17+
end
18+
19+
it 'returns a specific contact import' do
20+
stub_request(:get, "#{base_url}/contacts/imports/#{import_id}")
21+
.to_return(
22+
status: 200,
23+
body: expected_response.to_json,
24+
headers: { 'Content-Type' => 'application/json' }
25+
)
26+
27+
response = client.get(import_id)
28+
expect(response).to have_attributes(
29+
id: 'import-123',
30+
status: 'finished',
31+
created_contacts_count: 10,
32+
updated_contacts_count: 2,
33+
contacts_over_limit_count: 0
34+
)
35+
end
36+
37+
it 'raises error when contact import not found' do
38+
stub_request(:get, "#{base_url}/contacts/imports/not-found")
39+
.to_return(
40+
status: 404,
41+
body: { 'error' => 'Not Found' }.to_json,
42+
headers: { 'Content-Type' => 'application/json' }
43+
)
44+
45+
expect { client.get('not-found') }.to raise_error(Mailtrap::Error)
46+
end
47+
end
48+
49+
describe '#create' do
50+
let(:contacts) do
51+
[
52+
{
53+
email: 'example@example.com',
54+
fields: {
55+
fname: 'John',
56+
age: 30,
57+
is_subscribed: true,
58+
birthday: '1990-05-15'
59+
},
60+
list_ids_included: [1, 2],
61+
list_ids_excluded: [3]
62+
}
63+
]
64+
end
65+
let(:expected_response) do
66+
{
67+
'id' => 'import-456',
68+
'status' => 'created',
69+
'created_contacts_count' => 1,
70+
'updated_contacts_count' => 0,
71+
'contacts_over_limit_count' => 0
72+
}
73+
end
74+
75+
it 'creates a new contact import with hash' do
76+
stub_request(:post, "#{base_url}/contacts/imports")
77+
.with(body: { contacts: }.to_json)
78+
.to_return(
79+
status: 200,
80+
body: expected_response.to_json,
81+
headers: { 'Content-Type' => 'application/json' }
82+
)
83+
84+
response = client.create(contacts)
85+
expect(response).to have_attributes(
86+
id: 'import-456',
87+
status: 'created',
88+
created_contacts_count: 1,
89+
updated_contacts_count: 0,
90+
contacts_over_limit_count: 0
91+
)
92+
end
93+
94+
it 'raises error when invalid options are provided' do
95+
invalid_contacts = [contacts.first.merge(foo: 'bar')]
96+
expect { client.create(invalid_contacts) }.to raise_error(ArgumentError, /invalid options are given/)
97+
end
98+
99+
it 'raises error when API returns an error' do
100+
stub_request(:post, "#{base_url}/contacts/imports")
101+
.with(body: { contacts: }.to_json)
102+
.to_return(
103+
status: 422,
104+
body: { 'errors' => { 'email' => ['is invalid'] } }.to_json,
105+
headers: { 'Content-Type' => 'application/json' }
106+
)
107+
108+
expect { client.create(contacts) }.to raise_error(Mailtrap::Error)
109+
end
110+
end
111+
end

0 commit comments

Comments
 (0)