From 9ebdaa8a7170f0c56b6a9bb9e35da3a90cb96f2a Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Sun, 5 Nov 2023 13:15:42 +0100 Subject: [PATCH] [templating] Add `scheduleSegments` function Signed-off-by: Knut Ahlers --- docs/content/configuration/rule-examples.md | 22 ++++++++++++ docs/content/configuration/templating.md | 15 +++++++- internal/template/twitch/schedule.go | 39 +++++++++++++++++++++ pkg/twitch/schedule.go | 32 +++++++++-------- 4 files changed, 92 insertions(+), 16 deletions(-) create mode 100644 internal/template/twitch/schedule.go diff --git a/docs/content/configuration/rule-examples.md b/docs/content/configuration/rule-examples.md index 8900169..dc2ed76 100644 --- a/docs/content/configuration/rule-examples.md +++ b/docs/content/configuration/rule-examples.md @@ -55,6 +55,28 @@ title: "Rule Examples" - moderator ``` +## Display Stream-Schedule in Chat + +```yaml +- actions: + - type: respond + attributes: + message: |- + {{- $segs := scheduleSegments .channel 3 -}} + {{- $fmtSegs := list -}} + {{- range $segs -}} + {{- $fmtSegs = mustAppend $fmtSegs ( + printf "%s @ %s" + (.Category.Name) + (dateInZone "02.01. 15:40" .StartTime "Europe/Berlin") + ) -}} + {{- end -}} + Next streams are: {{ $fmtSegs | join ", " }} + - See more in the Twitch schedule: + https://www.twitch.tv/{{ fixUsername .channel }}/schedule + match_message: '!schedule\b' +``` + ## Game death counter with dynamic name ```yaml diff --git a/docs/content/configuration/templating.md b/docs/content/configuration/templating.md index bc87998..d0f8ad4 100644 --- a/docs/content/configuration/templating.md +++ b/docs/content/configuration/templating.md @@ -418,6 +418,19 @@ Example: * Die Oper haben wir überlebt, mal sehen was uns sonst noch alles töten möchte… - none ``` +### `scheduleSegments` + +Returns the next n segments in the channels schedule. If n is not given, returns all known segments. + +Syntax: `scheduleSegments [n]` + +Example: + +``` +# {{ $seg := scheduleSegments "luziferus" 1 | first }}Next Stream: {{ $seg.Title }} @ {{ dateInZone "2006-01-02 15:04" $seg.StartTime "Europe/Berlin" }} +* Next Stream: Little Nightmares @ 2023-11-05 18:00 +``` + ### `seededRandom` Returns a float value stable for the given seed @@ -428,7 +441,7 @@ Example: ``` # Your int this hour: {{ printf "%.0f" (mulf (seededRandom (list "int" .username (now | date "2006-01-02 15") | join ":")) 100) }}% -< Your int this hour: 37% +< Your int this hour: 73% ``` ### `streamUptime` diff --git a/internal/template/twitch/schedule.go b/internal/template/twitch/schedule.go new file mode 100644 index 0000000..229a4c5 --- /dev/null +++ b/internal/template/twitch/schedule.go @@ -0,0 +1,39 @@ +package twitch + +import ( + "context" + "math" + + "github.com/Luzifer/twitch-bot/v3/pkg/twitch" + "github.com/Luzifer/twitch-bot/v3/plugins" + "github.com/pkg/errors" +) + +func init() { + regFn = append( + regFn, + tplTwitchScheduleSegments, + ) +} + +func tplTwitchScheduleSegments(args plugins.RegistrationArguments) { + args.RegisterTemplateFunction("scheduleSegments", plugins.GenericTemplateFunctionGetter(func(channel string, n ...int) ([]twitch.ChannelStreamScheduleSegment, error) { + schedule, err := args.GetTwitchClient().GetChannelStreamSchedule(context.Background(), channel) + if err != nil { + return nil, errors.Wrap(err, "getting schedule") + } + + if len(n) > 0 { + return schedule.Segments[:int(math.Min(float64(n[0]), float64(len(schedule.Segments))))], nil + } + + return schedule.Segments, nil + }), plugins.TemplateFuncDocumentation{ + Description: "Returns the next n segments in the channels schedule. If n is not given, returns all known segments.", + Syntax: "scheduleSegments [n]", + Example: &plugins.TemplateFuncDocumentationExample{ + Template: `{{ $seg := scheduleSegments "luziferus" 1 | first }}Next Stream: {{ $seg.Title }} @ {{ dateInZone "2006-01-02 15:04" $seg.StartTime "Europe/Berlin" }}`, + FakedOutput: "Next Stream: Little Nightmares @ 2023-11-05 18:00", + }, + }) +} diff --git a/pkg/twitch/schedule.go b/pkg/twitch/schedule.go index b09ff65..2fce276 100644 --- a/pkg/twitch/schedule.go +++ b/pkg/twitch/schedule.go @@ -14,26 +14,28 @@ type ( // ChannelStreamSchedule represents the schedule of a channels with // its segments represening single planned streams ChannelStreamSchedule struct { - Segments []struct { - ID string `json:"id"` - StartTime time.Time `json:"start_time"` - EndTime time.Time `json:"end_time"` - Title string `json:"title"` - CanceledUntil *time.Time `json:"canceled_until"` - Category struct { - ID string `json:"id"` - Name string `json:"name"` - } `json:"category"` - IsRecurring bool `json:"is_recurring"` - } `json:"segments"` - BroadcasterID string `json:"broadcaster_id"` - BroadcasterName string `json:"broadcaster_name"` - BroadcasterLogin string `json:"broadcaster_login"` + Segments []ChannelStreamScheduleSegment `json:"segments"` + BroadcasterID string `json:"broadcaster_id"` + BroadcasterName string `json:"broadcaster_name"` + BroadcasterLogin string `json:"broadcaster_login"` Vacation struct { StartTime time.Time `json:"start_time"` EndTime time.Time `json:"end_time"` } `json:"vacation"` } + + ChannelStreamScheduleSegment struct { + ID string `json:"id"` + StartTime time.Time `json:"start_time"` + EndTime time.Time `json:"end_time"` + Title string `json:"title"` + CanceledUntil *time.Time `json:"canceled_until"` + Category struct { + ID string `json:"id"` + Name string `json:"name"` + } `json:"category"` + IsRecurring bool `json:"is_recurring"` + } ) // GetChannelStreamSchedule gets the broadcaster’s streaming schedule