Coverage Summary for Class: ClipResource (io.github.captnblubber.twitchkt.helix.resource)

Class Method, % Branch, % Line, % Instruction, %
ClipResource 100% (10/10) 92.9% (26/28) 98.5% (66/67) 99% (518/523)
ClipResource$create$1
ClipResource$createFromVod$1
ClipResource$get$1
ClipResource$getAllClips$$inlined$paginate$default$1 0% (0/1)
ClipResource$getDownloadUrls$1
Total 90.9% (10/11) 92.9% (26/28) 98.5% (66/67) 99% (518/523)


 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.Clip
 import io.github.captnblubber.twitchkt.helix.model.ClipDownload
 import io.github.captnblubber.twitchkt.helix.model.CreatedClip
 import kotlinx.coroutines.flow.Flow
 import kotlin.time.Instant
 
 /**
  * Twitch Helix Clips API resource.
  *
  * Provides methods for creating and retrieving video clips.
  *
  * @see <a href="https://dev.twitch.tv/docs/api/reference/#create-clip">Twitch API Reference - Clips</a>
  */
 class ClipResource internal constructor(
     private val http: HelixHttpClient,
 ) {
     /**
      * [Twitch API: Create Clip](https://dev.twitch.tv/docs/api/reference/#create-clip)
      *
      * Creates a clip from the broadcaster's stream. This API captures up to 90 seconds of the
      * broadcaster's stream. By default, Twitch publishes up to the last 30 seconds of the 90
      * seconds window and provides a default title for the clip.
      *
      * Creating a clip is an asynchronous process. To determine whether the clip was successfully
      * created, call [get] using the clip ID that this request returned. If after 15 seconds
      * [get] hasn't returned the clip, assume it failed.
      *
      * @param broadcasterId the ID of the broadcaster whose stream you want to create a clip from.
      * @param title the title of the clip.
      * @param duration the length of the clip in seconds. Possible values range from 5 to 60
      * inclusively with a precision of 0.1. The default is 30.
      * @return the created clip info containing the clip ID and edit URL.
      */
     @RequiresScope(TwitchScope.CLIPS_EDIT)
     suspend fun create(
         broadcasterId: String,
         title: String? = null,
         duration: Double? = null,
     ): CreatedClip {
         http.validateScopes(TwitchScope.CLIPS_EDIT)
         val params =
             buildList {
                 add("broadcaster_id" to broadcasterId)
                 title?.let { add("title" to it) }
                 duration?.let { add("duration" to it.toString()) }
             }
         return http.post<CreatedClip>("clips", params = params).requireFirst("clips")
     }
 
     /**
      * [Twitch API: Create Clip From VOD](https://dev.twitch.tv/docs/api/reference/#create-clip-from-vod)
      *
      * Creates a clip from a broadcaster's VOD on behalf of the broadcaster or an editor of the
      * channel. Since a live stream is actively creating a VOD, this endpoint can also be used to
      * create a clip from earlier in the current stream.
      *
      * `vod_offset` indicates where the clip will end. The clip will start at
      * (`vodOffset` - `duration`) and end at `vodOffset`. This means that [vodOffset] must be
      * greater than or equal to [duration].
      *
      * @param editorId the user ID of the editor for the channel. If using the broadcaster's auth
      * token, this is the same as [broadcasterId]. Must match the user_id in the access token.
      * @param broadcasterId the user ID for the channel you want to create a clip for.
      * @param vodId the ID of the VOD to clip.
      * @param vodOffset the offset in the VOD (in seconds) where the clip ends.
      * @param title the title of the clip.
      * @param duration the length of the clip in seconds. Precision is 0.1. Defaults to 30.
      * Min: 5 seconds, Max: 60 seconds.
      * @return the created clip info containing the clip ID and edit URL.
      */
     @RequiresScope(TwitchScope.CHANNEL_MANAGE_CLIPS, TwitchScope.EDITOR_MANAGE_CLIPS)
     suspend fun createFromVod(
         editorId: String,
         broadcasterId: String,
         vodId: String,
         vodOffset: Int,
         title: String,
         duration: Double? = null,
     ): CreatedClip {
         http.validateAnyScope(TwitchScope.CHANNEL_MANAGE_CLIPS, TwitchScope.EDITOR_MANAGE_CLIPS)
         val params =
             buildList {
                 add("editor_id" to editorId)
                 add("broadcaster_id" to broadcasterId)
                 add("vod_id" to vodId)
                 add("vod_offset" to vodOffset.toString())
                 add("title" to title)
                 duration?.let { add("duration" to it.toString()) }
             }
         return http.post<CreatedClip>("videos/clips", params = params).requireFirst("videos/clips")
     }
 
     /**
      * [Twitch API: Get Clips](https://dev.twitch.tv/docs/api/reference/#get-clips)
      *
      * Gets all clips matching the filter criteria.
      * Automatically paginates through all results.
      *
      * @param broadcasterId an ID that identifies the broadcaster whose video clips you want to get.
      * @param gameId an ID that identifies the game whose clips you want to get.
      * @param ids clip IDs to get (max 100).
      * @param startedAt the start date used to filter clips.
      * @param endedAt the end date used to filter clips.
      * @param isFeatured if `true`, returns only featured clips. If `false`, only non-featured. If `null`, all clips.
      * @return a [Flow] of [Clip] objects.
      */
     fun getAllClips(
         broadcasterId: String? = null,
         gameId: String? = null,
         ids: List<String> = emptyList(),
         startedAt: Instant? = null,
         endedAt: Instant? = null,
         isFeatured: Boolean? = null,
     ): Flow<Clip> {
         val params =
             buildList {
                 broadcasterId?.let { add("broadcaster_id" to it) }
                 gameId?.let { add("game_id" to it) }
                 ids.forEach { add("id" to it) }
                 startedAt?.let { add("started_at" to it.toString()) }
                 endedAt?.let { add("ended_at" to it.toString()) }
                 isFeatured?.let { add("is_featured" to it.toString()) }
             }
         return http.paginate<Clip>("clips", params)
     }
 
     /**
      * [Twitch API: Get Clips](https://dev.twitch.tv/docs/api/reference/#get-clips)
      *
      * Gets a single page of clips matching the filter criteria.
      *
      * @param broadcasterId an ID that identifies the broadcaster whose video clips you want to get.
      * @param gameId an ID that identifies the game whose clips you want to get.
      * @param ids clip IDs to get (max 100).
      * @param startedAt the start date used to filter clips.
      * @param endedAt the end date used to filter clips.
      * @param isFeatured if `true`, returns only featured clips. If `false`, only non-featured. If `null`, all clips.
      * @param cursor the cursor used to get the next page of results.
      * @param pageSize the maximum number of clips to return per page (1-100, default 20). Null uses the API default.
      * @return a [Page] of [Clip] objects.
      */
     suspend fun get(
         broadcasterId: String? = null,
         gameId: String? = null,
         ids: List<String> = emptyList(),
         startedAt: Instant? = null,
         endedAt: Instant? = null,
         isFeatured: Boolean? = null,
         cursor: String? = null,
         pageSize: Int? = null,
     ): Page<Clip> {
         val params =
             buildList {
                 broadcasterId?.let { add("broadcaster_id" to it) }
                 gameId?.let { add("game_id" to it) }
                 ids.forEach { add("id" to it) }
                 startedAt?.let { add("started_at" to it.toString()) }
                 endedAt?.let { add("ended_at" to it.toString()) }
                 isFeatured?.let { add("is_featured" to it.toString()) }
                 cursor?.let { add("after" to it) }
             }
         return http.getPage(endpoint = "clips", params = params, pageSize = pageSize)
     }
 
     /**
      * [Twitch API: Get Clips Download](https://dev.twitch.tv/docs/api/reference/#get-clips-download)
      *
      * Provides URLs to download the video file(s) for the specified clips.
      *
      * Rate Limits: Limited to 100 requests per minute.
      *
      * @param editorId the user ID of the editor requesting the downloads. If using the
      * broadcaster's auth token, this is the same as [broadcasterId]. Must match the user_id
      * in the access token.
      * @param broadcasterId the ID of the broadcaster you want to download clips for.
      * @param clipIds the clip IDs to get download URLs for. You may specify up to 10 clips.
      * @return the list of clip download info with landscape and portrait URLs.
      */
     @RequiresScope(TwitchScope.CHANNEL_MANAGE_CLIPS, TwitchScope.EDITOR_MANAGE_CLIPS)
     suspend fun getDownloadUrls(
         editorId: String,
         broadcasterId: String,
         clipIds: List<String>,
     ): List<ClipDownload> {
         http.validateAnyScope(TwitchScope.CHANNEL_MANAGE_CLIPS, TwitchScope.EDITOR_MANAGE_CLIPS)
         val params =
             buildList {
                 add("editor_id" to editorId)
                 add("broadcaster_id" to broadcasterId)
                 clipIds.forEach { add("clip_id" to it) }
             }
         return http.get<ClipDownload>("clips/downloads", params).data
     }
 }