Skip to content

Suppressions Api #52

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions examples/suppressions_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require 'mailtrap'

client = Mailtrap::Client.new(api_key: 'your-api-key')
suppressions = Mailtrap::SuppressionsAPI.new 3229, client
Comment on lines +3 to +4
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Remove hardcoded credentials from example.

The example contains hardcoded API credentials which could be accidentally committed or copied by users. Consider using placeholder text or environment variables by default.

-client = Mailtrap::Client.new(api_key: 'your-api-key')
-suppressions = Mailtrap::SuppressionsAPI.new 3229, client
+# Set your API credentials as environment variables
+# export MAILTRAP_API_KEY='your-api-key'
+# export MAILTRAP_ACCOUNT_ID=your-account-id
+suppressions = Mailtrap::SuppressionsAPI.new
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
client = Mailtrap::Client.new(api_key: 'your-api-key')
suppressions = Mailtrap::SuppressionsAPI.new 3229, client
# Set your API credentials as environment variables
# export MAILTRAP_API_KEY='your-api-key'
# export MAILTRAP_ACCOUNT_ID=your-account-id
suppressions = Mailtrap::SuppressionsAPI.new
🤖 Prompt for AI Agents
In examples/suppressions_api.rb around lines 3 to 4, the API key is hardcoded
directly in the code, which risks accidental exposure. Replace the hardcoded API
key string with a placeholder text like 'your-api-key' or fetch it from an
environment variable to avoid embedding sensitive credentials in the example.


# Set your API credentials as environment variables
# export MAILTRAP_API_KEY='your-api-key'
# export MAILTRAP_ACCOUNT_ID=your-account-id
#
# suppressions = Mailtrap::SuppressionsAPI.new

# Get all suppressions
list = suppressions.list

# Delete a suppression
suppressions.delete(list.first.id)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add nil check before accessing list.first.

The code assumes the suppressions list is not empty, which could cause a NoMethodError if no suppressions exist.

-suppressions.delete(list.first.id)
+suppressions.delete(list.first.id) if list.any?
🤖 Prompt for AI Agents
In examples/suppressions_api.rb at line 16, add a nil check before accessing
list.first to prevent a NoMethodError when the suppressions list is empty.
Modify the code to verify that list.first is not nil before calling .id and
passing it to suppressions.delete, ensuring safe handling of empty lists.

2 changes: 2 additions & 0 deletions lib/mailtrap.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
require_relative 'mailtrap/mail'
require_relative 'mailtrap/errors'
require_relative 'mailtrap/version'
require_relative 'mailtrap/base_api'
require_relative 'mailtrap/email_templates_api'
require_relative 'mailtrap/suppressions_api'

module Mailtrap
# @!macro api_errors
Expand Down
30 changes: 30 additions & 0 deletions lib/mailtrap/base_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

module Mailtrap
class BaseAPI
attr_reader :account_id, :client

# @param account_id [Integer] The account ID
# @param client [Mailtrap::Client] The client instance
# @raise [ArgumentError] If account_id is nil
def initialize(account_id = ENV.fetch('MAILTRAP_ACCOUNT_ID'), client = Mailtrap::Client.new)
raise ArgumentError, 'account_id is required' if account_id.nil?

@account_id = account_id
@client = client
end

private

def validate_options!(options, supported_options)
invalid_options = options.keys - supported_options
return if invalid_options.empty?

raise ArgumentError, "invalid options are given: #{invalid_options}, supported_options: #{supported_options}"
end

def build_entity(options, response_class)
response_class.new(options.slice(*response_class.members))
end
end
end
8 changes: 5 additions & 3 deletions lib/mailtrap/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,11 @@ def send(mail)

# Performs a GET request to the specified path
# @param path [String] The request path
# @param query_params [Hash] Query parameters to append to the URL (optional)
# @return [Hash, nil] The JSON response
# @!macro api_errors
def get(path)
perform_request(:get, general_api_host, path)
def get(path, query_params = {})
perform_request(:get, general_api_host, path, nil, query_params)
end

# Performs a POST request to the specified path
Expand Down Expand Up @@ -121,9 +122,10 @@ def send_path
"/api/send#{sandbox ? "/#{inbox_id}" : ""}"
end

def perform_request(method, host, path, body = nil)
def perform_request(method, host, path, body = nil, query_params = {})
http_client = http_client_for(host)
request = setup_request(method, path, body)
request.query = URI.encode_www_form(query_params) if query_params.any?
response = http_client.request(request)
handle_response(response)
end
Expand Down
37 changes: 7 additions & 30 deletions lib/mailtrap/email_templates_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,16 @@
require_relative 'email_template'

module Mailtrap
class EmailTemplatesAPI
class EmailTemplatesAPI < BaseAPI
SUPPORTED_OPTIONS = %i[name subject category body_html body_text].freeze
private_constant :SUPPORTED_OPTIONS

attr_reader :account_id, :client

# @param account_id [Integer] The account ID
# @param client [Mailtrap::Client] The client instance
# @raise [ArgumentError] If account_id is nil
def initialize(account_id = ENV.fetch('MAILTRAP_ACCOUNT_ID'), client = Client.new)
raise ArgumentError, 'account_id is required' if account_id.nil?

@account_id = account_id
@client = client
end

# Lists all email templates for the account
# @return [Array<EmailTemplate>] Array of template objects
# @!macro api_errors
def list
response = client.get(base_path)
response.map { |template| build_email_template(template) }
response.map { |template| build_entity(template, EmailTemplate) }
end

# Retrieves a specific email template
Expand All @@ -33,7 +21,7 @@ def list
# @!macro api_errors
def get(template_id)
response = client.get("#{base_path}/#{template_id}")
build_email_template(response)
build_entity(response, EmailTemplate)
end

# Creates a new email template
Expand All @@ -47,10 +35,10 @@ def get(template_id)
# @!macro api_errors
# @raise [ArgumentError] If invalid options are provided
def create(options)
validate_options!(options)
validate_options!(options, SUPPORTED_OPTIONS)

response = client.post(base_path, email_template: options)
build_email_template(response)
build_entity(response, EmailTemplate)
end

# Updates an existing email template
Expand All @@ -65,10 +53,10 @@ def create(options)
# @!macro api_errors
# @raise [ArgumentError] If invalid options are provided
def update(template_id, options)
validate_options!(options)
validate_options!(options, SUPPORTED_OPTIONS)

response = client.patch("#{base_path}/#{template_id}", email_template: options)
build_email_template(response)
build_entity(response, EmailTemplate)
end

# Deletes an email template
Expand All @@ -81,19 +69,8 @@ def delete(template_id)

private

def build_email_template(options)
EmailTemplate.new(options.slice(*EmailTemplate.members))
end

def base_path
"/api/accounts/#{account_id}/email_templates"
end

def validate_options!(options)
invalid_options = options.keys - SUPPORTED_OPTIONS
return if invalid_options.empty?

raise ArgumentError, "invalid options are given: #{invalid_options}, supported_options: #{SUPPORTED_OPTIONS}"
end
end
end
46 changes: 46 additions & 0 deletions lib/mailtrap/suppression.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# frozen_string_literal: true

module Mailtrap
# Data Transfer Object for Suppression
# @see https://api-docs.mailtrap.io/docs/mailtrap-api-docs/f8144826d885a-list-and-search-suppressions
# @attr_reader id [String] The suppression UUID
# @attr_reader type [String] The suppression type
# @attr_reader created_at [String] The creation timestamp
# @attr_reader email [String] The email address
# @attr_reader sending_stream [String] The sending stream
# @attr_reader domain_name [String, nil] The domain name
# @attr_reader message_bounce_category [String, nil] The bounce category
# @attr_reader message_category [String, nil] The message category
# @attr_reader message_client_ip [String, nil] The client IP
# @attr_reader message_created_at [String, nil] The message creation timestamp
# @attr_reader message_esp_response [String, nil] The ESP response
# @attr_reader message_esp_server_type [String, nil] The ESP server type
# @attr_reader message_outgoing_ip [String, nil] The outgoing IP
# @attr_reader message_recipient_mx_name [String, nil] The recipient MX name
# @attr_reader message_sender_email [String, nil] The sender email
# @attr_reader message_subject [String, nil] The message subject
Suppression = Struct.new(
:id,
:type,
:created_at,
:email,
:sending_stream,
:domain_name,
:message_bounce_category,
:message_category,
:message_client_ip,
:message_created_at,
:message_esp_response,
:message_esp_server_type,
:message_outgoing_ip,
:message_recipient_mx_name,
:message_sender_email,
:message_subject,
keyword_init: true
) do
# @return [Hash] The suppression attributes as a hash
def to_h
super.compact
end
end
end
33 changes: 33 additions & 0 deletions lib/mailtrap/suppressions_api.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require_relative 'suppression'

module Mailtrap
class SuppressionsAPI < BaseAPI
# Lists all suppressions for the account
# @param email [String] Email address to filter suppressions (optional)
# @return [Array<Suppression>] Array of suppression objects
# @!macro api_errors
def list(email: nil)
query_params = {}
query_params[:email] = email if email

response = client.get(base_path, query_params)
response.map { |suppression| build_entity(suppression, Suppression) }
end

# Deletes a suppression
# @param suppression_id [String] The suppression UUID
# @return nil
# @!macro api_errors
def delete(suppression_id)
client.delete("#{base_path}/#{suppression_id}")
end

private

def base_path
"/api/accounts/#{account_id}/suppressions"
end
end
end
Loading