-
Notifications
You must be signed in to change notification settings - Fork 7
Add Sandbox messages API #82
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
base: main
Are you sure you want to change the base?
Changes from all commits
e3c1b61
ee4c726
8b0a93b
17409ee
80133b0
3d454fe
53d8e59
c352df3
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,54 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module Mailtrap | ||
| # Data Transfer Object for Sandbox Message | ||
| # @see https://docs.mailtrap.io/developers/email-sandbox/email-sandbox-api/messages | ||
| # @attr_reader id [Integer] The message ID | ||
| # @attr_reader inbox_id [Integer] The inbox ID | ||
| # @attr_reader subject [String] The message subject | ||
| # @attr_reader sent_at [String] The timestamp when the message was sent | ||
| # @attr_reader from_email [String] The sender's email address | ||
| # @attr_reader from_name [String] The sender's name | ||
| # @attr_reader to_email [String] The recipient's email address | ||
| # @attr_reader to_name [String] The recipient's name | ||
| # @attr_reader email_size [Integer] The size of the email in bytes | ||
| # @attr_reader is_read [Boolean] Whether the message has been read | ||
| # @attr_reader created_at [String] The timestamp when the message was created | ||
| # @attr_reader updated_at [String] The timestamp when the message was last updated | ||
| # @attr_reader html_body_size [Integer] The size of the HTML body in bytes | ||
| # @attr_reader text_body_size [Integer] The size of the text body in bytes | ||
| # @attr_reader human_size [String] The human-readable size of the email | ||
| # @attr_reader html_path [String] The path to the HTML version of the email | ||
| # @attr_reader txt_path [String] The path to the text version of the email | ||
| # @attr_reader raw_path [String] The path to the raw version of the email | ||
| # @attr_reader download_path [String] The path to download the email | ||
| # @attr_reader html_source_path [String] The path to the HTML source of the email | ||
| # @attr_reader blacklists_report_info [Boolean] Information about blacklists report | ||
| # @attr_reader smtp_information [Hash] Information about SMTP | ||
| # | ||
| SandboxMessage = Struct.new( | ||
| :id, | ||
| :inbox_id, | ||
| :subject, | ||
| :sent_at, | ||
| :from_email, | ||
| :from_name, | ||
| :to_email, | ||
| :to_name, | ||
| :email_size, | ||
| :is_read, | ||
| :created_at, | ||
| :updated_at, | ||
| :html_body_size, | ||
| :text_body_size, | ||
| :human_size, | ||
| :html_path, | ||
| :txt_path, | ||
| :raw_path, | ||
| :download_path, | ||
| :html_source_path, | ||
| :blacklists_report_info, | ||
| :smtp_information, | ||
| keyword_init: true | ||
| ) | ||
| end |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,154 @@ | ||||||||||||||||||||||||||||||
| # frozen_string_literal: true | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| require_relative 'base_api' | ||||||||||||||||||||||||||||||
| require_relative 'sandbox_message' | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| module Mailtrap | ||||||||||||||||||||||||||||||
| class SandboxMessagesAPI | ||||||||||||||||||||||||||||||
| include BaseAPI | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| attr_reader :account_id, :inbox_id, :client | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| self.supported_options = %i[is_read] | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| self.response_class = SandboxMessage | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # @param inbox_id [Integer] The inbox ID | ||||||||||||||||||||||||||||||
| # @param account_id [Integer] The account ID | ||||||||||||||||||||||||||||||
| # @param client [Mailtrap::Client] The client instance | ||||||||||||||||||||||||||||||
| # @raise [ArgumentError] If account_id is nil | ||||||||||||||||||||||||||||||
| def initialize(inbox_id, account_id = ENV.fetch('MAILTRAP_ACCOUNT_ID'), client = Mailtrap::Client.new) | ||||||||||||||||||||||||||||||
| raise ArgumentError, 'account_id is required' if account_id.nil? | ||||||||||||||||||||||||||||||
| raise ArgumentError, 'inbox_id is required' if inbox_id.nil? | ||||||||||||||||||||||||||||||
|
Comment on lines
+16
to
+22
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. 🧩 Analysis chain🏁 Script executed: cat -n lib/mailtrap/sandbox_messages_api.rb | head -30Repository: mailtrap/mailtrap-ruby Length of output: 1217 🏁 Script executed: # Let's also check if there are any other references to account_id handling
rg "account_id" lib/mailtrap/sandbox_messages_api.rb -A 2 -B 2Repository: mailtrap/mailtrap-ruby Length of output: 806 🏁 Script executed: # Verify the behavior of ENV.fetch vs ENV[]
# ENV.fetch raises KeyError if key doesn't exist
# ENV[] returns nil if key doesn't exist
python3 << 'EOF'
# Simulate Ruby's ENV.fetch behavior
# ENV.fetch('KEY') raises KeyError if not found
# ENV['KEY'] returns nil if not found
print("ENV.fetch behavior: raises KeyError when env var not found")
print("ENV['KEY'] behavior: returns nil when env var not found")
print("\nThe review claim:")
print("- Using ENV.fetch means KeyError is raised (not ArgumentError)")
print("- The `@raise` documentation claims ArgumentError will be raised")
print("- This is a mismatch between documented behavior and actual behavior")
EOFRepository: mailtrap/mailtrap-ruby Length of output: 394 🏁 Script executed: # Check YARD documentation in the file
rg "@raise" lib/mailtrap/sandbox_messages_api.rb -B 5 -A 1Repository: mailtrap/mailtrap-ruby Length of output: 756 Align error behavior with the YARD contract. Line 20 uses 💡 Proposed fix- def initialize(inbox_id, account_id = ENV.fetch('MAILTRAP_ACCOUNT_ID'), client = Mailtrap::Client.new)
+ def initialize(inbox_id, account_id = ENV['MAILTRAP_ACCOUNT_ID'], client = Mailtrap::Client.new)
raise ArgumentError, 'account_id is required' if account_id.nil?
raise ArgumentError, 'inbox_id is required' if inbox_id.nil?📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| @account_id = account_id | ||||||||||||||||||||||||||||||
| @inbox_id = inbox_id | ||||||||||||||||||||||||||||||
| @client = client | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Retrieves a specific sandbox message from inbox | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [SandboxMessage] Sandbox message object | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get(message_id) | ||||||||||||||||||||||||||||||
| base_get(message_id) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Deletes a sandbox message | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [SandboxMessage] Deleted Sandbox message object | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def delete(message_id) | ||||||||||||||||||||||||||||||
| base_delete(message_id) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Updates an existing sandbox message | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The sandbox message ID | ||||||||||||||||||||||||||||||
| # @param [Hash] options The parameters to update | ||||||||||||||||||||||||||||||
| # @return [SandboxMessage] Updated Sandbox message object | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| # @raise [ArgumentError] If invalid options are provided | ||||||||||||||||||||||||||||||
| def update(message_id, options) | ||||||||||||||||||||||||||||||
| base_update(message_id, options) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Lists all sandbox messages for the account, limited up to 30 at once | ||||||||||||||||||||||||||||||
| # @param search [String] Search query string. Matches subject, to_email, and to_name. | ||||||||||||||||||||||||||||||
| # @param last_id [Integer] If specified, a page of records before last_id is returned. | ||||||||||||||||||||||||||||||
| # Overrides page if both are given. | ||||||||||||||||||||||||||||||
| # @param page [Integer] Page number for paginated results. | ||||||||||||||||||||||||||||||
| # @return [Array<SandboxMessage>] Array of sandbox message objects | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def list(search: nil, last_id: nil, page: nil) | ||||||||||||||||||||||||||||||
| query_params = {} | ||||||||||||||||||||||||||||||
| query_params[:search] = search unless search.nil? | ||||||||||||||||||||||||||||||
| query_params[:last_id] = last_id unless last_id.nil? | ||||||||||||||||||||||||||||||
| query_params[:page] = page unless page.nil? | ||||||||||||||||||||||||||||||
|
Comment on lines
+55
to
+66
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. Enforce The docs say 🛠️ Proposed fix def list(search: nil, last_id: nil, page: nil)
query_params = {}
query_params[:search] = search unless search.nil?
- query_params[:last_id] = last_id unless last_id.nil?
- query_params[:page] = page unless page.nil?
+ if !last_id.nil?
+ query_params[:last_id] = last_id
+ elsif !page.nil?
+ query_params[:page] = page
+ end
base_list(query_params)
end🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| base_list(query_params) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Forward message to an email address. | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @param email [String] The email to forward sandbox message to | ||||||||||||||||||||||||||||||
| # @return [String] Forwarded message confirmation | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def forward_message(message_id:, email:) | ||||||||||||||||||||||||||||||
| client.post("#{base_path}/#{message_id}/forward", { email: email }) | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get message spam score | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [Hash] Spam report | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_spam_score(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/spam_report") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get message HTML analysis | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [Hash] brief HTML report | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_html_analysis(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/analyze") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get text message | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [String] text email body | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_text_message(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/body.txt") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get raw message | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [String] raw email body | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_raw_message(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/body.raw") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get message source | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [String] HTML source of a message. | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_html_source(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/body.htmlsource") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get formatted HTML email body. Not applicable for plain text emails. | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [String] message body in html format. | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_html_message(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/body.html") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get message as EML | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [Hash] mail headers of the message. | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_message_as_eml(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/body.eml") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| # Get mail headers | ||||||||||||||||||||||||||||||
| # @param message_id [Integer] The Sandbox message ID | ||||||||||||||||||||||||||||||
| # @return [Hash] mail headers of the message. | ||||||||||||||||||||||||||||||
| # @!macro api_errors | ||||||||||||||||||||||||||||||
| def get_mail_headers(message_id) | ||||||||||||||||||||||||||||||
| client.get("#{base_path}/#{message_id}/mail_headers") | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def base_path | ||||||||||||||||||||||||||||||
| "/api/accounts/#{account_id}/inboxes/#{inbox_id}/messages" | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| def wrap_request(options) | ||||||||||||||||||||||||||||||
| { message: options } | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
| end | ||||||||||||||||||||||||||||||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please see all the places where
json_responseis used and update those as well.