// Block user call.blockUser({ user_id: "sara" }); // kick call.kickUser({ user_id: "sara" }); // Unblock user call.unblockUser({ user_id: "sara" });Overview
When running calls with a larger audience, you’ll often need moderation features to prevent abuse. Participants can share inappropriate content via
- The video feed
- Audio
- Screen share
- Chat messages
- Username
Stream has tools to help you manage these issues while on a call.
Kicking & Blocking a member from a call
Call can be configured to only be accessible to their members. To remove a user from a call and prevent from accessing again:
# Block user call.block_user(user_id='sara') # Kick user call.kick_user(user_id='sara') # Unblock user call.unblock_user(user_id='sara')// Block user call.BlockUser(ctx, &getstream.BlockUserRequest{ UserID: "sara", }) // Kick user call.KickUser(ctx, &getstream.KickUserRequest{ UserID: "sara", }) // Unblock user call.UnblockUser(ctx, &getstream.UnblockUserRequest{ UserID: "sara", })# Block user curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/unblock?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "user_id": "sara" }' # Kick user curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/kick?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "user_id": "sara" }' # Unblock user curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/unblock?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "user_id": "sara" }'Call permissions
You can configure if a screen share is enabled, disabled or requires requesting permission
call.update({ settings_override: { screensharing: { enabled: true, access_request_enabled: true }, }, });from getstream.models import CallSettingsRequest call.update( settings_override=CallSettingsRequest( screensharing=ScreensharingSettingsRequest( enabled=True, access_request_enabled=True ), ), )call.Update(ctx, &getstream.UpdateCallRequest{ SettingsOverride: &getstream.CallSettingsRequest{ Screensharing: &getstream.ScreensharingSettingsRequest{ Enabled: getstream.PtrTo(true), AccessRequestEnabled: getstream.PtrTo(true), }, }, })curl -X PATCH "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "Content-Type: application/json" \ -H "stream-auth-type: jwt" \ -d '{ "data": { "created_by_id": "john", "settings_override": { "screensharing": { "enabled": true, "access_request_enabled": true } } } }'Muting everyone
You can also mute every other participant’s video or audio.
// You can specify which kind of stream(s) to mute call.muteUsers({ mute_all_users: true, audio: true, muted_by_id: "john", });# You can specify which kind of stream(s) to mute call.mute_users( mute_all_users=True, audio=True, )// You can specify which kind of stream(s) to mute call.MuteUsers(ctx, &getstream.MuteUsersRequest{ MuteAllUsers: getstream.PtrTo(true), Audio: getstream.PtrTo(true), MutedByID: getstream.PtrTo("john"), })curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/mute_users?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "Content-Type: application/json" \ -H "stream-auth-type: jwt" \ -d '{ "mute_all_users": true, "audio": true, "muted_by_id": "john" }'Muting one participant’s video or audio (or both)
call.muteUsers({ user_ids: ["sara"], audio: true, video: true, screenshare: true, screenshare_audio: true, muted_by_id: "john", });call.mute_users( muted_by_id=user_id, user_ids=[alice.id, bob.id], audio=True, video=True, screenshare=True, screenshare_audio=True, )call.MuteUsers(ctx, &getstream.MuteUsersRequest{ UserIDs: []string{alice.id,bob.id}, Audio: getstream.PtrTo(true), Video: getstream.PtrTo(true), Screenshare: getstream.PtrTo(true), ScreenshareAudio: getstream.PtrTo(true), MutedByID: user_id, }) curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/mute_users?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "Content-Type: application/json" \ -H "stream-auth-type: jwt" \ -d '{ "user_ids": ["sara"], "audio": true, "video": true, "screenshare": true, "screenshare_audio": true, "muted_by_id": "john" }'Granting and revoking permissions
It’s possible for users to ask for any of the following permissions:
- Sending audio
- Sending video
- Sharing their screen
This feature is very common in audio rooms where users usually have to request permission to speak, but it can be useful in other call types and scenarios as well.
These requests will trigger the call.permission_request webhook.
This is how these requests can be accepted:
call.updateUserPermissions({ user_id: "sara", grant_permissions: [VideoOwnCapability.SEND_AUDIO], });from getstream.models import OwnCapability call.update_user_permissions( user_id=alice.id, grant_permissions=[OwnCapability.SEND_AUDIO], )call.UpdateUserPermissions(ctx, &getstream.UpdateUserPermissionsRequest{ UserID: "sara", GrantPermissions: []string{getream.SEND_AUDIO.String()}, })curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/user_permissions?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "Content-Type: application/json" \ -H "stream-auth-type: jwt" \ -d '{ "user_id": "sara", "grant_permissions": ["send-audio"] }'For moderation purposes any user’s permission to
- send audio
- send video
- share their screen
can be revoked at any time. This is how it can be done:
call.updateUserPermissions({ user_id: "sara", revoke_permissions: [VideoOwnCapability.SEND_AUDIO], });from getstream.models import OwnCapability call.update_user_permissions( user_id=alice.id, revoke_permissions=[OwnCapability.SEND_AUDIO], )call.UpdateUserPermissions(ctx, &getstream.UpdateUserPermissionsRequest{ UserID: "sara", RevokePermissions: []string{getream.SEND_AUDIO.String()}, })curl -X POST "https://video.stream-io-api.com/api/v2/video/call/${CALL_TYPE}/${CALL_ID}/user_permissions?api_key=${API_KEY}" \ -H "Authorization: ${TOKEN}" \ -H "Content-Type: application/json" \ -H "stream-auth-type: jwt" \ -d '{ "user_id": "sara", "revoke_permissions": ["send-audio"] }'Banning users
Users can be banned, when doing that they are not allowed to join or create calls. Banned users also cannot ring or notify other users.
client.moderation.ban({ target_user_id: "<bad user id>", banned_by_id: "<moderator id>", reason: "<reason>", }); // remove the ban for a user client.moderation.unban({ target_user_id: "<user id>", }); // ban a user for 30 minutes client.moderation.ban({ target_user_id: "<bad user id>", banned_by_id: "<moderator id>", timeout: 30, }); // ban a user and all users sharing the same IP client.moderation.ban({ target_user_id: "<bad user id>", banned_by_id: "<moderator id>", reason: "<reason>", ip_ban: true, });# ban a user client.ban( target_user_id=bad_user.id, banned_by_id=moderator.id, reason="banned reason here", ) # remove the ban for a user client.unban(target_user_id=bad_user.id) # ban a user for 30 minutes client.ban( target_user_id=bad_user.id, banned_by_id=moderator.id, timeout=30, ) # ban a user and all users sharing the same IP client.ban( target_user_id=bad_user.id, banned_by_id=moderator.id, reason="Banned user and all users sharing the same IP for half hour", ip_ban=True, )# Ban a user curl -X POST https://video.stream-io-api.com/api/v2/moderation/ban?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "target_user_id": "sara", "banned_by_id": "john", "reason": "banned reason here" }' # Removes ban for user curl -X DELETE https://video.stream-io-api.com/api/v2/moderation/ban?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "target_user_id": "sara" }' # Ban a user for 30 minutes curl -X POST https://video.stream-io-api.com/api/v2/moderation/ban?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "target_user_id": "sara", "banned_by_id": "john", "timeout": 30 }' # Ban a user and all users sharing the same IP curl -X POST https://video.stream-io-api.com/api/v2/moderation/ban?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "target_user_id": "sara", "banned_by_id": "john", "ip_ban": true }'Deactivating users
Deactivated users are no longer able to make any API call or connect to websockets (and receive updates on event of any kind).
client.deactivateUser({ user_id: '<id>', }); // reactivate client.reactivateUsers({ user_ids: ['<id>'], }); // deactivating users in bulk is performed asynchronously const deactivateResponse = client.deactivateUsers({ user_ids: ['<id1>', '<id2>'...], });# deactivate one user client.deactivate_user(user_id=alice.id) # reactivates the user client.reactivate_user(user_id=alice.id) # deactivating users in bulk is performed asynchronously response = client.deactivate_users(user_ids=[alice.id, bob.id])// deactivate one user response, err := client.DeactivateUser(ctx, "alice", &getstream.DeactivateUserRequest{}) // reactivates the user _, err = client.ReactivateUser(ctx, "alice", &getstream.ReactivateUserRequest{}) // deactivates users in bulk, this is an async operation _, err = client.DeactivateUsers(ctx, &getstream.DeactivateUsersRequest{ UserIds: []string{"alice", "bob"}, })// deactivate one user client.deactivateUser("john", DeactivateUserRequest.builder().build()).execute(); // reactivates the user client.reactivateUser("john", ReactivateUserRequest.builder().build()).execute(); // deactivates users in bulk, this is an async operation client.deactivateUsers(DeactivateUsersRequest.builder().userIds(List.of("<id1>", "<id2>")).build()).execute();# Deactivate users curl -X POST https://video.stream-io-api.com/api/v2/users/deactivate?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "user_ids": ["sara"] }' # Reactivate users curl -X POST https://video.stream-io-api.com/api/v2/users/reactivate?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H "Content-Type: application/json" \ -d '{ "user_ids": ["sara"] }'Deactivating users in bulk can take some time, this is how you can check the progress:
// Example of monitoring the status of an async task // The logic is same for all async tasks const response = await client.exportUsers({ user_ids: ["<user id1>", "<user id1>"], }); // you need to poll this endpoint const taskResponse = await client.getTask({ id: response.task_id }); console.log(taskResponse.status === "completed");# Example of monitoring the status of an async task # The logic is same for all async tasks response = client.export_users(user_ids=["<user id1>", "<user id1>"]) task_id = response.data.task_id # get information about the task task_status = client.get_task(task_id) # just an example, in reality it can take a few seconds for a task to be processed if task_status.data.status == "completed": print(task_status.data.result)// Example of monitoring the status of an async task // The logic is same for all async tasks response, err := client.ExportUsers(ctx, &getstream.ExportUsersRequest{ UserIds: []string{"<user id1>", "<user id1>"}, }) taskID := response.Data.TaskID // get information about the task taskStatus, err := client.GetTask(ctx, taskID, &getstream.GetTaskRequest{}) // just an example, in reality it can take a few seconds for a task to be processed if taskStatus.Data.Status == "completed" { println("Export is completed") }var response = client.exportUsers(ExportUsersRequest.builder().userIds(List.of("user-id1", "user-id2")).build()).execute(); var taskID = response.getData().getTaskID(); // get information about the task var taskStatus = client.getTask(taskID).execute(); // just an example, in reality it can take a few seconds for a task to be processed if (taskStatus.getData().getStatus().equals("completed")) { System.out.println("Export is completed"); }# When an operation is async, a task_id will be included in the API response # That task_id can be used to monitor the status of the task # When finished, task status will be completed curl -X GET https://video.stream-io-api.com/api/v2/tasks/${TASK_ID}?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt"For more information, please refer to the async operations guide
User blocking
Users can block other users using the API, when a user blocks another it will no longer receive ringing calls or notification from the blocked user.
client.blockUsers({ blocked_user_id: "bob", user_id: "alice", }); client.getBlockedUsers({ user_id: "alice" }); client.unblockUsers({ blocked_user_id: "bob", user_id: "alice", });# alice blocks bob client.block_users(blocked_user_id=bob.id, user_id=alice.id) # list blocked users by alice response = client.get_blocked_users(user_id=alice.id) # alice unblocks bob client.unblock_users(blocked_user_id=bob.id, user_id=alice.id)// alice blocks bob client.BlockUsers(ctx, &getstream.BlockUsersRequest{ BlockedUserID: "bob.ID", UserID: &alice.ID, }) // list blocked users by alice response, err := client.GetBlockedUsers(ctx, &getstream.GetBlockedUsersRequest{ UserID: &alice.ID, }) // alice unblocks bob client.UnblockUsers(ctx, &getstream.UnblockUsersRequest{ BlockedUserID: bob.ID, UserID: &alice.ID, })curl -X POST https://video.stream-io-api.com/api/v2/users/block?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H 'Content-Type: application/json' \ -d '{ "blocked_user_id": "bob", "user_id": "alice" }' USER_ID='alice'; ENCODED_USER_ID=$(echo ${USER_ID} | perl -MURI::Escape -lne 'print uri_escape($_)') curl -X GET "https://video.stream-io-api.com/api/v2/users/block?api_key=${API_KEY}&user_id=${ENCODED_USER_ID}" \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" curl -X POST https://video.stream-io-api.com/api/v2/users/unblock?api_key=${API_KEY} \ -H "Authorization: ${TOKEN}" \ -H "stream-auth-type: jwt" \ -H 'Content-Type: application/json' \ -d '{ "blocked_user_id": "bob", "user_id": "alice" }'