diff --git a/CHANGELOG.md b/CHANGELOG.md index 17d3cac7..c25166fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Nylas Java SDK Changelog +## [Unreleased] + +### Changed +* `SendMessageRequest.sendAt` field changed from `Int?` to `Long?` to support Unix timestamps beyond 2038. Maintains backward compatibility through method overloading - existing `Int` parameters are automatically converted to `Long`. **Note:** Kotlin users passing integer literals may need to specify type explicitly (e.g., `1620000000L` or `1620000000 as Int`). + ## [2.13.1] ### Fixed diff --git a/src/main/kotlin/com/nylas/models/SendMessageRequest.kt b/src/main/kotlin/com/nylas/models/SendMessageRequest.kt index c69f59f1..7366b1ab 100644 --- a/src/main/kotlin/com/nylas/models/SendMessageRequest.kt +++ b/src/main/kotlin/com/nylas/models/SendMessageRequest.kt @@ -56,7 +56,7 @@ data class SendMessageRequest( * Unix timestamp to send the message at. */ @Json(name = "send_at") - val sendAt: Int? = null, + val sendAt: Long? = null, /** * The ID of the message that you are replying to. */ @@ -94,7 +94,7 @@ data class SendMessageRequest( internal var subject: String? = null private var body: String? = null private var starred: Boolean? = null - private var sendAt: Int? = null + private var sendAt: Long? = null private var replyToMessageId: String? = null private var trackingOptions: TrackingOptions? = null private var useDraft: Boolean? = null @@ -162,7 +162,14 @@ data class SendMessageRequest( * @param sendAt The unix timestamp to send the message at. * @return The builder. */ - fun sendAt(sendAt: Int?) = apply { this.sendAt = sendAt } + fun sendAt(sendAt: Long?) = apply { this.sendAt = sendAt } + + /** + * Sets the unix timestamp to send the message at. + * @param sendAt The unix timestamp to send the message at (automatically converted to Long). + * @return The builder. + */ + fun sendAt(sendAt: Int?) = apply { this.sendAt = sendAt?.toLong() } /** * Sets the ID of the message that you are replying to. diff --git a/src/test/kotlin/com/nylas/resources/MessagesTests.kt b/src/test/kotlin/com/nylas/resources/MessagesTests.kt index c1a66f16..0fd52dad 100644 --- a/src/test/kotlin/com/nylas/resources/MessagesTests.kt +++ b/src/test/kotlin/com/nylas/resources/MessagesTests.kt @@ -616,6 +616,75 @@ class MessagesTests { assertNull(queryParamCaptor.firstValue) } + @Test + fun `sending a message with Int sendAt value calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(SendMessageRequest::class.java) + val sendMessageRequest = + SendMessageRequest.Builder(to = listOf(EmailName(email = "test@gmail.com", name = "Test"))) + .body("Hello, I just sent a message using Nylas!") + .subject("Hello from Nylas!") + .sendAt(1620000000 as Int) // Explicitly test Int overload conversion to Long + .build() + + messages.send(grantId, sendMessageRequest) + + val pathCaptor = argumentCaptor() + val typeCaptor = argumentCaptor() + val requestBodyCaptor = argumentCaptor() + val queryParamCaptor = argumentCaptor() + val overrideParamCaptor = argumentCaptor() + verify(mockNylasClient).executePost>( + pathCaptor.capture(), + typeCaptor.capture(), + requestBodyCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + + assertEquals("v3/grants/$grantId/messages/send", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Message::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(sendMessageRequest), requestBodyCaptor.firstValue) + assertNull(queryParamCaptor.firstValue) + + // Verify the sendAt field is properly set as Long + assertEquals(1620000000L, sendMessageRequest.sendAt) + } + + @Test + fun `sending a message with Long sendAt value calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(SendMessageRequest::class.java) + val longTimestamp = 1893456000L // Year 2030 timestamp that exceeds Int.MAX_VALUE in the future + val sendMessageRequest = + SendMessageRequest.Builder(to = listOf(EmailName(email = "test@gmail.com", name = "Test"))) + .body("Hello, I just sent a message using Nylas!") + .subject("Hello from Nylas!") + .sendAt(longTimestamp) // Long value + .build() + + messages.send(grantId, sendMessageRequest) + + val pathCaptor = argumentCaptor() + val typeCaptor = argumentCaptor() + val requestBodyCaptor = argumentCaptor() + val queryParamCaptor = argumentCaptor() + val overrideParamCaptor = argumentCaptor() + verify(mockNylasClient).executePost>( + pathCaptor.capture(), + typeCaptor.capture(), + requestBodyCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + + assertEquals("v3/grants/$grantId/messages/send", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Message::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(sendMessageRequest), requestBodyCaptor.firstValue) + assertNull(queryParamCaptor.firstValue) + + // Verify the sendAt field is properly set as Long + assertEquals(longTimestamp, sendMessageRequest.sendAt) + } + @Test fun `sending a message with a large attachment calls requests with the correct params`() { val adapter = JsonHelper.moshi().adapter(SendMessageRequest::class.java)