Skip to content

Commit 0e7a926

Browse files
authored
Add channel mute/unmute (#54)
1 parent 1bf5564 commit 0e7a926

File tree

6 files changed

+119
-0
lines changed

6 files changed

+119
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,4 @@ pip-selfcheck.json
6262
.vscode
6363
*,cover
6464
.eggs
65+
.envrc

stream_chat/async_chat/channel.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,3 +281,34 @@ async def hide(self, user_id):
281281

282282
async def show(self, user_id):
283283
return await self.client.post(f"{self.url}/show", data={"user_id": user_id})
284+
285+
async def mute(self, user_id, expiration=None):
286+
"""
287+
Mutes the channel for the given user for an optional expiration in milliseconds
288+
289+
:param user_id: the id of the user muting the channel
290+
:param expiration: optional expiration in ms. If not given, mute doesn't expire until unmutes
291+
:return: The server response
292+
"""
293+
294+
params = {
295+
"user_id": user_id,
296+
"channel_cid": self.cid,
297+
}
298+
if expiration:
299+
params["expiration"] = expiration
300+
return await self.client.post("moderation/mute/channel", data=params)
301+
302+
async def unmute(self, user_id):
303+
"""
304+
Unmutes the channel for the given user
305+
306+
:param user_id: the id of the user unmuting the channel
307+
:return: The server response
308+
"""
309+
310+
params = {
311+
"user_id": user_id,
312+
"channel_cid": self.cid,
313+
}
314+
return await self.client.post("moderation/unmute/channel", data=params)

stream_chat/base/channel.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@ def url(self):
1818
raise StreamChannelException("channel does not have an id")
1919
return f"channels/{self.channel_type}/{self.id}"
2020

21+
@property
22+
def cid(self):
23+
if self.id is None:
24+
raise StreamChannelException("channel does not have an id")
25+
return f"{self.channel_type}:{self.id}"
26+
2127
@abc.abstractmethod
2228
def send_message(self, message, user_id, **options):
2329
"""
@@ -277,6 +283,14 @@ def hide(self, user_id):
277283
def show(self, user_id):
278284
pass
279285

286+
@abc.abstractmethod
287+
def mute(self, user_id, expiration=None):
288+
pass
289+
290+
@abc.abstractmethod
291+
def unmute(self, user_id):
292+
pass
293+
280294

281295
def add_user_id(payload, user_id):
282296
return {**payload, "user": {"id": user_id}}

stream_chat/channel.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,34 @@ def hide(self, user_id):
279279

280280
def show(self, user_id):
281281
return self.client.post(f"{self.url}/show", data={"user_id": user_id})
282+
283+
def mute(self, user_id, expiration=None):
284+
"""
285+
Mutes the channel for the given user for an optional expiration in milliseconds
286+
287+
:param user_id: the id of the user muting the channel
288+
:param expiration: optional expiration in ms. If not given, mute doesn't expire until unmutes
289+
:return: The server response
290+
"""
291+
292+
params = {
293+
"user_id": user_id,
294+
"channel_cid": self.cid,
295+
}
296+
if expiration:
297+
params["expiration"] = expiration
298+
return self.client.post("moderation/mute/channel", data=params)
299+
300+
def unmute(self, user_id):
301+
"""
302+
Unmutes the channel for the given user
303+
304+
:param user_id: the id of the user unmuting the channel
305+
:return: The server response
306+
"""
307+
308+
params = {
309+
"user_id": user_id,
310+
"channel_cid": self.cid,
311+
}
312+
return self.client.post("moderation/unmute/channel", data=params)

stream_chat/tests/async_chat/test_channel.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,3 +288,24 @@ async def test_query_members(self, event_loop, client, channel):
288288
assert len(response) == 2
289289
assert response[0]["user"]["id"] == "jessica"
290290
assert response[1]["user"]["id"] == "john2"
291+
292+
@pytest.mark.asyncio
293+
async def test_mute_umute(self, event_loop, client, channel, random_users):
294+
user_id = random_users[0]["id"]
295+
response = await channel.mute(user_id, expiration=30000)
296+
assert "channel_mute" in response
297+
assert response["channel_mute"]["channel"]["cid"] == channel.cid
298+
assert response["channel_mute"]["user"]["id"] == user_id
299+
300+
response = await client.query_channels(
301+
{"muted": True, "cid": channel.cid},
302+
user_id=user_id,
303+
)
304+
assert len(response["channels"]) == 1
305+
306+
await channel.unmute(user_id)
307+
response = await client.query_channels(
308+
{"muted": True, "cid": channel.cid},
309+
user_id=user_id,
310+
)
311+
assert len(response["channels"]) == 0

stream_chat/tests/test_channel.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,24 @@ def test_query_members(self, client, channel):
258258
assert len(response) == 2
259259
assert response[0]["user"]["id"] == "jessica"
260260
assert response[1]["user"]["id"] == "john2"
261+
262+
def test_mute_unmute(self, client, channel, random_users):
263+
user_id = random_users[0]["id"]
264+
response = channel.mute(user_id, expiration=30000)
265+
assert "channel_mute" in response
266+
assert "expires" in response["channel_mute"]
267+
assert response["channel_mute"]["channel"]["cid"] == channel.cid
268+
assert response["channel_mute"]["user"]["id"] == user_id
269+
270+
response = client.query_channels(
271+
{"muted": True, "cid": channel.cid}, user_id=user_id
272+
)
273+
print(response, channel.cid)
274+
assert len(response["channels"]) == 1
275+
276+
channel.unmute(user_id)
277+
response = client.query_channels(
278+
{"muted": True, "cid": channel.cid},
279+
user_id=user_id,
280+
)
281+
assert len(response["channels"]) == 0

0 commit comments

Comments
 (0)