Skip to content
Merged
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
.env
**/*/.env
# Example test files
examples/messages/large_test_file.txt
*.gem
*.rbc
.bundle
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# Changelog

### Unreleased
* Replaced `rest-client` dependency with `httparty` for improved maintainability and security
- `rest-client` is no longer actively maintained and has known security vulnerabilities
- `httparty` is actively maintained and provides better performance
- All existing functionality remains backwards compatible - no customer code changes required
- Removed workaround for `rest-client` cookie jar threading bug
* Added support for new `fields` query parameter values in Messages API:
- `include_tracking_options`: Returns messages and their tracking settings
- `raw_mime`: Returns the grant_id, object, id, and raw_mime fields only
Expand All @@ -11,6 +16,11 @@
- `label`: String label describing the message tracking purpose
* Added support for `raw_mime` field in message responses containing Base64url-encoded message data
* Added `MessageFields` module with constants for all valid field values to improve developer experience
* Fixed multipart email sending bug where large attachments would fail due to multipart flag key mismatch (#525)
- `FileUtils.handle_message_payload` transforms keys to symbols (`:multipart`)
- `HttpClient.build_request` was only checking for string keys (`"multipart"`)
- Now checks for both string and symbol keys to maintain full backwards compatibility
- Prevents encoding errors when sending emails with attachments larger than 3MB

### 6.4.0 / 2025-04-30
* Added support for Notetaker APIs
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ If you have a question about the Nylas Communications Platform, [contact Nylas S
### Prerequisites

- Ruby 3.0 or above.
- Ruby Frameworks: `rest-client` and `yajl-ruby`.
- Ruby Frameworks: `httparty` and `yajl-ruby`.

### Install

Expand Down
6 changes: 5 additions & 1 deletion examples/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ NYLAS_API_URI=https://api.us.nylas.com

# Grant ID - Required for message and event examples
# You can get this from your Nylas Dashboard after connecting an account
NYLAS_GRANT_ID=your_grant_id_here
NYLAS_GRANT_ID=your_grant_id_here

# Send email - Optionl
# Used for send examples
[email protected]
29 changes: 28 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ examples/
├── events/ # Event-related examples
│ └── event_notetaker_example.rb # Example of creating events with Notetaker
├── messages/ # Message-related examples
│ └── message_fields_example.rb # Example of using new message fields functionality
│ ├── message_fields_example.rb # Example of using new message fields functionality
│ ├── file_upload_example.rb # Example of file upload functionality with HTTParty migration
│ └── send_message_example.rb # Example of basic message sending functionality
└── notetaker/ # Standalone Notetaker examples
├── README.md # Notetaker-specific documentation
└── notetaker_example.rb # Basic Notetaker functionality example
Expand Down Expand Up @@ -53,6 +55,31 @@ Before running any example, make sure to:
export NYLAS_GRANT_ID="your_grant_id"
```

- `messages/file_upload_example.rb`: Demonstrates file upload functionality with the HTTParty migration, including:
- Sending messages with small attachments (<3MB) - handled as JSON with base64 encoding
- Sending messages with large attachments (>3MB) - handled as multipart form data
- Creating test files of appropriate sizes for demonstration
- File handling logic and processing differences
- Verification that HTTParty migration works for both upload methods

Additional environment variables needed:
```bash
export NYLAS_GRANT_ID="your_grant_id"
export NYLAS_TEST_EMAIL="[email protected]" # Email address to send test messages to
```

- `messages/send_message_example.rb`: Demonstrates basic message sending functionality, including:
- Sending simple text messages
- Handling multiple recipients (TO, CC, BCC)
- Sending rich HTML content
- Processing responses and error handling

Additional environment variables needed:
```bash
export NYLAS_GRANT_ID="your_grant_id"
export NYLAS_TEST_EMAIL="[email protected]" # Email address to send test messages to
```

### Notetaker
- `notetaker/notetaker_example.rb`: Shows basic Notetaker functionality, including:
- Inviting a Notetaker to a meeting
Expand Down
276 changes: 276 additions & 0 deletions examples/messages/file_upload_example.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

# Example demonstrating file upload functionality in the Nylas Ruby SDK
# Tests both small (<3MB) and large (>3MB) file handling with the new HTTParty implementation
#
# This example shows how to:
# 1. Send messages with small attachments (<3MB) - handled as JSON with base64 encoding
# 2. Send messages with large attachments (>3MB) - handled as multipart form data
# 3. Create test files of appropriate sizes for demonstration
# 4. Handle file upload errors and responses
#
# Prerequisites:
# - Ruby 3.0 or later
# - A Nylas API key
# - A grant ID (connected email account)
# - A test email address to send to
#
# Environment variables needed:
# export NYLAS_API_KEY="your_api_key"
# export NYLAS_GRANT_ID="your_grant_id"
# export NYLAS_TEST_EMAIL="[email protected]" # Email address to send test messages to
# export NYLAS_API_URI="https://api.us.nylas.com" # Optional
#
# Alternatively, create a .env file in the examples directory with:
# NYLAS_API_KEY=your_api_key
# NYLAS_GRANT_ID=your_grant_id
# [email protected]
# NYLAS_API_URI=https://api.us.nylas.com

$LOAD_PATH.unshift File.expand_path('../../lib', __dir__)
require "nylas"
require "json"
require "tempfile"

# Simple .env file loader
def load_env_file
env_file = File.expand_path('../.env', __dir__)
return unless File.exist?(env_file)

puts "Loading environment variables from .env file..."
File.readlines(env_file).each do |line|
line = line.strip
next if line.empty? || line.start_with?('#')

key, value = line.split('=', 2)
next unless key && value

# Remove quotes if present
value = value.gsub(/\A['"]|['"]\z/, '')
ENV[key] = value
end
end

def create_small_test_file
puts "\n=== Creating Small Test File (<3MB) ==="

# Create a 1MB test file
content = "A" * (1024 * 1024) # 1MB of 'A' characters

temp_file = Tempfile.new(['small_test', '.txt'])
temp_file.write(content)
temp_file.rewind

puts "- Created test file: #{temp_file.path}"
puts "- File size: #{File.size(temp_file.path)} bytes (#{File.size(temp_file.path) / (1024.0 * 1024).round(2)} MB)"
puts "- This will be sent as JSON with base64 encoding"

temp_file
end

def find_or_create_large_test_file
puts "\n=== Finding Large Test File (>3MB) ==="

# Look for an existing large file, or create one if needed
large_file_path = File.expand_path("large_test_file.txt", __dir__)

unless File.exist?(large_file_path) && File.size(large_file_path) > 3 * 1024 * 1024
puts "- Creating 5MB test file on disk..."
content = "B" * (5 * 1024 * 1024) # 5MB of 'B' characters
File.write(large_file_path, content)
puts "- Created permanent test file: #{large_file_path}"
else
puts "- Found existing test file: #{large_file_path}"
end

puts "- File size: #{File.size(large_file_path)} bytes (#{File.size(large_file_path) / (1024.0 * 1024).round(2)} MB)"
puts "- This will be sent as multipart form data"

large_file_path
end

def send_message_with_small_attachment(nylas, grant_id, recipient_email, test_file)
puts "\n=== Sending Message with Small Attachment ==="

begin
# Build the file attachment
file_attachment = Nylas::FileUtils.attach_file_request_builder(test_file.path)

request_body = {
subject: "Test Email with Small Attachment (<3MB) - HTTParty Migration Test",
to: [{ email: recipient_email }],
body: "This is a test email with a small attachment (<3MB) to verify the HTTParty migration works correctly.\n\nFile size: #{File.size(test_file.path)} bytes\nSent at: #{Time.now}",
attachments: [file_attachment]
}

puts "- Sending message with small attachment..."
puts "- Recipient: #{recipient_email}"
puts "- Attachment size: #{File.size(test_file.path)} bytes"
puts "- Expected handling: JSON with base64 encoding"

response, request_id = nylas.messages.send(
identifier: grant_id,
request_body: request_body
)

puts "✅ Message sent successfully!"
puts "- Message ID: #{response[:id]}"
puts "- Request ID: #{request_id}"
puts "- Grant ID: #{response[:grant_id]}"

response
rescue => e
puts "❌ Failed to send message with small attachment: #{e.message}"
puts "- Error class: #{e.class}"
raise
end
end

def send_message_with_large_attachment(nylas, grant_id, recipient_email, test_file_path)
puts "\n=== Sending Message with Large Attachment ==="

begin
# Build the file attachment
file_attachment = Nylas::FileUtils.attach_file_request_builder(test_file_path)

request_body = {
subject: "Test Email with Large Attachment (>3MB) - HTTParty Migration Test",
to: [{ email: recipient_email }],
body: "This is a test email with a large attachment (>3MB) to verify the HTTParty migration works correctly.\n\nFile size: #{File.size(test_file_path)} bytes\nSent at: #{Time.now}",
attachments: [file_attachment]
}

puts "- Sending message with large attachment..."
puts "- Recipient: #{recipient_email}"
puts "- Attachment size: #{File.size(test_file_path)} bytes"
puts "- Expected handling: Multipart form data"

response, request_id = nylas.messages.send(
identifier: grant_id,
request_body: request_body
)

puts "✅ Message sent successfully!"
puts "- Message ID: #{response[:id]}"
puts "- Request ID: #{request_id}"
puts "- Grant ID: #{response[:grant_id]}"

response
rescue => e
puts "❌ Failed to send message with large attachment: #{e.message}"
puts "- Error class: #{e.class}"
raise
end
end

def demonstrate_file_utils_handling
puts "\n=== Demonstrating File Handling Logic ==="

# Create temporary files to test the file handling logic
small_file = create_small_test_file
large_file_path = find_or_create_large_test_file

begin
# Test small file handling
small_attachment = Nylas::FileUtils.attach_file_request_builder(small_file.path)
puts "- Small file attachment structure: #{small_attachment.keys}"

# Test large file handling
large_attachment = Nylas::FileUtils.attach_file_request_builder(large_file_path)
puts "- Large file attachment structure: #{large_attachment.keys}"

# Demonstrate the SDK's file size handling
small_payload = {
subject: "test",
attachments: [small_attachment]
}

large_payload = {
subject: "test",
attachments: [large_attachment]
}

# Show how the SDK determines handling method
small_handling, small_files = Nylas::FileUtils.handle_message_payload(small_payload)
large_handling, large_files = Nylas::FileUtils.handle_message_payload(large_payload)

puts "- Small file handling method: #{small_handling['multipart'] ? 'Form Data' : 'JSON'}"
puts "- Large file handling method: #{large_handling['multipart'] ? 'Form Data' : 'JSON'}"

ensure
small_file.close
small_file.unlink
# Note: We keep the large file on disk for future use
end
end

def main
# Load .env file if it exists
load_env_file

# Check for required environment variables
api_key = ENV["NYLAS_API_KEY"]
grant_id = ENV["NYLAS_GRANT_ID"]
test_email = ENV["NYLAS_TEST_EMAIL"]

raise "NYLAS_API_KEY environment variable is not set" unless api_key
raise "NYLAS_GRANT_ID environment variable is not set" unless grant_id
raise "NYLAS_TEST_EMAIL environment variable is not set" unless test_email

puts "=== Nylas File Upload Example - HTTParty Migration Test ==="
puts "Using API key: #{api_key[0..4]}..."
puts "Using grant ID: #{grant_id[0..8]}..."
puts "Test email recipient: #{test_email}"

# Initialize the Nylas client
nylas = Nylas::Client.new(
api_key: api_key,
api_uri: ENV["NYLAS_API_URI"] || "https://api.us.nylas.com"
)

begin
# Demonstrate file handling logic
demonstrate_file_utils_handling

# Create test files
small_file = create_small_test_file
large_file_path = find_or_create_large_test_file

begin
# Test 1: Send message with small attachment
small_response = send_message_with_small_attachment(nylas, grant_id, test_email, small_file)

# Test 2: Send message with large attachment
large_response = send_message_with_large_attachment(nylas, grant_id, test_email, large_file_path)

puts "\n=== Summary ==="
puts "✅ Both small and large file uploads completed successfully!"
puts "- Small file message ID: #{small_response[:id]}"
puts "- Large file message ID: #{large_response[:id]}"
puts "- HTTParty migration verified for both file handling methods"

ensure
# Clean up temporary small file only
small_file.close
small_file.unlink
puts "\n🧹 Cleaned up temporary small file (large file kept on disk for reuse)"
end

rescue => e
puts "\n❌ Example failed: #{e.message}"
puts "- #{e.backtrace.first}"
exit 1
end

puts "\n🎉 File upload example completed successfully!"
puts "This confirms that the HTTParty migration properly handles:"
puts "- Small files (<3MB): JSON with base64 encoding"
puts "- Large files (>3MB): Multipart form data"
puts "- File attachment building and processing"
puts "- HTTP request execution with different payload types"
end

if __FILE__ == $0
main
end
Loading
Loading