diff --git a/resend/contacts/_contacts.py b/resend/contacts/_contacts.py index b35b643..3650a6c 100644 --- a/resend/contacts/_contacts.py +++ b/resend/contacts/_contacts.py @@ -250,29 +250,34 @@ def update(cls, params: UpdateParams) -> UpdateContactResponse: @classmethod def list( - cls, audience_id: Optional[str] = None, params: Optional[ListParams] = None + cls, + audience_id: Optional[str] = None, + params: Optional[ListParams] = None, + segment_id: Optional[str] = None, ) -> ListResponse: """ List all contacts. - Can list either global contacts or audience-specific contacts. + Can list global contacts, audience-specific contacts, or segment contacts. see more: https://resend.com/docs/api-reference/contacts/list-contacts Args: - audience_id (Optional[str]): The audience ID. If not provided, lists all global contacts. + audience_id (Optional[str]): Deprecated. Use segment_id instead. params (Optional[ListParams]): Optional pagination parameters - limit: Number of contacts to retrieve (max 100, min 1). If not provided, all contacts will be returned without pagination. - after: ID after which to retrieve more contacts - before: ID before which to retrieve more contacts + segment_id (Optional[str]): The segment ID. When provided, lists contacts + in the segment via GET /segments/{segment_id}/contacts. Returns: ListResponse: A list of contact objects """ - if audience_id: - # Audience-specific contacts + if segment_id: + base_path = f"/segments/{segment_id}/contacts" + elif audience_id: base_path = f"/audiences/{audience_id}/contacts" else: - # Global contacts base_path = "/contacts" query_params = cast(Dict[Any, Any], params) if params else None @@ -419,21 +424,28 @@ async def update_async(cls, params: UpdateParams) -> UpdateContactResponse: @classmethod async def list_async( - cls, audience_id: Optional[str] = None, params: Optional[ListParams] = None + cls, + audience_id: Optional[str] = None, + params: Optional[ListParams] = None, + segment_id: Optional[str] = None, ) -> ListResponse: """ List all contacts (async). - Can list either global contacts or audience-specific contacts. + Can list global contacts, audience-specific contacts, or segment contacts. see more: https://resend.com/docs/api-reference/contacts/list-contacts Args: - audience_id (Optional[str]): The audience ID. If not provided, lists all global contacts. + audience_id (Optional[str]): Deprecated. Use segment_id instead. params (Optional[ListParams]): Optional pagination parameters + segment_id (Optional[str]): The segment ID. When provided, lists contacts + in the segment via GET /segments/{segment_id}/contacts. Returns: ListResponse: A list of contact objects """ - if audience_id: + if segment_id: + base_path = f"/segments/{segment_id}/contacts" + elif audience_id: base_path = f"/audiences/{audience_id}/contacts" else: base_path = "/contacts" diff --git a/tests/contacts_async_test.py b/tests/contacts_async_test.py index 2e73cf5..c24f758 100644 --- a/tests/contacts_async_test.py +++ b/tests/contacts_async_test.py @@ -248,3 +248,38 @@ async def test_should_list_contacts_async_raise_exception_when_no_content( _ = await resend.Contacts.list_async( audience_id="48c269ed-9873-4d60-bdd9-cd7e6fc0b9b8" ) + + async def test_contacts_list_async_by_segment_id(self) -> None: + self.set_mock_json( + { + "object": "list", + "has_more": False, + "data": [ + { + "id": "e169aa45-1ecf-4183-9955-b1499d5701d3", + "email": "steve.wozniak@gmail.com", + "first_name": "Steve", + "last_name": "Wozniak", + "created_at": "2023-10-06T23:47:56.678Z", + "unsubscribed": False, + } + ], + } + ) + + contacts: resend.Contacts.ListResponse = await resend.Contacts.list_async( + segment_id="78261eea-8f8b-4381-83c6-79fa7120f1cf" + ) + assert contacts["object"] == "list" + assert contacts["has_more"] is False + assert contacts["data"][0]["id"] == "e169aa45-1ecf-4183-9955-b1499d5701d3" + assert contacts["data"][0]["email"] == "steve.wozniak@gmail.com" + + async def test_should_list_contacts_async_by_segment_raise_exception_when_no_content( + self, + ) -> None: + self.set_mock_json(None) + with pytest.raises(NoContentError): + _ = await resend.Contacts.list_async( + segment_id="78261eea-8f8b-4381-83c6-79fa7120f1cf" + ) diff --git a/tests/contacts_test.py b/tests/contacts_test.py index 6441df2..c0f965c 100644 --- a/tests/contacts_test.py +++ b/tests/contacts_test.py @@ -387,6 +387,65 @@ def test_contacts_list_global(self) -> None: assert contacts["data"][0]["id"] == "global-1" assert contacts["data"][1]["id"] == "global-2" + def test_contacts_list_by_segment_id(self) -> None: + self.set_mock_json( + { + "object": "list", + "has_more": False, + "data": [ + { + "id": "e169aa45-1ecf-4183-9955-b1499d5701d3", + "email": "steve.wozniak@gmail.com", + "first_name": "Steve", + "last_name": "Wozniak", + "created_at": "2023-10-06T23:47:56.678Z", + "unsubscribed": False, + } + ], + } + ) + + contacts: resend.Contacts.ListResponse = resend.Contacts.list( + segment_id="78261eea-8f8b-4381-83c6-79fa7120f1cf" + ) + assert contacts["object"] == "list" + assert contacts["has_more"] is False + assert contacts["data"][0]["id"] == "e169aa45-1ecf-4183-9955-b1499d5701d3" + assert contacts["data"][0]["email"] == "steve.wozniak@gmail.com" + + def test_contacts_list_by_segment_id_with_pagination(self) -> None: + self.set_mock_json( + { + "object": "list", + "has_more": True, + "data": [ + { + "id": "contact-1", + "email": "contact1@example.com", + "first_name": "Contact", + "last_name": "One", + "created_at": "2023-10-06T23:47:56.678Z", + "unsubscribed": False, + } + ], + } + ) + + params: resend.Contacts.ListParams = {"limit": 10, "after": "previous-id"} + contacts: resend.Contacts.ListResponse = resend.Contacts.list( + segment_id="78261eea-8f8b-4381-83c6-79fa7120f1cf", params=params + ) + assert contacts["object"] == "list" + assert contacts["has_more"] is True + assert len(contacts["data"]) == 1 + + def test_should_list_contacts_by_segment_raise_exception_when_no_content( + self, + ) -> None: + self.set_mock_json(None) + with self.assertRaises(NoContentError): + _ = resend.Contacts.list(segment_id="78261eea-8f8b-4381-83c6-79fa7120f1cf") + def test_contacts_remove_global_by_id(self) -> None: self.set_mock_json( {