-
Notifications
You must be signed in to change notification settings - Fork 8
Add Inbound Email v2 API support #117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2b9193f
25d78ea
ce34267
afe4039
c28fbe2
e608358
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| require 'mailtrap' | ||
|
|
||
| client = Mailtrap::Client.new(api_key: 'your-api-key') | ||
| folders = Mailtrap::InboundFoldersAPI.new(client) | ||
|
|
||
| # Create a folder | ||
| folder = folders.create(name: 'Support') | ||
| # => #<struct Mailtrap::InboundFolder id=1, name="Support"> | ||
|
|
||
| # List all folders | ||
| folders.list | ||
| # => [#<struct Mailtrap::InboundFolder id=1, name="Support">] | ||
|
|
||
| # Get a folder | ||
| folders.get(folder.id) | ||
| # => #<struct Mailtrap::InboundFolder id=1, name="Support"> | ||
|
|
||
| # Update a folder | ||
| folders.update(folder.id, name: 'Customer Success') | ||
| # => #<struct Mailtrap::InboundFolder id=1, name="Customer Success"> | ||
|
|
||
| # Delete a folder (and all of its inboxes) | ||
| folders.delete(folder.id) | ||
| # => nil |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| require 'mailtrap' | ||
|
|
||
| client = Mailtrap::Client.new(api_key: 'your-api-key') | ||
| inboxes = Mailtrap::InboundInboxesAPI.new(client) | ||
| folder_id = 1 | ||
|
|
||
| # Create an inbox. Omit domain_id for a Mailtrap-hosted inbox; pass it for a custom-domain inbox. | ||
| inbox = inboxes.create(folder_id, name: 'Tickets') | ||
| # => #<struct Mailtrap::InboundInbox id=42, name="Tickets", address="...@inbound-mailtrap.io", domain_id=892> | ||
|
|
||
| # List inboxes in a folder | ||
| inboxes.list(folder_id) | ||
| # => [#<struct Mailtrap::InboundInbox id=42, ...>] | ||
|
|
||
| # Get an inbox | ||
| inboxes.get(folder_id, inbox.id) | ||
| # => #<struct Mailtrap::InboundInbox id=42, ...> | ||
|
|
||
| # Update an inbox | ||
| inboxes.update(folder_id, inbox.id, name: 'Tickets (renamed)') | ||
| # => #<struct Mailtrap::InboundInbox id=42, name="Tickets (renamed)", ...> | ||
|
|
||
| # Delete an inbox | ||
| inboxes.delete(folder_id, inbox.id) | ||
| # => nil |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| require 'mailtrap' | ||
|
|
||
| client = Mailtrap::Client.new(api_key: 'your-api-key') | ||
| messages = Mailtrap::InboundMessagesAPI.new(client) | ||
| inbox_id = 42 | ||
|
|
||
| # List messages in an inbox (cursor-paginated) | ||
| page = messages.list(inbox_id) | ||
| # => #<struct Mailtrap::InboundMessagesListResponse data=[...], total_count=1, last_id=nil> | ||
|
|
||
| # Fetch the next page with the returned cursor | ||
| messages.list(inbox_id, last_id: page.last_id) if page.last_id | ||
|
|
||
| # Get a single message with its body and attachment download URLs | ||
| message = messages.get(inbox_id, page.data.first.id) | ||
| # => #<struct Mailtrap::InboundMessage id="1700000000000123", ...> | ||
|
|
||
| # Reply to the original sender | ||
| messages.reply(inbox_id, message.id, text: 'Thanks for reaching out.') | ||
| # => #<struct Mailtrap::InboundSendResult message_ids=["1a2b3c4d-..."]> | ||
|
|
||
| # Reply to everyone on the original message | ||
| messages.reply_all(inbox_id, message.id, text: 'Looping everyone in.') | ||
| # => #<struct Mailtrap::InboundSendResult message_ids=["1a2b3c4d-..."]> | ||
|
|
||
| # Forward to new recipients (at least one `to` is required) | ||
| messages.forward(inbox_id, message.id, to: [{ email: 'colleague@example.com' }], text: 'Please take a look.') | ||
| # => #<struct Mailtrap::InboundSendResult message_ids=["1a2b3c4d-..."]> | ||
|
|
||
| # Delete a message | ||
| messages.delete(inbox_id, message.id) | ||
| # => nil | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| require 'mailtrap' | ||
|
|
||
| client = Mailtrap::Client.new(api_key: 'your-api-key') | ||
| threads = Mailtrap::InboundThreadsAPI.new(client) | ||
| inbox_id = 42 | ||
|
|
||
| # List threads in an inbox (cursor-paginated) | ||
| page = threads.list(inbox_id) | ||
| # => #<struct Mailtrap::InboundThreadsListResponse data=[...], total_count=1, last_id=nil> | ||
|
|
||
| # Fetch the next page with the returned cursor | ||
| threads.list(inbox_id, last_id: page.last_id) if page.last_id | ||
|
|
||
| # Get a single thread with its messages embedded (oldest first) | ||
| threads.get(inbox_id, page.data.first.id) | ||
| # => #<struct Mailtrap::InboundThread id="1700000000000124", messages=[...]> | ||
|
|
||
| # Delete a thread | ||
| threads.delete(inbox_id, page.data.first.id) | ||
|
mklocek marked this conversation as resolved.
|
||
| # => nil | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Mailtrap | ||
| # Data Transfer Object for an inbound message attachment | ||
| # @see https://docs.mailtrap.io/developers/inbound | ||
| # @attr_reader attachment_id [String] The attachment ID | ||
| # @attr_reader size [Integer, nil] The attachment size in bytes | ||
| # @attr_reader filename [String, nil] The attachment filename | ||
| # @attr_reader content_type [String, nil] The attachment MIME type | ||
| # @attr_reader content_disposition [String, nil] attachment or inline | ||
| # @attr_reader content_id [String, nil] The content ID for inline attachments | ||
| # @attr_reader download_url [String, nil] Signed URL to download the attachment (only when fetched by ID) | ||
| # @attr_reader download_url_expires_at [String, nil] When the download URL expires (only when fetched by ID) | ||
| # rubocop:disable Lint/StructNewOverride -- +size+ is an API field that shadows Struct#size | ||
| InboundAttachment = Struct.new( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW i wonder if it would make more sense to use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good thought — |
||
| :attachment_id, | ||
| :size, | ||
| :filename, | ||
| :content_type, | ||
| :content_disposition, | ||
| :content_id, | ||
| :download_url, | ||
| :download_url_expires_at, | ||
| keyword_init: true | ||
| ) | ||
| # rubocop:enable Lint/StructNewOverride | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Mailtrap | ||
| # Data Transfer Object for an inbound folder | ||
| # @see https://docs.mailtrap.io/developers/inbound | ||
| # @attr_reader id [Integer] The folder ID | ||
| # @attr_reader name [String] The folder name | ||
| InboundFolder = Struct.new( | ||
| :id, | ||
| :name, | ||
| keyword_init: true | ||
| ) | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative 'base_api' | ||
| require_relative 'inbound_folder' | ||
|
|
||
| module Mailtrap | ||
| class InboundFoldersAPI | ||
| include BaseAPI | ||
|
|
||
| self.supported_options = %i[name] | ||
| self.response_class = InboundFolder | ||
|
|
||
| # Inbound is scoped to the token's account, so no account_id is required. | ||
| # @param client [Mailtrap::Client] The client instance | ||
| def initialize(client = Mailtrap::Client.new) | ||
| @client = client | ||
| end | ||
|
|
||
| # Lists all inbound folders in the account | ||
| # @return [Array<InboundFolder>] Array of folders | ||
| # @!macro api_errors | ||
| def list | ||
| base_list | ||
| end | ||
|
|
||
| # Retrieves a specific inbound folder | ||
| # @param folder_id [Integer] The folder ID | ||
| # @return [InboundFolder] Folder object | ||
| # @!macro api_errors | ||
| def get(folder_id) | ||
| base_get(folder_id) | ||
| end | ||
|
|
||
| # Creates a new inbound folder | ||
| # @param [Hash] options The parameters to create | ||
| # @option options [String] :name The folder name | ||
| # @return [InboundFolder] Created folder | ||
| # @!macro api_errors | ||
| # @raise [ArgumentError] If invalid options are provided | ||
| def create(options) | ||
| base_create(options) | ||
| end | ||
|
|
||
| # Updates an inbound folder | ||
| # @param folder_id [Integer] The folder ID | ||
| # @param [Hash] options The parameters to update | ||
| # @option options [String] :name The folder name | ||
| # @return [InboundFolder] Updated folder | ||
| # @!macro api_errors | ||
| # @raise [ArgumentError] If invalid options are provided | ||
| def update(folder_id, options) | ||
| base_update(folder_id, options) | ||
| end | ||
|
|
||
| # Deletes an inbound folder along with all of its inboxes | ||
| # @param folder_id [Integer] The folder ID | ||
| # @return nil | ||
| # @!macro api_errors | ||
| def delete(folder_id) | ||
| base_delete(folder_id) | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def base_path | ||
| '/api/inbound/folders' | ||
| end | ||
| end | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Mailtrap | ||
| # Data Transfer Object for an inbound inbox | ||
| # @see https://docs.mailtrap.io/developers/inbound | ||
| # @attr_reader id [Integer] The inbox ID | ||
| # @attr_reader name [String] The inbox name | ||
| # @attr_reader address [String] The inbox's inbound address | ||
| # @attr_reader domain_id [Integer] The sending domain the inbox is attached to | ||
| InboundInbox = Struct.new( | ||
| :id, | ||
| :name, | ||
| :address, | ||
| :domain_id, | ||
| keyword_init: true | ||
| ) | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require_relative 'base_api' | ||
| require_relative 'inbound_inbox' | ||
|
|
||
| module Mailtrap | ||
| class InboundInboxesAPI | ||
| include BaseAPI | ||
|
|
||
| self.response_class = InboundInbox | ||
|
|
||
| CREATE_OPTIONS = %i[name domain_id].freeze | ||
| UPDATE_OPTIONS = %i[name].freeze | ||
|
|
||
| # Inbound is scoped to the token's account, so no account_id is required. | ||
| # @param client [Mailtrap::Client] The client instance | ||
| def initialize(client = Mailtrap::Client.new) | ||
| @client = client | ||
| end | ||
|
|
||
| # Lists all inboxes in a folder | ||
| # @param folder_id [Integer] The folder ID | ||
| # @return [Array<InboundInbox>] Array of inboxes | ||
| # @!macro api_errors | ||
| def list(folder_id) | ||
| client.get(inboxes_path(folder_id)).map { |item| handle_response(item) } | ||
| end | ||
|
|
||
| # Retrieves a specific inbox | ||
| # @param folder_id [Integer] The folder ID | ||
| # @param inbox_id [Integer] The inbox ID | ||
| # @return [InboundInbox] Inbox object | ||
| # @!macro api_errors | ||
| def get(folder_id, inbox_id) | ||
| handle_response(client.get("#{inboxes_path(folder_id)}/#{inbox_id}")) | ||
| end | ||
|
|
||
| # Creates a new inbox in a folder | ||
| # @param folder_id [Integer] The folder ID | ||
| # @param [Hash] options The parameters to create | ||
| # @option options [String] :name The inbox name | ||
| # @option options [Integer] :domain_id Attach to a custom domain; omit for a Mailtrap-hosted inbox | ||
| # @return [InboundInbox] Created inbox | ||
| # @!macro api_errors | ||
| # @raise [ArgumentError] If invalid options are provided | ||
| def create(folder_id, options) | ||
| validate_options!(options, CREATE_OPTIONS) | ||
| handle_response(client.post(inboxes_path(folder_id), options)) | ||
| end | ||
|
|
||
| # Updates an inbox | ||
| # @param folder_id [Integer] The folder ID | ||
| # @param inbox_id [Integer] The inbox ID | ||
| # @param [Hash] options The parameters to update | ||
| # @option options [String] :name The inbox name | ||
| # @return [InboundInbox] Updated inbox | ||
| # @!macro api_errors | ||
| # @raise [ArgumentError] If invalid options are provided | ||
| def update(folder_id, inbox_id, options) | ||
| validate_options!(options, UPDATE_OPTIONS) | ||
| handle_response(client.patch("#{inboxes_path(folder_id)}/#{inbox_id}", options)) | ||
| end | ||
|
|
||
| # Deletes an inbox | ||
| # @param folder_id [Integer] The folder ID | ||
| # @param inbox_id [Integer] The inbox ID | ||
| # @return nil | ||
| # @!macro api_errors | ||
| def delete(folder_id, inbox_id) | ||
| client.delete("#{inboxes_path(folder_id)}/#{inbox_id}") | ||
| end | ||
|
|
||
| private | ||
|
|
||
| def inboxes_path(folder_id) | ||
| "/api/inbound/folders/#{folder_id}/inboxes" | ||
| end | ||
| end | ||
| end |
Uh oh!
There was an error while loading. Please reload this page.