diff --git a/stream_chat/async_chat/campaign.py b/stream_chat/async_chat/campaign.py index 521e7a8..4dfd8e9 100644 --- a/stream_chat/async_chat/campaign.py +++ b/stream_chat/async_chat/campaign.py @@ -38,10 +38,12 @@ async def delete(self, **options: Any) -> StreamResponse: ) async def start( - self, scheduled_for: Optional[Union[str, datetime.datetime]] = None + self, + scheduled_for: Optional[Union[str, datetime.datetime]] = None, + stop_at: Optional[Union[str, datetime.datetime]] = None, ) -> StreamResponse: return await self.client.start_campaign( # type: ignore - campaign_id=self.campaign_id, scheduled_for=scheduled_for + campaign_id=self.campaign_id, scheduled_for=scheduled_for, stop_at=stop_at ) async def stop(self) -> StreamResponse: diff --git a/stream_chat/async_chat/client.py b/stream_chat/async_chat/client.py index 05ad3e8..f46e1f0 100644 --- a/stream_chat/async_chat/client.py +++ b/stream_chat/async_chat/client.py @@ -485,7 +485,7 @@ async def send_file( return await self._parse_response(response) async def create_blocklist( - self, name: str, words: Iterable[str], type: str = "regular" + self, name: str, words: Iterable[str], type: str = "word" ) -> StreamResponse: return await self.post( "blocklists", data={"name": name, "words": words, "type": type} @@ -676,12 +676,17 @@ async def start_campaign( self, campaign_id: str, scheduled_for: Optional[Union[str, datetime.datetime]] = None, + stop_at: Optional[Union[str, datetime.datetime]] = None, ) -> StreamResponse: payload = {} if scheduled_for is not None: if isinstance(scheduled_for, datetime.datetime): scheduled_for = scheduled_for.isoformat() payload["scheduled_for"] = scheduled_for + if stop_at is not None: + if isinstance(stop_at, datetime.datetime): + stop_at = stop_at.isoformat() + payload["stop_at"] = stop_at return await self.post(f"campaigns/{campaign_id}/start", data=payload) async def stop_campaign(self, campaign_id: str) -> StreamResponse: diff --git a/stream_chat/base/campaign.py b/stream_chat/base/campaign.py index bbe5f19..70aba77 100644 --- a/stream_chat/base/campaign.py +++ b/stream_chat/base/campaign.py @@ -40,7 +40,9 @@ def delete(self) -> Union[StreamResponse, Awaitable[StreamResponse]]: @abc.abstractmethod def start( - self, scheduled_for: Optional[Union[str, datetime.datetime]] = None + self, + scheduled_for: Optional[Union[str, datetime.datetime]] = None, + stop_at: Optional[Union[str, datetime.datetime]] = None, ) -> Union[StreamResponse, Awaitable[StreamResponse]]: pass diff --git a/stream_chat/base/client.py b/stream_chat/base/client.py index 38ef942..747a989 100644 --- a/stream_chat/base/client.py +++ b/stream_chat/base/client.py @@ -765,7 +765,7 @@ def send_file( @abc.abstractmethod def create_blocklist( - self, name: str, words: Iterable[str], type: str = "regular" + self, name: str, words: Iterable[str], type: str = "word" ) -> Union[StreamResponse, Awaitable[StreamResponse]]: """ Create a blocklist @@ -1102,6 +1102,7 @@ def start_campaign( self, campaign_id: str, scheduled_for: Optional[Union[str, datetime.datetime]] = None, + stop_at: Optional[Union[str, datetime.datetime]] = None, ) -> Union[StreamResponse, Awaitable[StreamResponse]]: """ Start a campaign at given time or now if not specified diff --git a/stream_chat/campaign.py b/stream_chat/campaign.py index 3063a8c..b9eafea 100644 --- a/stream_chat/campaign.py +++ b/stream_chat/campaign.py @@ -36,10 +36,12 @@ def delete(self, **options: Any) -> StreamResponse: ) def start( - self, scheduled_for: Optional[Union[str, datetime.datetime]] = None + self, + scheduled_for: Optional[Union[str, datetime.datetime]] = None, + stop_at: Optional[Union[str, datetime.datetime]] = None, ) -> StreamResponse: return self.client.start_campaign( # type: ignore - campaign_id=self.campaign_id, scheduled_for=scheduled_for + campaign_id=self.campaign_id, scheduled_for=scheduled_for, stop_at=stop_at ) def stop(self) -> StreamResponse: diff --git a/stream_chat/client.py b/stream_chat/client.py index 9b4aac4..ece696b 100644 --- a/stream_chat/client.py +++ b/stream_chat/client.py @@ -467,7 +467,7 @@ def send_file( return self._parse_response(response) def create_blocklist( - self, name: str, words: Iterable[str], type: str = "regular" + self, name: str, words: Iterable[str], type: str = "word" ) -> StreamResponse: return self.post( "blocklists", data={"name": name, "words": words, "type": type} @@ -609,7 +609,7 @@ def remove_segment_targets( ) def campaign( # type: ignore - self, campaign_id: Optional[str] = None, data: CampaignData = None + self, campaign_id: Optional[str] = None, data: Optional[CampaignData] = None ) -> Campaign: return Campaign(client=self, campaign_id=campaign_id, data=data) @@ -649,12 +649,17 @@ def start_campaign( self, campaign_id: str, scheduled_for: Optional[Union[str, datetime.datetime]] = None, + stop_at: Optional[Union[str, datetime.datetime]] = None, ) -> StreamResponse: payload = {} if scheduled_for is not None: if isinstance(scheduled_for, datetime.datetime): scheduled_for = scheduled_for.isoformat() payload["scheduled_for"] = scheduled_for + if stop_at is not None: + if isinstance(stop_at, datetime.datetime): + stop_at = stop_at.isoformat() + payload["stop_at"] = stop_at return self.post(f"campaigns/{campaign_id}/start", data=payload) def stop_campaign(self, campaign_id: str) -> StreamResponse: diff --git a/stream_chat/tests/async_chat/test_campaign.py b/stream_chat/tests/async_chat/test_campaign.py index beefb1a..24be9dc 100644 --- a/stream_chat/tests/async_chat/test_campaign.py +++ b/stream_chat/tests/async_chat/test_campaign.py @@ -92,8 +92,11 @@ async def test_campaign_start_stop( now = datetime.datetime.now(datetime.timezone.utc) one_hour_later = now + datetime.timedelta(hours=1) + two_hours_later = now + datetime.timedelta(hours=2) - started = await campaign.start(scheduled_for=one_hour_later) + started = await campaign.start( + scheduled_for=one_hour_later, stop_at=two_hours_later + ) assert started.is_ok() assert "campaign" in started assert "id" in started["campaign"] diff --git a/stream_chat/tests/async_chat/test_client.py b/stream_chat/tests/async_chat/test_client.py index 4d4c711..e40a740 100644 --- a/stream_chat/tests/async_chat/test_client.py +++ b/stream_chat/tests/async_chat/test_client.py @@ -580,7 +580,7 @@ async def test_query_channels_members_in( assert len(response["channels"][0]["members"]) == 9 async def test_create_blocklist(self, client: StreamChatAsync): - await client.create_blocklist(name="Foo", words=["fudge", "heck"]) + await client.create_blocklist(name="Foo", words=["fudge", "heck"], type="word") async def test_list_blocklists(self, client: StreamChatAsync): response = await client.list_blocklists() diff --git a/stream_chat/tests/test_campaign.py b/stream_chat/tests/test_campaign.py index b8d9c89..3083500 100644 --- a/stream_chat/tests/test_campaign.py +++ b/stream_chat/tests/test_campaign.py @@ -96,8 +96,9 @@ def test_campaign_start_stop(self, client: StreamChat, random_user: Dict): now = datetime.datetime.now(datetime.timezone.utc) one_hour_later = now + datetime.timedelta(hours=1) + two_hours_later = now + datetime.timedelta(hours=2) - started = campaign.start(scheduled_for=one_hour_later) + started = campaign.start(scheduled_for=one_hour_later, stop_at=two_hours_later) assert started.is_ok() assert "campaign" in started assert "id" in started["campaign"] diff --git a/stream_chat/tests/test_client.py b/stream_chat/tests/test_client.py index 97ca9c4..e600049 100644 --- a/stream_chat/tests/test_client.py +++ b/stream_chat/tests/test_client.py @@ -549,7 +549,7 @@ def test_query_channels_members_in( assert len(response["channels"][0]["members"]) == 9 def test_create_blocklist(self, client: StreamChat): - client.create_blocklist(name="Foo", words=["fudge", "heck"], type="regular") + client.create_blocklist(name="Foo", words=["fudge", "heck"], type="word") def test_list_blocklists(self, client: StreamChat): response = client.list_blocklists() diff --git a/stream_chat/types/campaign.py b/stream_chat/types/campaign.py index 2e401dc..bc1b730 100644 --- a/stream_chat/types/campaign.py +++ b/stream_chat/types/campaign.py @@ -31,11 +31,13 @@ class ChannelTemplate(TypedDict, total=False): Parameters: type: The type of channel. id: The ID of the channel. + members: List of member IDs. custom: Custom data. """ type: str - id: str + id: Optional[str] + members: Optional[List[str]] custom: Optional[Dict]