Current section

Files

Jump to
teac lib teac api predictions.ex
Raw

lib/teac/api/predictions.ex

defmodule Teac.Api.Predictions do
alias Teac.Api
@get_schema NimbleOptions.new!(
broadcaster_id: [type: :string, required: true],
id: [type: :string],
status: [type: :string],
after: [type: :string],
first: [type: :pos_integer]
)
@post_schema NimbleOptions.new!(
broadcaster_id: [type: :string, required: true],
title: [type: :string, required: true],
outcomes: [type: :any, required: true],
prediction_window: [type: :integer, required: true]
)
@patch_schema NimbleOptions.new!(
broadcaster_id: [type: :string, required: true],
id: [type: :string, required: true],
status: [type: :string, required: true],
winning_outcome_id: [type: :string]
)
@doc """
Gets a list of Channel Points Predictions that the broadcaster created.
## Authorization
Requires a user access token with the `channel:read:predictions` or `channel:manage:predictions` scope.
## Options
* `:broadcaster_id` - required. The broadcaster whose predictions to get.
* `:id` - optional. Filter by prediction ID.
* `:status` - optional. Filter by status.
* `:first` - optional. Maximum items to return. Default: 20, max: 25.
* `:after` - optional. Cursor for forward pagination.
"""
@spec get(Teac.Client.t(), keyword()) ::
{:ok, list(map()), String.t() | nil, Teac.RateLimit.t()} | {:error, Teac.Error.t()}
def get(%Teac.Client{} = client, opts \\ []) do
case NimbleOptions.validate(opts, @get_schema) do
{:ok, opts} ->
params =
[
broadcaster_id: opts[:broadcaster_id],
id: opts[:id],
status: opts[:status],
after: opts[:after],
first: opts[:first]
]
|> Enum.reject(fn {_, v} -> is_nil(v) end)
[base_url: Api.uri("predictions"), params: params, headers: Api.headers(client)]
|> Keyword.merge(Application.get_env(:teac, :api_req_options, []))
|> Req.get()
|> Api.handle_paginated_response()
{:error, %NimbleOptions.ValidationError{} = err} ->
{:error, err.message}
end
end
@doc "Streams all predictions, automatically following pagination cursors."
@spec stream(Teac.Client.t(), keyword()) :: Enumerable.t()
def stream(%Teac.Client{} = client, opts \\ []) do
Teac.Api.Pagination.stream(client, &get/2, opts)
end
@doc """
Creates a Channel Points Prediction for the broadcaster's channel.
## Authorization
Requires a user access token with the `channel:manage:predictions` scope.
## Options
* `:broadcaster_id` - required. The broadcaster creating the prediction.
* `:title` - required. The question for the prediction. Max 45 characters.
* `:outcomes` - required. List of outcome maps with a `"title"` key. Min 2, max 10.
* `:prediction_window` - required. Duration in seconds. Min 30, max 1800.
"""
@spec post(Teac.Client.t(), keyword()) :: {:ok, list(map()), Teac.RateLimit.t()} | {:error, Teac.Error.t()}
def post(%Teac.Client{} = client, opts \\ []) do
case NimbleOptions.validate(opts, @post_schema) do
{:ok, opts} ->
[
base_url: Api.uri("predictions"),
headers: Api.headers(client),
json: %{
broadcaster_id: opts[:broadcaster_id],
title: opts[:title],
outcomes: opts[:outcomes],
prediction_window: opts[:prediction_window]
}
]
|> Keyword.merge(Application.get_env(:teac, :api_req_options, []))
|> Req.post()
|> Api.handle_response()
{:error, %NimbleOptions.ValidationError{} = err} ->
{:error, err.message}
end
end
@doc """
Locks, resolves, or cancels a Channel Points Prediction.
## Authorization
Requires a user access token with the `channel:manage:predictions` scope.
## Options
* `:broadcaster_id` - required. The broadcaster who owns the prediction.
* `:id` - required. The ID of the prediction to update.
* `:status` - required. Valid values: `"RESOLVED"`, `"CANCELED"`, `"LOCKED"`.
* `:winning_outcome_id` - required when status is `"RESOLVED"`. The ID of the winning outcome.
"""
@spec patch(Teac.Client.t(), keyword()) :: {:ok, list(map()), Teac.RateLimit.t()} | {:error, Teac.Error.t()}
def patch(%Teac.Client{} = client, opts \\ []) do
case NimbleOptions.validate(opts, @patch_schema) do
{:ok, opts} ->
body =
%{
broadcaster_id: opts[:broadcaster_id],
id: opts[:id],
status: opts[:status],
winning_outcome_id: opts[:winning_outcome_id]
}
|> Enum.reject(fn {_, v} -> is_nil(v) end)
|> Map.new()
[base_url: Api.uri("predictions"), headers: Api.headers(client), json: body]
|> Keyword.merge(Application.get_env(:teac, :api_req_options, []))
|> Req.patch()
|> Api.handle_response()
{:error, %NimbleOptions.ValidationError{} = err} ->
{:error, err.message}
end
end
end