Skip to content

Commit 4f7e486

Browse files
authored
TT-4429: CRUDs for rules/policies/lists, new feature (#312)
1 parent 7a179ce commit 4f7e486

36 files changed

Lines changed: 2602 additions & 31 deletions

.claude/settings.local.json

Lines changed: 0 additions & 31 deletions
This file was deleted.

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,6 @@ out
1515
.idea
1616
.DS_Store
1717
src/main/kotlin/com/nylas/Main.kt
18+
19+
# Claude Code per-user local settings (not shared)
20+
.claude/settings.local.json

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
- `NylasClient.domains()` accessor returning the new `Domains` resource
99
- Automatic multipart/form-data upload when the total attachment size exceeds the JSON limit
1010
- Examples: `TransactionalEmailExample.java` and `KotlinTransactionalEmailExample.kt`
11+
* Administration API — Policies, Rules, and Lists (app-level, `nylas` provider only)
12+
- `Policies` resource via `client.policies()`: full CRUD (`list`, `find`, `create`, `update`, `destroy`) with `CreatePolicyRequest` / `UpdatePolicyRequest` and supporting models (`Policy`, `PolicyLimits`, `PolicyOptions`, `PolicySpamDetection`)
13+
- `Rules` resource via `client.rules()`: full CRUD with `CreateRuleRequest` / `UpdateRuleRequest` and supporting models (`Rule`, `RuleAction`, `RuleActionType`, `RuleCondition`, `RuleConditionOperator`, `RuleMatch`, `RuleMatchOperator`, `RuleTrigger`)
14+
- `NylasLists` resource via `client.lists()`: full CRUD plus `listItems`, `addItems`, and `removeItems` for managing list contents; `NylasList`, `NylasListItem`, `NylasListType`, `ListItemsRequest` models
1115

1216
## [v2.16.1] - Release 2026-05-21
1317

src/main/kotlin/com/nylas/NylasClient.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,24 @@ open class NylasClient(
171171
*/
172172
open fun notetakers(): Notetakers = Notetakers(this)
173173

174+
/**
175+
* Access the Policies API
176+
* @return The Policies API
177+
*/
178+
open fun policies(): Policies = Policies(this)
179+
180+
/**
181+
* Access the Rules API
182+
* @return The Rules API
183+
*/
184+
open fun rules(): Rules = Rules(this)
185+
186+
/**
187+
* Access the Lists API
188+
* @return The Lists API
189+
*/
190+
open fun lists(): NylasLists = NylasLists(this)
191+
174192
/**
175193
* Get a URL builder instance for the Nylas API.
176194
*/
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.nylas.models
2+
3+
import com.squareup.moshi.Json
4+
5+
/**
6+
* Class representation of a Nylas create list request.
7+
*/
8+
data class CreateNylasListRequest(
9+
/**
10+
* Name of the list (1–256 characters).
11+
*/
12+
@Json(name = "name")
13+
val name: String,
14+
/**
15+
* The type of values this list will hold. Immutable after creation.
16+
*/
17+
@Json(name = "type")
18+
val type: NylasListType,
19+
/**
20+
* Optional description of the list.
21+
*/
22+
@Json(name = "description")
23+
val description: String? = null,
24+
) {
25+
/**
26+
* Builder for [CreateNylasListRequest].
27+
* @param name Name of the list.
28+
* @param type The type of values this list will hold.
29+
*/
30+
class Builder(
31+
private val name: String,
32+
private val type: NylasListType,
33+
) {
34+
private var description: String? = null
35+
36+
/**
37+
* Set the description of the list.
38+
* @param description Optional description of the list.
39+
* @return The builder.
40+
*/
41+
fun description(description: String) = apply { this.description = description }
42+
43+
/**
44+
* Build the [CreateNylasListRequest].
45+
* @return A [CreateNylasListRequest] with the provided values.
46+
*/
47+
fun build() = CreateNylasListRequest(name, type, description)
48+
}
49+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package com.nylas.models
2+
3+
import com.squareup.moshi.Json
4+
5+
/**
6+
* Class representation of a Nylas create policy request.
7+
*/
8+
data class CreatePolicyRequest(
9+
/**
10+
* Name of the policy.
11+
*/
12+
@Json(name = "name")
13+
val name: String,
14+
/**
15+
* Optional mailbox and behavior settings.
16+
*/
17+
@Json(name = "options")
18+
val options: PolicyOptions? = null,
19+
/**
20+
* Resource and rate limits for agent accounts using this policy.
21+
*/
22+
@Json(name = "limits")
23+
val limits: PolicyLimits? = null,
24+
/**
25+
* IDs of rules to link to this policy.
26+
*/
27+
@Json(name = "rules")
28+
val rules: List<String>? = null,
29+
/**
30+
* Spam detection configuration.
31+
*/
32+
@Json(name = "spam_detection")
33+
val spamDetection: PolicySpamDetection? = null,
34+
) {
35+
/**
36+
* Builder for [CreatePolicyRequest].
37+
* @param name Name of the policy.
38+
*/
39+
class Builder(
40+
private val name: String,
41+
) {
42+
private var options: PolicyOptions? = null
43+
private var limits: PolicyLimits? = null
44+
private var rules: List<String>? = null
45+
private var spamDetection: PolicySpamDetection? = null
46+
47+
/**
48+
* Set the mailbox and behavior settings.
49+
* @param options Optional mailbox and behavior settings.
50+
* @return The builder.
51+
*/
52+
fun options(options: PolicyOptions) = apply { this.options = options }
53+
54+
/**
55+
* Set the resource and rate limits.
56+
* @param limits Resource and rate limits for agent accounts using this policy.
57+
* @return The builder.
58+
*/
59+
fun limits(limits: PolicyLimits) = apply { this.limits = limits }
60+
61+
/**
62+
* Set the IDs of rules to link to this policy.
63+
* @param rules IDs of rules to link to this policy.
64+
* @return The builder.
65+
*/
66+
fun rules(rules: List<String>) = apply { this.rules = rules }
67+
68+
/**
69+
* Set the spam detection configuration.
70+
* @param spamDetection Spam detection configuration.
71+
* @return The builder.
72+
*/
73+
fun spamDetection(spamDetection: PolicySpamDetection) = apply { this.spamDetection = spamDetection }
74+
75+
/**
76+
* Build the [CreatePolicyRequest].
77+
* @return A [CreatePolicyRequest] with the provided values.
78+
*/
79+
fun build() = CreatePolicyRequest(name, options, limits, rules, spamDetection)
80+
}
81+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.nylas.models
2+
3+
import com.squareup.moshi.Json
4+
5+
/**
6+
* Class representation of a Nylas create rule request.
7+
*/
8+
data class CreateRuleRequest(
9+
/**
10+
* Name of the rule.
11+
*/
12+
@Json(name = "name")
13+
val name: String,
14+
/**
15+
* When this rule is evaluated.
16+
*/
17+
@Json(name = "trigger")
18+
val trigger: RuleTrigger,
19+
/**
20+
* The match conditions for this rule.
21+
*/
22+
@Json(name = "match")
23+
val match: RuleMatch,
24+
/**
25+
* The actions to perform when conditions are met.
26+
*/
27+
@Json(name = "actions")
28+
val actions: List<RuleAction>,
29+
/**
30+
* Optional description of the rule.
31+
*/
32+
@Json(name = "description")
33+
val description: String? = null,
34+
/**
35+
* Evaluation order — lower numbers run first. Range 0–1000, default 10.
36+
*/
37+
@Json(name = "priority")
38+
val priority: Int? = null,
39+
/**
40+
* Whether the rule is active. Defaults to true.
41+
*/
42+
@Json(name = "enabled")
43+
val enabled: Boolean? = null,
44+
) {
45+
init {
46+
require(!(actions.any { it.type == RuleActionType.BLOCK } && actions.size > 1)) {
47+
"RuleActionType.BLOCK is terminal and cannot be combined with other actions."
48+
}
49+
}
50+
51+
/**
52+
* Builder for [CreateRuleRequest].
53+
* @param name Name of the rule.
54+
* @param trigger When this rule is evaluated.
55+
* @param match The match conditions.
56+
* @param actions The actions to perform.
57+
*/
58+
class Builder(
59+
private val name: String,
60+
private val trigger: RuleTrigger,
61+
private val match: RuleMatch,
62+
private val actions: List<RuleAction>,
63+
) {
64+
private var description: String? = null
65+
private var priority: Int? = null
66+
private var enabled: Boolean? = null
67+
68+
/**
69+
* Set the description of the rule.
70+
* @param description Optional description of the rule.
71+
* @return The builder.
72+
*/
73+
fun description(description: String) = apply { this.description = description }
74+
75+
/**
76+
* Set the evaluation priority.
77+
* @param priority Evaluation order — lower numbers run first. Range 0–1000.
78+
* @return The builder.
79+
*/
80+
fun priority(priority: Int) = apply { this.priority = priority }
81+
82+
/**
83+
* Set whether the rule is active.
84+
* @param enabled Whether the rule is active.
85+
* @return The builder.
86+
*/
87+
fun enabled(enabled: Boolean) = apply { this.enabled = enabled }
88+
89+
/**
90+
* Build the [CreateRuleRequest].
91+
* @return A [CreateRuleRequest] with the provided values.
92+
* @throws IllegalArgumentException if [RuleActionType.BLOCK] is combined with other actions.
93+
*/
94+
fun build() = CreateRuleRequest(name, trigger, match, actions, description, priority, enabled)
95+
}
96+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.nylas.models
2+
3+
import com.squareup.moshi.Json
4+
5+
/**
6+
* Class representation of a request to add or remove items in a Nylas list.
7+
*/
8+
data class ListItemsRequest(
9+
/**
10+
* The values to add or remove. Max 1000 items per request.
11+
*/
12+
@Json(name = "items")
13+
val items: List<String>,
14+
) {
15+
/**
16+
* Builder for [ListItemsRequest].
17+
*/
18+
class Builder {
19+
private var items: List<String> = emptyList()
20+
21+
/**
22+
* Set the items to add or remove.
23+
* @param items The values to add or remove. Max 1000 items per request.
24+
* @return The builder.
25+
*/
26+
fun items(items: List<String>) = apply { this.items = items }
27+
28+
/**
29+
* Build the [ListItemsRequest].
30+
* @return A [ListItemsRequest] with the provided values.
31+
*/
32+
fun build() = ListItemsRequest(items)
33+
}
34+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package com.nylas.models
2+
3+
import com.squareup.moshi.Json
4+
5+
/**
6+
* Class representation of the query parameters for listing items in a Nylas list.
7+
*/
8+
data class ListNylasListItemsQueryParams(
9+
/**
10+
* The maximum number of objects to return.
11+
*/
12+
@Json(name = "limit")
13+
val limit: Int? = null,
14+
/**
15+
* Cursor for pagination. Pass the value of [ListResponse.nextCursor] to get the next page.
16+
*/
17+
@Json(name = "page_token")
18+
val pageToken: String? = null,
19+
) : IQueryParams {
20+
/**
21+
* Builder for [ListNylasListItemsQueryParams].
22+
*/
23+
class Builder {
24+
private var limit: Int? = null
25+
private var pageToken: String? = null
26+
27+
/**
28+
* Set the maximum number of objects to return.
29+
* @param limit The maximum number of objects to return.
30+
* @return The builder.
31+
*/
32+
fun limit(limit: Int) = apply { this.limit = limit }
33+
34+
/**
35+
* Set the pagination cursor.
36+
* @param pageToken Cursor for pagination. Pass the value of [ListResponse.nextCursor].
37+
* @return The builder.
38+
*/
39+
fun pageToken(pageToken: String) = apply { this.pageToken = pageToken }
40+
41+
/**
42+
* Build the [ListNylasListItemsQueryParams].
43+
* @return A [ListNylasListItemsQueryParams] with the provided values.
44+
*/
45+
fun build() = ListNylasListItemsQueryParams(limit, pageToken)
46+
}
47+
}

0 commit comments

Comments
 (0)