Files
self 3e288a7e95 feat: prefix Sender plugin slug
Rename Sender plugin identity to tribe-one-sender across manifest, runtime API routes, metrics, e2e fixtures, and tests.
2026-06-17 22:33:33 +02:00

109 lines
2.9 KiB
Elixir

defmodule TribeOne.TribesPlugin.SenderWeb.StreamingAPIPlug do
@moduledoc false
import Plug.Conn
alias TribeOne.TribesPlugin.Sender.{Playback, Stats}
alias Tribes.RequestInfo
def init(opts), do: opts
def call(
%{
method: "GET",
path_info: ["plugins-api", "tribe-one-sender", "streams", stream_id, "playback"]
} =
conn,
_opts
) do
case Playback.playback_info(stream_id) do
{:ok, payload} -> json(conn, 200, payload)
{:error, :not_live} -> json(conn, 404, %{"error" => "not_live"})
{:error, _reason} -> json(conn, 404, %{"error" => "not_found"})
end
end
def call(
%{method: "POST", path_info: ["plugins-api", "tribe-one-sender", "player-events"]} = conn,
_opts
) do
{event, body, conn} = read_event(conn)
request_info = RequestInfo.fetch(conn)
record_result = record_player_event(event, request_info)
:telemetry.execute(
[:sender, :player, :event],
%{count: 1},
%{
body: body,
event: event,
remote_ip: conn.remote_ip,
request_ip: request_info.ip,
trusted_proxy?: request_info.trusted_proxy?
}
)
json(conn, 202, player_event_response(record_result))
end
def call(conn, _opts) do
json(conn, 404, %{"error" => "not_found"})
end
defp json(conn, status, payload) do
conn
|> put_resp_content_type("application/json")
|> send_resp(status, JSON.encode!(payload))
end
defp read_event(conn) do
cond do
event_params?(conn.body_params) ->
{conn.body_params, JSON.encode!(conn.body_params), conn}
event_params?(conn.params) ->
{conn.params, JSON.encode!(conn.params), conn}
true ->
read_raw_event(conn)
end
end
defp read_raw_event(conn) do
{:ok, body, conn} = read_body(conn)
{decode_body(body), body, conn}
end
defp decode_body(body) do
case JSON.decode(body) do
{:ok, decoded} when is_map(decoded) -> decoded
_other -> %{}
end
end
defp record_player_event(
%{
"event" => event,
"stream_id" => stream_id,
"generation_id" => generation_id,
"viewer_session_id" => viewer_session_id
},
%RequestInfo{trusted_proxy?: false, ip: remote_ip}
)
when event in ["heartbeat", "playback.started"] do
Stats.record_viewer_heartbeat(stream_id, generation_id, viewer_session_id, remote_ip)
end
defp record_player_event(_event, _request_info), do: :ignored
defp event_params?(%Plug.Conn.Unfetched{}), do: false
defp event_params?(params) when is_map(params), do: map_size(params) > 0
defp event_params?(_params), do: false
defp player_event_response(viewer_count) when is_integer(viewer_count) do
%{"ok" => true, "viewer_count" => viewer_count}
end
defp player_event_response(_record_result), do: %{"ok" => true}
end