Coverage Summary for Class: UserResource (io.github.captnblubber.twitchkt.helix.resource)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| UserResource |
100%
(15/15)
|
100%
(10/10)
|
100%
(57/57)
|
100%
(482/482)
|
| UserResource$blockUser$1 |
|
| UserResource$getActiveExtensions$1 |
|
| UserResource$getAllBlockedUsers$$inlined$paginate$default$1 |
0%
(0/1)
|
|
| UserResource$getAllBlockedUsers$1 |
100%
(1/1)
|
|
100%
(1/1)
|
100%
(35/35)
|
| UserResource$getBlockList$1 |
|
| UserResource$getExtensions$1 |
|
| UserResource$getUsers$1 |
|
| UserResource$unblockUser$1 |
|
| UserResource$updateActiveExtensions$1 |
|
| UserResource$updateUser$1 |
|
| Total |
94.1%
(16/17)
|
100%
(10/10)
|
100%
(58/58)
|
100%
(517/517)
|
package io.github.captnblubber.twitchkt.helix.resource
import io.github.captnblubber.twitchkt.auth.RequiresScope
import io.github.captnblubber.twitchkt.auth.TwitchScope
import io.github.captnblubber.twitchkt.helix.Page
import io.github.captnblubber.twitchkt.helix.internal.HelixHttpClient
import io.github.captnblubber.twitchkt.helix.internal.requireFirst
import io.github.captnblubber.twitchkt.helix.model.ActiveExtensions
import io.github.captnblubber.twitchkt.helix.model.BlockReason
import io.github.captnblubber.twitchkt.helix.model.BlockSourceContext
import io.github.captnblubber.twitchkt.helix.model.BlockedUser
import io.github.captnblubber.twitchkt.helix.model.User
import io.github.captnblubber.twitchkt.helix.model.UserExtension
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onStart
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Twitch Helix Users API resource.
*
* Provides methods for getting and updating user information, managing block lists,
* and working with user extensions.
*
* @see <a href="https://dev.twitch.tv/docs/api/reference/#get-users">Twitch API Reference - Users</a>
*/
class UserResource internal constructor(
private val http: HelixHttpClient,
) {
/**
* [Twitch API: Get Users](https://dev.twitch.tv/docs/api/reference/#get-users)
*
* Gets information about one or more users.
*
* You may look up users using their user ID, login name, or both but the total number of
* entries must not exceed 100.
*
* If you don't specify IDs or login names, the request returns information about the user
* in the access token if you specify a user access token.
*
* To include the user's verified email address in the response, you must use a user access
* token that includes the `user:read:email` scope.
*
* @param ids the IDs of the users to get. You may specify a maximum of 100 IDs.
* @param logins the login names of the users to get. You may specify a maximum of 100 login names.
* @return the list of matching users.
*/
suspend fun getUsers(
ids: List<String> = emptyList(),
logins: List<String> = emptyList(),
): List<User> {
val params =
buildList {
ids.forEach { add("id" to it) }
logins.forEach { add("login" to it) }
}
return http.get<User>("users", params).data
}
/**
* [Twitch API: Update User](https://dev.twitch.tv/docs/api/reference/#update-user)
*
* Updates the specified user's information. The user ID in the OAuth token identifies the
* user whose information you want to update.
*
* To include the user's verified email address in the response, the user access token must
* also include the `user:read:email` scope.
*
* @param description the string to update the channel's description to. The description is
* limited to a maximum of 300 characters. To remove the description, specify this parameter
* but don't set its value (e.g., pass an empty string).
* @return the updated user.
*/
@RequiresScope(TwitchScope.USER_EDIT)
suspend fun updateUser(description: String? = null): User {
http.validateScopes(TwitchScope.USER_EDIT)
val params =
buildList {
description?.let { add("description" to it) }
}
return http.put<User>("users", params = params).requireFirst("users")
}
/**
* [Twitch API: Get User Block List](https://dev.twitch.tv/docs/api/reference/#get-user-block-list)
*
* Gets all users that the broadcaster has blocked.
* Automatically paginates through all results.
*
* @param broadcasterId the ID of the broadcaster whose block list you want to get. This ID must match the user ID in the access token.
* @return a [Flow] of [BlockedUser] objects.
*/
@RequiresScope(TwitchScope.USER_READ_BLOCKED_USERS, TwitchScope.USER_MANAGE_BLOCKED_USERS)
fun getAllBlockedUsers(broadcasterId: String): Flow<BlockedUser> {
val params = listOf("broadcaster_id" to broadcasterId)
return http
.paginate<BlockedUser>("users/blocks", params)
.onStart { http.validateAnyScope(TwitchScope.USER_READ_BLOCKED_USERS, TwitchScope.USER_MANAGE_BLOCKED_USERS) }
}
/**
* [Twitch API: Get User Block List](https://dev.twitch.tv/docs/api/reference/#get-user-block-list)
*
* Gets a single page of users that the broadcaster has blocked.
*
* @param broadcasterId the ID of the broadcaster whose block list you want to get. This ID must match the user ID in the access token.
* @param cursor the cursor used to get the next page of results.
* @param pageSize the maximum number of items to return per page (1-100, default 20). Null uses the API default.
* @return a [Page] of [BlockedUser] objects.
*/
@RequiresScope(TwitchScope.USER_READ_BLOCKED_USERS, TwitchScope.USER_MANAGE_BLOCKED_USERS)
suspend fun getBlockList(
broadcasterId: String,
cursor: String? = null,
pageSize: Int? = null,
): Page<BlockedUser> {
http.validateAnyScope(TwitchScope.USER_READ_BLOCKED_USERS, TwitchScope.USER_MANAGE_BLOCKED_USERS)
val params =
buildList {
add("broadcaster_id" to broadcasterId)
cursor?.let { add("after" to it) }
}
return http.getPage(endpoint = "users/blocks", params = params, pageSize = pageSize)
}
/**
* [Twitch API: Block User](https://dev.twitch.tv/docs/api/reference/#block-user)
*
* Blocks the specified user from interacting with or being followed by the broadcaster.
* The user ID in the OAuth token identifies the broadcaster who is blocking the user.
*
* @param targetUserId the ID of the user to block.
* @param sourceContext the location where the harassment took place that is causing the
* broadcaster to block the user. Possible values are: `chat`, `whisper`.
* @param reason the reason the broadcaster is blocking the user. Possible values are:
* `harassment`, `spam`, `other`.
*/
@RequiresScope(TwitchScope.USER_MANAGE_BLOCKED_USERS)
suspend fun blockUser(
targetUserId: String,
sourceContext: BlockSourceContext? = null,
reason: BlockReason? = null,
) {
http.validateScopes(TwitchScope.USER_MANAGE_BLOCKED_USERS)
val params =
buildList {
add("target_user_id" to targetUserId)
sourceContext?.let { add("source_context" to it.value) }
reason?.let { add("reason" to it.value) }
}
http.putNoContent("users/blocks", params = params)
}
/**
* [Twitch API: Unblock User](https://dev.twitch.tv/docs/api/reference/#unblock-user)
*
* Removes the user from the broadcaster's block list. The user ID in the OAuth token
* identifies the broadcaster who is removing the block.
*
* @param targetUserId the ID of the user to unblock.
*/
@RequiresScope(TwitchScope.USER_MANAGE_BLOCKED_USERS)
suspend fun unblockUser(targetUserId: String) {
http.validateScopes(TwitchScope.USER_MANAGE_BLOCKED_USERS)
val params = listOf("target_user_id" to targetUserId)
http.deleteNoContent("users/blocks", params)
}
/**
* [Twitch API: Get User Extensions](https://dev.twitch.tv/docs/api/reference/#get-user-extensions)
*
* Gets a list of all extensions (both active and inactive) that the broadcaster has installed.
* The user ID in the access token identifies the broadcaster.
*
* @return the list of extensions that the user has installed.
*/
@RequiresScope(TwitchScope.USER_READ_BROADCAST, TwitchScope.USER_EDIT_BROADCAST)
suspend fun getExtensions(): List<UserExtension> {
http.validateAnyScope(TwitchScope.USER_READ_BROADCAST, TwitchScope.USER_EDIT_BROADCAST)
return http.get<UserExtension>("users/extensions/list").data
}
/**
* [Twitch API: Get User Active Extensions](https://dev.twitch.tv/docs/api/reference/#get-user-active-extensions)
*
* Gets the active extensions that the broadcaster has installed for each configuration
* slot (panel, overlay, or component). If the `user_id` query parameter is not provided,
* the user ID in the access token identifies the broadcaster.
*
* @param userId the ID of the broadcaster whose active extensions you want to get. This
* parameter is optional. If not specified, the user ID from the access token is used.
* @return the active extensions organized by type (panel, overlay, component).
*/
suspend fun getActiveExtensions(userId: String? = null): ActiveExtensions {
val params =
buildList {
userId?.let { add("user_id" to it) }
}
return http.getTyped<ActiveExtensionsResponse>("users/extensions", params).data
}
/**
* [Twitch API: Update User Extensions](https://dev.twitch.tv/docs/api/reference/#update-user-extensions)
*
* Updates the active extensions that the broadcaster has installed for each configuration
* slot (panel, overlay, or component).
*
* @param extensions the extensions to activate. Specifies which extensions to activate and
* in which slots. Slots that are not specified are disabled.
* @return the updated active extensions.
*/
@RequiresScope(TwitchScope.CHANNEL_MANAGE_EXTENSIONS, TwitchScope.USER_EDIT_BROADCAST)
suspend fun updateActiveExtensions(extensions: ActiveExtensions): ActiveExtensions {
http.validateAnyScope(TwitchScope.CHANNEL_MANAGE_EXTENSIONS, TwitchScope.USER_EDIT_BROADCAST)
return http
.putTyped<ActiveExtensionsResponse>(
"users/extensions",
body = http.encodeBody(ActiveExtensionsResponse(extensions)),
).data
}
}
@Serializable
internal data class ActiveExtensionsResponse(
val data: ActiveExtensions,
)