Skip to content

Commit 07f3bcd

Browse files
committed
feat: Add support for tracking_options and raw_mime fields in Messages API
- Add MessageFields constants for better field parameter management - Support new fields query parameter values: include_tracking_options and raw_mime - Add comprehensive test coverage (19 tests, 99.64% coverage) - Create working example with .env file support - Update documentation and changelog - Maintains full backwards compatibility with existing API usage
1 parent 0f6d1d6 commit 07f3bcd

File tree

7 files changed

+468
-0
lines changed

7 files changed

+468
-0
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# Changelog
22

3+
### Unreleased
4+
* Added support for new `fields` query parameter values in Messages API:
5+
- `include_tracking_options`: Returns messages and their tracking settings
6+
- `raw_mime`: Returns the grant_id, object, id, and raw_mime fields only
7+
* Added support for `tracking_options` field in message responses containing:
8+
- `opens`: Boolean indicating if message open tracking is enabled
9+
- `thread_replies`: Boolean indicating if thread replied tracking is enabled
10+
- `links`: Boolean indicating if link clicked tracking is enabled
11+
- `label`: String label describing the message tracking purpose
12+
* Added support for `raw_mime` field in message responses containing Base64url-encoded message data
13+
* Added `MessageFields` module with constants for all valid field values to improve developer experience
14+
315
### 6.4.0 / 2025-04-30
416
* Added support for Notetaker APIs
517
* Added support for Notetaker via the calendar and event APIs

examples/.env.example

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Nylas API Key - Required
2+
# Get it from your Nylas Dashboard: https://dashboard.nylas.com/
3+
NYLAS_API_KEY=your_api_key_here
4+
5+
# Meeting Link - Required for Notetaker examples
6+
# This should be a link to a Zoom, Google Meet, or Microsoft Teams meeting
7+
MEETING_LINK=your_meeting_link_here
8+
9+
# Nylas API URI - Optional (defaults to https://api.us.nylas.com)
10+
# Only change this if instructed by Nylas support
11+
NYLAS_API_URI=https://api.us.nylas.com
12+
13+
# Grant ID - Required for message and event examples
14+
# You can get this from your Nylas Dashboard after connecting an account
15+
NYLAS_GRANT_ID=your_grant_id_here

examples/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ examples/
99
├── README.md # This file
1010
├── events/ # Event-related examples
1111
│ └── event_notetaker_example.rb # Example of creating events with Notetaker
12+
├── messages/ # Message-related examples
13+
│ └── message_fields_example.rb # Example of using new message fields functionality
1214
└── notetaker/ # Standalone Notetaker examples
1315
├── README.md # Notetaker-specific documentation
1416
└── notetaker_example.rb # Basic Notetaker functionality example
@@ -39,6 +41,18 @@ Before running any example, make sure to:
3941
- Retrieving Notetaker details
4042
- Updating event and Notetaker settings
4143

44+
### Messages
45+
- `messages/message_fields_example.rb`: Shows how to use the new message fields functionality, including:
46+
- Retrieving messages with tracking options
47+
- Getting raw MIME data from messages
48+
- Using MessageFields constants for better code readability
49+
- Comparing different field options (standard, headers, tracking, raw MIME)
50+
51+
Additional environment variables needed:
52+
```bash
53+
export NYLAS_GRANT_ID="your_grant_id"
54+
```
55+
4256
### Notetaker
4357
- `notetaker/notetaker_example.rb`: Shows basic Notetaker functionality, including:
4458
- Inviting a Notetaker to a meeting
Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
#!/usr/bin/env ruby
2+
# frozen_string_literal: true
3+
4+
# Example demonstrating the new message fields functionality in the Nylas Ruby SDK
5+
#
6+
# This example shows how to:
7+
# 1. Use MessageFields constants for better code readability
8+
# 2. Retrieve messages with different field options (standard, tracking, headers, raw MIME)
9+
# 3. Access tracking options like opens, thread_replies, links, and labels
10+
# 4. Get raw MIME data for advanced message processing
11+
#
12+
# Prerequisites:
13+
# - Ruby 3.0 or later
14+
# - A Nylas API key
15+
# - A grant ID (connected email account)
16+
#
17+
# Environment variables needed:
18+
# export NYLAS_API_KEY="your_api_key"
19+
# export NYLAS_GRANT_ID="your_grant_id"
20+
# export NYLAS_API_URI="https://api.us.nylas.com" # Optional
21+
#
22+
# Alternatively, create a .env file in the examples directory with:
23+
# NYLAS_API_KEY=your_api_key
24+
# NYLAS_GRANT_ID=your_grant_id
25+
# NYLAS_API_URI=https://api.us.nylas.com
26+
27+
$LOAD_PATH.unshift File.expand_path('../../lib', __dir__)
28+
require "nylas"
29+
require "json"
30+
31+
# Simple .env file loader
32+
def load_env_file
33+
env_file = File.expand_path('../.env', __dir__)
34+
return unless File.exist?(env_file)
35+
36+
puts "Loading environment variables from .env file..."
37+
File.readlines(env_file).each do |line|
38+
line = line.strip
39+
next if line.empty? || line.start_with?('#')
40+
41+
key, value = line.split('=', 2)
42+
next unless key && value
43+
44+
# Remove quotes if present
45+
value = value.gsub(/\A['"]|['"]\z/, '')
46+
ENV[key] = value
47+
end
48+
end
49+
50+
def list_messages_with_standard_fields(nylas, grant_id)
51+
puts "\n=== Listing Messages with Standard Fields ==="
52+
53+
messages, request_id = nylas.messages.list(
54+
identifier: grant_id,
55+
query_params: {
56+
fields: Nylas::MessageFields::STANDARD,
57+
limit: 5
58+
}
59+
)
60+
61+
puts "Found #{messages.length} messages with standard fields"
62+
if messages.any?
63+
message = messages.first
64+
puts "- Sample message ID: #{message[:id]}"
65+
puts "- Subject: #{message[:subject]}"
66+
puts "- Has tracking_options: #{message.key?(:tracking_options)}"
67+
puts "- Has raw_mime: #{message.key?(:raw_mime)}"
68+
end
69+
puts "Request ID: #{request_id}"
70+
71+
messages
72+
end
73+
74+
def list_messages_with_tracking_options(nylas, grant_id)
75+
puts "\n=== Listing Messages with Tracking Options ==="
76+
77+
messages, request_id = nylas.messages.list(
78+
identifier: grant_id,
79+
query_params: {
80+
fields: Nylas::MessageFields::INCLUDE_TRACKING_OPTIONS,
81+
limit: 5
82+
}
83+
)
84+
85+
puts "Found #{messages.length} messages with tracking options"
86+
if messages.any?
87+
message = messages.first
88+
puts "- Sample message ID: #{message[:id]}"
89+
puts "- Subject: #{message[:subject]}"
90+
91+
if message[:tracking_options]
92+
tracking = message[:tracking_options]
93+
puts "- Tracking Options:"
94+
puts " - Opens tracking: #{tracking[:opens]}"
95+
puts " - Thread replies tracking: #{tracking[:thread_replies]}"
96+
puts " - Links tracking: #{tracking[:links]}"
97+
puts " - Label: #{tracking[:label]}" if tracking[:label]
98+
else
99+
puts "- No tracking options available for this message"
100+
end
101+
end
102+
puts "Request ID: #{request_id}"
103+
104+
messages
105+
end
106+
107+
def get_message_with_raw_mime(nylas, grant_id, message_id)
108+
puts "\n=== Getting Message with Raw MIME Data ==="
109+
110+
message, request_id = nylas.messages.find(
111+
identifier: grant_id,
112+
message_id: message_id,
113+
query_params: { fields: Nylas::MessageFields::RAW_MIME }
114+
)
115+
116+
puts "Retrieved message with raw MIME data:"
117+
puts "- Message ID: #{message[:id]}"
118+
puts "- Grant ID: #{message[:grant_id]}"
119+
puts "- Object type: #{message[:object]}"
120+
puts "- Raw MIME length: #{message[:raw_mime]&.length || 0} characters"
121+
puts "- Raw MIME preview: #{message[:raw_mime]&.slice(0, 50)}..." if message[:raw_mime]
122+
puts "- Available fields: #{message.keys.sort}"
123+
puts "Request ID: #{request_id}"
124+
125+
# Note: When using RAW_MIME, only grant_id, object, id, and raw_mime fields are returned
126+
message
127+
end
128+
129+
def get_message_with_headers(nylas, grant_id, message_id)
130+
puts "\n=== Getting Message with Headers ==="
131+
132+
message, request_id = nylas.messages.find(
133+
identifier: grant_id,
134+
message_id: message_id,
135+
query_params: { fields: Nylas::MessageFields::INCLUDE_HEADERS }
136+
)
137+
138+
puts "Retrieved message with headers:"
139+
puts "- Message ID: #{message[:id]}"
140+
puts "- Subject: #{message[:subject]}"
141+
puts "- Has headers: #{message.key?(:headers)}"
142+
143+
if message[:headers]
144+
puts "- Sample headers:"
145+
message[:headers].first(3).each do |header|
146+
puts " - #{header[:name]}: #{header[:value]}"
147+
end
148+
end
149+
puts "Request ID: #{request_id}"
150+
151+
message
152+
end
153+
154+
def demonstrate_message_fields_constants
155+
puts "\n=== Message Fields Constants ==="
156+
puts "Available MessageFields constants:"
157+
puts "- STANDARD: #{Nylas::MessageFields::STANDARD}"
158+
puts "- INCLUDE_HEADERS: #{Nylas::MessageFields::INCLUDE_HEADERS}"
159+
puts "- INCLUDE_TRACKING_OPTIONS: #{Nylas::MessageFields::INCLUDE_TRACKING_OPTIONS}"
160+
puts "- RAW_MIME: #{Nylas::MessageFields::RAW_MIME}"
161+
end
162+
163+
def main
164+
# Load .env file if it exists
165+
load_env_file
166+
167+
# Check for required environment variables
168+
api_key = ENV["NYLAS_API_KEY"]
169+
grant_id = ENV["NYLAS_GRANT_ID"]
170+
171+
raise "NYLAS_API_KEY environment variable is not set" unless api_key
172+
raise "NYLAS_GRANT_ID environment variable is not set" unless grant_id
173+
174+
puts "Using API key: #{api_key[0..4]}..."
175+
puts "Using grant ID: #{grant_id[0..8]}..."
176+
177+
# Initialize the Nylas client
178+
nylas = Nylas::Client.new(
179+
api_key: api_key,
180+
api_uri: ENV["NYLAS_API_URI"] || "https://api.us.nylas.com"
181+
)
182+
183+
puts "\n=== Nylas Message Fields Example ==="
184+
185+
begin
186+
# Demonstrate the constants
187+
demonstrate_message_fields_constants
188+
189+
# Example 1: List messages with standard fields (default)
190+
standard_messages = list_messages_with_standard_fields(nylas, grant_id)
191+
192+
# Example 2: List messages with tracking options
193+
tracking_messages = list_messages_with_tracking_options(nylas, grant_id)
194+
195+
# Example 3: Get a specific message with raw MIME data
196+
if standard_messages.any?
197+
message_id = standard_messages.first[:id]
198+
get_message_with_raw_mime(nylas, grant_id, message_id)
199+
200+
# Example 4: Get a message with headers
201+
get_message_with_headers(nylas, grant_id, message_id)
202+
else
203+
puts "\nNo messages available to demonstrate raw MIME and headers retrieval"
204+
end
205+
206+
puts "\n=== Example completed successfully! ==="
207+
208+
rescue Nylas::NylasApiError => e
209+
puts "\nAPI Error: #{e.message}"
210+
puts "Type: #{e.type}"
211+
puts "Status Code: #{e.status_code}"
212+
puts "Request ID: #{e.request_id}" if e.request_id
213+
rescue StandardError => e
214+
puts "\nError: #{e.message}"
215+
puts e.backtrace.first(5)
216+
end
217+
end
218+
219+
main if __FILE__ == $PROGRAM_NAME

examples/messages/test_example.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

lib/nylas/resources/messages.rb

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
require_relative "../utils/file_utils"
77

88
module Nylas
9+
# Module representing the possible 'fields' values for Messages API requests.
10+
# @see https://developer.nylas.com/docs/api/messages#get-/v3/grants/-identifier-/messages
11+
module MessageFields
12+
# Return the standard message payload (default)
13+
STANDARD = "standard"
14+
# Return messages and their custom headers
15+
INCLUDE_HEADERS = "include_headers"
16+
# Return messages and their tracking settings
17+
INCLUDE_TRACKING_OPTIONS = "include_tracking_options"
18+
# Return the grant_id, object, id, and raw_mime fields only
19+
RAW_MIME = "raw_mime"
20+
end
21+
922
# Nylas Messages API
1023
class Messages < Resource
1124
include ApiOperations::Get
@@ -26,6 +39,11 @@ def initialize(sdk_instance)
2639
#
2740
# @param identifier [String] Grant ID or email account to query.
2841
# @param query_params [Hash, nil] Query params to pass to the request.
42+
# You can use the fields parameter to specify which data to return:
43+
# - MessageFields::STANDARD (default): Returns the standard message payload
44+
# - MessageFields::INCLUDE_HEADERS: Returns messages and their custom headers
45+
# - MessageFields::INCLUDE_TRACKING_OPTIONS: Returns messages and their tracking settings
46+
# - MessageFields::RAW_MIME: Returns the grant_id, object, id, and raw_mime fields only
2947
# @return [Array(Array(Hash), String, String)] The list of messages, API Request ID, and next cursor.
3048
def list(identifier:, query_params: nil)
3149
get_list(
@@ -39,6 +57,11 @@ def list(identifier:, query_params: nil)
3957
# @param identifier [String] Grant ID or email account to query.
4058
# @param message_id [String] The id of the message to return.
4159
# @param query_params [Hash, nil] Query params to pass to the request.
60+
# You can use the fields parameter to specify which data to return:
61+
# - MessageFields::STANDARD (default): Returns the standard message payload
62+
# - MessageFields::INCLUDE_HEADERS: Returns messages and their custom headers
63+
# - MessageFields::INCLUDE_TRACKING_OPTIONS: Returns messages and their tracking settings
64+
# - MessageFields::RAW_MIME: Returns the grant_id, object, id, and raw_mime fields only
4265
# @return [Array(Hash, String)] The message and API request ID.
4366
def find(identifier:, message_id:, query_params: nil)
4467
get(

0 commit comments

Comments
 (0)