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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Unreleased
* Added Manage Domains (`Client.domains`, `/v3/admin/domains`): list, create, find, update, delete, `get_info`, and `verify` with models in `nylas.models.domains`; optional `ServiceAccountSigner` (`nylas.handler.service_account`) for service-account headers (`X-Nylas-Kid`, `X-Nylas-Nonce`, `X-Nylas-Timestamp`, `X-Nylas-Signature`) on each `Domains` method; new `cryptography` dependency, RSA signing, and `HttpClient` `serialized_json_body` so signed payloads match the wire body
* Added Transactional Send: `Client.transactional_send.send()` for `POST /v3/domains/{domain_name}/messages/send`, with `TransactionalSendMessageRequest` and `TransactionalTemplate` models (JSON and multipart send behavior aligned with grant `messages.send`)
* Added Policies support (`Client.policies`, `/v3/policies`): list, create, find, update, and delete, with typed request/response models in `nylas.models.policies`
* Added Rules support (`Client.rules`): list, create, find, update, and delete for `/v3/rules`, plus `list_evaluations` for `/v3/grants/{grant_id}/rule-evaluations`, with typed request/response models in `nylas.models.rules`

v6.14.3
----------
Expand Down
11 changes: 11 additions & 0 deletions nylas/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from nylas.resources.policies import Policies
from nylas.resources.scheduler import Scheduler
from nylas.resources.notetakers import Notetakers
from nylas.resources.rules import Rules


class Client:
Expand Down Expand Up @@ -165,6 +166,16 @@ def policies(self) -> Policies:
"""
return Policies(self.http_client)

@property
def rules(self) -> Rules:
"""
Access the Rules API.

Returns:
The Rules API.
"""
return Rules(self.http_client)

@property
def messages(self) -> Messages:
"""
Expand Down
155 changes: 155 additions & 0 deletions nylas/models/rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
from dataclasses import dataclass
from typing import Any, List, Optional

from dataclasses_json import dataclass_json
from typing_extensions import NotRequired, TypedDict

from nylas.models.list_query_params import ListQueryParams


class ListRulesQueryParams(ListQueryParams):
"""Query parameters for listing rules."""

pass


class ListRuleEvaluationsQueryParams(ListQueryParams):
"""Query parameters for listing rule evaluations."""

pass


class RuleConditionRequest(TypedDict):
"""A single condition used in a rule match clause."""

field: str
operator: str
value: Any


class RuleMatchRequest(TypedDict):
"""Match clause for create/update rule requests."""

conditions: List[RuleConditionRequest]
operator: NotRequired[str]


class RuleActionRequest(TypedDict):
"""Action object used in create/update rule requests."""

type: str
value: NotRequired[str]


class CreateRuleRequest(TypedDict):
"""Request body for creating a rule."""

name: str
match: RuleMatchRequest
actions: List[RuleActionRequest]
description: NotRequired[str]
priority: NotRequired[int]
enabled: NotRequired[bool]
trigger: NotRequired[str]


class UpdateRuleRequest(TypedDict, total=False):
"""Request body for updating a rule."""

name: NotRequired[str]
match: NotRequired[RuleMatchRequest]
actions: NotRequired[List[RuleActionRequest]]
description: NotRequired[str]
priority: NotRequired[int]
enabled: NotRequired[bool]
trigger: NotRequired[str]


@dataclass_json
@dataclass
class RuleCondition:
"""A condition in a rule match clause."""

field: Optional[str] = None
operator: Optional[str] = None
value: Optional[Any] = None


@dataclass_json
@dataclass
class RuleMatch:
"""A rule's condition set and matching strategy."""

operator: Optional[str] = None
conditions: Optional[List[RuleCondition]] = None


@dataclass_json
@dataclass
class RuleAction:
"""An action applied when a rule matches."""

type: Optional[str] = None
value: Optional[str] = None


@dataclass_json
@dataclass
class Rule:
"""A rule used for automated filtering and routing."""

id: Optional[str] = None
name: Optional[str] = None
description: Optional[str] = None
priority: Optional[int] = None
enabled: Optional[bool] = None
trigger: Optional[str] = None
match: Optional[RuleMatch] = None
actions: Optional[List[RuleAction]] = None
application_id: Optional[str] = None
organization_id: Optional[str] = None
created_at: Optional[int] = None
updated_at: Optional[int] = None


@dataclass_json
@dataclass
class RuleEvaluationInput:
"""Sender data used as input to rule evaluation."""

from_address: Optional[str] = None
from_domain: Optional[str] = None
from_tld: Optional[str] = None


@dataclass_json
@dataclass
class RuleEvaluationAppliedActions:
"""Actions applied when rules matched."""

blocked: Optional[bool] = None
marked_as_spam: Optional[bool] = None
marked_as_read: Optional[bool] = None
marked_starred: Optional[bool] = None
archived: Optional[bool] = None
trashed: Optional[bool] = None
folder_ids: Optional[List[str]] = None


@dataclass_json
@dataclass
class RuleEvaluation:
"""An audit record describing rule evaluation for a grant."""

id: Optional[str] = None
grant_id: Optional[str] = None
message_id: Optional[str] = None
evaluated_at: Optional[int] = None
evaluation_stage: Optional[str] = None
evaluation_input: Optional[RuleEvaluationInput] = None
applied_actions: Optional[RuleEvaluationAppliedActions] = None
matched_rule_ids: Optional[List[str]] = None
application_id: Optional[str] = None
organization_id: Optional[str] = None
created_at: Optional[int] = None
updated_at: Optional[int] = None
94 changes: 94 additions & 0 deletions nylas/resources/rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
from nylas.config import RequestOverrides
from nylas.handler.api_resources import (
CreatableApiResource,
DestroyableApiResource,
FindableApiResource,
ListableApiResource,
UpdatableApiResource,
)
from nylas.models.response import DeleteResponse, ListResponse, Response
from nylas.models.rules import (
CreateRuleRequest,
ListRuleEvaluationsQueryParams,
ListRulesQueryParams,
Rule,
RuleEvaluation,
UpdateRuleRequest,
)


class Rules(
ListableApiResource,
FindableApiResource,
CreatableApiResource,
UpdatableApiResource,
DestroyableApiResource,
):
"""Nylas Rules API."""

def list(
self,
query_params: ListRulesQueryParams = None,
overrides: RequestOverrides = None,
) -> ListResponse[Rule]:
"""Return all rules for the application."""
return super().list(
path="/v3/rules",
response_type=Rule,
query_params=query_params,
overrides=overrides,
)

def create(
self,
request_body: CreateRuleRequest,
overrides: RequestOverrides = None,
) -> Response[Rule]:
"""Create a new rule."""
return super().create(
path="/v3/rules",
request_body=request_body,
response_type=Rule,
overrides=overrides,
)

def find(self, rule_id: str, overrides: RequestOverrides = None) -> Response[Rule]:
"""Return a specific rule by ID."""
return super().find(
path=f"/v3/rules/{rule_id}",
response_type=Rule,
overrides=overrides,
)

def update(
self,
rule_id: str,
request_body: UpdateRuleRequest,
overrides: RequestOverrides = None,
) -> Response[Rule]:
"""Update a rule by ID."""
return super().update(
path=f"/v3/rules/{rule_id}",
response_type=Rule,
request_body=request_body,
method="PUT",
overrides=overrides,
)

def destroy(self, rule_id: str, overrides: RequestOverrides = None) -> DeleteResponse:
"""Delete a rule by ID."""
return super().destroy(path=f"/v3/rules/{rule_id}", overrides=overrides)

def list_evaluations(
self,
grant_id: str,
query_params: ListRuleEvaluationsQueryParams = None,
overrides: RequestOverrides = None,
) -> ListResponse[RuleEvaluation]:
"""Return rule evaluation audit records for a grant."""
return super().list(
path=f"/v3/grants/{grant_id}/rule-evaluations",
response_type=RuleEvaluation,
query_params=query_params,
overrides=overrides,
)
Loading
Loading