Module: Mailblastr::Contacts
- Defined in:
- lib/mailblastr/contacts.rb
Overview
Contacts are DOMAIN-FIRST: each sending domain has its own contact pool,
so the flat /contacts API takes domain (required on create/list). The
nested audience variants (audience_id:) derive the pool from the path.
Class Method Summary collapse
-
.add_to_segment(contact_id, segment_id) ⇒ Object
Add a contact to a segment.
-
.batch(params) ⇒ Object
Bulk-import contacts from an array (upsert by email; max 10,000).
-
.create(params) ⇒ Object
Create a contact.
-
.create_import_upload(params) ⇒ Object
Mint a presigned direct-upload URL for a CSV too large to inline (up to 256 MB).
-
.delete(params) ⇒ Object
Delete a contact.
-
.get(params) ⇒ Object
Retrieve a contact by id (exact) or by email.
-
.get_topics(contact_id, params = {}) ⇒ Object
Get a contact's topic subscriptions.
-
.import(params) ⇒ Object
Bulk-import contacts from CSV (header row optional; upsert by email).
-
.list(params = {}) ⇒ Object
List contacts.
-
.list_segments(contact_id, params = {}) ⇒ Object
List the segments a contact belongs to — items carry id/name/created_at only, not the full segment object.
-
.remove_from_segment(contact_id, segment_id) ⇒ Object
Remove a contact from a segment.
-
.update(params) ⇒ Object
Update a contact (id or email).
-
.update_topics(contact_id, params) ⇒ Object
Update a contact's topic subscriptions.
Class Method Details
.add_to_segment(contact_id, segment_id) ⇒ Object
Add a contact to a segment. POST /contacts/:id/segments/:segment_id
138 139 140 |
# File 'lib/mailblastr/contacts.rb', line 138 def add_to_segment(contact_id, segment_id) Client.request(:post, "/contacts/#{Client.path_escape(contact_id)}/segments/#{Client.path_escape(segment_id)}") end |
.batch(params) ⇒ Object
Bulk-import contacts from an array (upsert by email; max 10,000). POST /audiences/:id/contacts/batch Contacts.batch({ audience_id: "aud_1", contacts: [{ email: "a@b.com" }], on_conflict: "skip" })
86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/mailblastr/contacts.rb', line 86 def batch(params) audience_id = Client.opt(params, :audience_id) query = {} on_conflict = Client.opt(params, :on_conflict) query[:on_conflict] = on_conflict if on_conflict Client.request( :post, "/audiences/#{Client.path_escape(audience_id)}/contacts/batch", body: { contacts: Client.opt(params, :contacts) }, query: query ) end |
.create(params) ⇒ Object
Create a contact. POST /contacts (flat, domain required) or
POST /audiences/:id/contacts when audience_id is given.
Mailblastr::Contacts.create({ domain: "yourdomain.com", email: "a@b.com" })
Mailblastr::Contacts.create({ audience_id: "aud_1", email: "a@b.com" })
13 14 15 16 17 18 19 20 21 22 |
# File 'lib/mailblastr/contacts.rb', line 13 def create(params) audience_id = Client.opt(params, :audience_id) if audience_id body = Client.without(params, :audience_id, :domain) Client.request(:post, "/audiences/#{Client.path_escape(audience_id)}/contacts", body: body) else Client.require_domain!(params, "Contacts.create (flat /contacts API)") Client.request(:post, "/contacts", body: Client.without(params, :audience_id)) end end |
.create_import_upload(params) ⇒ Object
Mint a presigned direct-upload URL for a CSV too large to inline
(up to 256 MB). Upload the file to upload_url, then pass the returned
storage_key to Contacts.import.
POST /audiences/:id/contacts/import/upload — params: { filename:, size: }
The upload_url is a bearer credential — do not log it.
128 129 130 131 132 133 134 135 |
# File 'lib/mailblastr/contacts.rb', line 128 def create_import_upload(params) audience_id = Client.opt(params, :audience_id) Client.request( :post, "/audiences/#{Client.path_escape(audience_id)}/contacts/import/upload", body: Client.without(params, :audience_id) ) end |
.delete(params) ⇒ Object
Delete a contact. DELETE /contacts/:id (pass domain when id is an
email), or the nested route when audience_id is given.
73 74 75 76 77 78 79 80 81 |
# File 'lib/mailblastr/contacts.rb', line 73 def delete(params) id = Client.path_escape(Client.opt(params, :id)) audience_id = Client.opt(params, :audience_id) return Client.request(:delete, "/audiences/#{Client.path_escape(audience_id)}/contacts/#{id}") if audience_id domain = Client.opt(params, :domain) query = domain ? { domain: domain } : nil Client.request(:delete, "/contacts/#{id}", query: query) end |
.get(params) ⇒ Object
Retrieve a contact by id (exact) or by email. An email can exist in
several domains' pools, so pass domain to pick the pool.
Contacts.get({ id: "cont_1" })
Contacts.get({ id: "a@b.com", domain: "yourdomain.com" })
Contacts.get({ id: "cont_1", audience_id: "aud_1" })
29 30 31 32 33 34 35 36 37 |
# File 'lib/mailblastr/contacts.rb', line 29 def get(params) id = Client.path_escape(Client.opt(params, :id)) audience_id = Client.opt(params, :audience_id) return Client.request(:get, "/audiences/#{Client.path_escape(audience_id)}/contacts/#{id}") if audience_id domain = Client.opt(params, :domain) query = domain ? { domain: domain } : nil Client.request(:get, "/contacts/#{id}", query: query) end |
.get_topics(contact_id, params = {}) ⇒ Object
Get a contact's topic subscriptions. GET /contacts/:id/topics
158 159 160 161 162 163 164 |
# File 'lib/mailblastr/contacts.rb', line 158 def get_topics(contact_id, params = {}) Client.request( :get, "/contacts/#{Client.path_escape(contact_id)}/topics", query: Client.pagination(params) ) end |
.import(params) ⇒ Object
Bulk-import contacts from CSV (header row optional; upsert by email).
Non-builtin columns auto-register as custom properties unless
create_properties: false. Pass segment_id to also add every
imported email to one of this audience's segments.
POST /audiences/:id/contacts/import
Inline CSV text (capped at 5 MB and 10,000 rows):
Contacts.import({ audience_id: "aud_1", csv: "email\na@b.com" })
Or a file already uploaded via create_import_upload (no row cap — the
overflow past your contact limit comes back as limit_skipped):
Contacts.import({ audience_id: "aud_1", storage_key: key })
110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/mailblastr/contacts.rb', line 110 def import(params) audience_id = Client.opt(params, :audience_id) query = Client.filters(params, :on_conflict, :segment_id) query[:create_properties] = "false" if Client.opt(params, :create_properties) == false body = Client.filters(params, :csv, :file_name, :storage_key) Client.request( :post, "/audiences/#{Client.path_escape(audience_id)}/contacts/import", body: body, query: query ) end |
.list(params = {}) ⇒ Object
List contacts. Flat /contacts requires domain (names the pool);
pass audience_id instead to use the nested API. segment_id
filters either variant; limit/after/before paginate.
42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/mailblastr/contacts.rb', line 42 def list(params = {}) audience_id = Client.opt(params, :audience_id) query = Client.pagination(params) segment_id = Client.opt(params, :segment_id) query[:segment_id] = segment_id if segment_id if audience_id Client.request(:get, "/audiences/#{Client.path_escape(audience_id)}/contacts", query: query) else query = { domain: Client.require_domain!(params, "Contacts.list (flat /contacts API)") }.merge(query) Client.request(:get, "/contacts", query: query) end end |
.list_segments(contact_id, params = {}) ⇒ Object
List the segments a contact belongs to — items carry id/name/created_at only, not the full segment object. GET /contacts/:id/segments
149 150 151 152 153 154 155 |
# File 'lib/mailblastr/contacts.rb', line 149 def list_segments(contact_id, params = {}) Client.request( :get, "/contacts/#{Client.path_escape(contact_id)}/segments", query: Client.pagination(params) ) end |
.remove_from_segment(contact_id, segment_id) ⇒ Object
Remove a contact from a segment. DELETE /contacts/:id/segments/:segment_id
143 144 145 |
# File 'lib/mailblastr/contacts.rb', line 143 def remove_from_segment(contact_id, segment_id) Client.request(:delete, "/contacts/#{Client.path_escape(contact_id)}/segments/#{Client.path_escape(segment_id)}") end |
.update(params) ⇒ Object
Update a contact (id or email). PATCH /contacts/:id, or the nested
route when audience_id is given. On the flat API pass domain when
id is an email (disambiguates across pools).
Contacts.update({ id: "cont_1", unsubscribed: true })
60 61 62 63 64 65 66 67 68 69 |
# File 'lib/mailblastr/contacts.rb', line 60 def update(params) id = Client.path_escape(Client.opt(params, :id)) audience_id = Client.opt(params, :audience_id) if audience_id body = Client.without(params, :audience_id, :domain, :id) Client.request(:patch, "/audiences/#{Client.path_escape(audience_id)}/contacts/#{id}", body: body) else Client.request(:patch, "/contacts/#{id}", body: Client.without(params, :audience_id, :id)) end end |
.update_topics(contact_id, params) ⇒ Object
Update a contact's topic subscriptions. PATCH /contacts/:id/topics Contacts.update_topics("cont_1", { topics: [{ id: "top_1", subscription: "opt_in" }] })
168 169 170 |
# File 'lib/mailblastr/contacts.rb', line 168 def update_topics(contact_id, params) Client.request(:patch, "/contacts/#{Client.path_escape(contact_id)}/topics", body: params) end |