mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-12-20 11:51:17 +00:00
[template] Add lastPoll
function
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
04648a22e0
commit
79fb09469c
3 changed files with 109 additions and 0 deletions
|
@ -1,11 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/Luzifer/twitch-bot/v3/internal/service/access"
|
||||
"github.com/Luzifer/twitch-bot/v3/pkg/twitch"
|
||||
"github.com/Luzifer/twitch-bot/v3/plugins"
|
||||
)
|
||||
|
@ -16,6 +18,7 @@ func init() {
|
|||
tplFuncs.Register("followAge", plugins.GenericTemplateFunctionGetter(tplTwitchFollowAge))
|
||||
tplFuncs.Register("followDate", plugins.GenericTemplateFunctionGetter(tplTwitchFollowDate))
|
||||
tplFuncs.Register("doesFollowLongerThan", plugins.GenericTemplateFunctionGetter(tplTwitchDoesFollowLongerThan))
|
||||
tplFuncs.Register("lastPoll", plugins.GenericTemplateFunctionGetter(tplTwitchLastPoll))
|
||||
tplFuncs.Register("recentGame", plugins.GenericTemplateFunctionGetter(tplTwitchRecentGame))
|
||||
tplFuncs.Register("recentTitle", plugins.GenericTemplateFunctionGetter(tplTwitchRecentTitle))
|
||||
tplFuncs.Register("streamUptime", plugins.GenericTemplateFunctionGetter(tplTwitchStreamUptime))
|
||||
|
@ -85,6 +88,28 @@ func tplTwitchDoesFollowLongerThan(from, to string, t any) (bool, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func tplTwitchLastPoll(username string) (*twitch.PollInfo, error) {
|
||||
hasPollAccess, err := accessService.HasAnyPermissionForChannel(username, twitch.ScopeChannelReadPolls, twitch.ScopeChannelManagePolls)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "checking read-poll-permission")
|
||||
}
|
||||
|
||||
if !hasPollAccess {
|
||||
return nil, errors.Errorf("not authorized to read polls for channel %s", username)
|
||||
}
|
||||
|
||||
tc, err := accessService.GetTwitchClientForChannel(strings.TrimLeft(username, "#"), access.ClientConfig{
|
||||
TwitchClient: cfg.TwitchClient,
|
||||
TwitchClientSecret: cfg.TwitchClientSecret,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting twitch client for user")
|
||||
}
|
||||
|
||||
poll, err := tc.GetLatestPoll(context.Background(), strings.TrimLeft(username, "#"))
|
||||
return poll, errors.Wrap(err, "getting last poll")
|
||||
}
|
||||
|
||||
func tplTwitchRecentGame(username string, v ...string) (string, error) {
|
||||
game, _, err := twitchClient.GetRecentStreamInfo(strings.TrimLeft(username, "#"))
|
||||
if len(v) > 0 && (err != nil || game == "") {
|
||||
|
|
69
pkg/twitch/polls.go
Normal file
69
pkg/twitch/polls.go
Normal file
|
@ -0,0 +1,69 @@
|
|||
package twitch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const pollCacheTimeout = 10 * time.Second // Cache polls for a short moment to prevent multiple requests in one template
|
||||
|
||||
type (
|
||||
PollInfo struct {
|
||||
ID string `json:"id"`
|
||||
BroadcasterID string `json:"broadcaster_id"`
|
||||
BroadcasterName string `json:"broadcaster_name"`
|
||||
BroadcasterLogin string `json:"broadcaster_login"`
|
||||
Title string `json:"title"`
|
||||
Choices []struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Votes int `json:"votes"`
|
||||
ChannelPointsVotes int `json:"channel_points_votes"`
|
||||
} `json:"choices"`
|
||||
ChannelPointsVotingEnabled bool `json:"channel_points_voting_enabled"`
|
||||
ChannelPointsPerVote int `json:"channel_points_per_vote"`
|
||||
Status string `json:"status"`
|
||||
Duration int `json:"duration"`
|
||||
StartedAt time.Time `json:"started_at"`
|
||||
EndedAt *time.Time `json:"ended_at"`
|
||||
}
|
||||
)
|
||||
|
||||
func (c *Client) GetLatestPoll(ctx context.Context, username string) (*PollInfo, error) {
|
||||
cacheKey := []string{"getLatestPoll", username}
|
||||
if poll := c.apiCache.Get(cacheKey); poll != nil {
|
||||
return poll.(*PollInfo), nil
|
||||
}
|
||||
|
||||
id, err := c.GetIDForUsername(username)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "getting ID for username")
|
||||
}
|
||||
|
||||
var payload struct {
|
||||
Data []*PollInfo `json:"data"`
|
||||
}
|
||||
|
||||
if err := c.request(clientRequestOpts{
|
||||
AuthType: authTypeBearerToken,
|
||||
Context: ctx,
|
||||
Method: http.MethodGet,
|
||||
OKStatus: http.StatusOK,
|
||||
Out: &payload,
|
||||
URL: fmt.Sprintf("https://api.twitch.tv/helix/polls?broadcaster_id=%s&first=1", id),
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "request channel info")
|
||||
}
|
||||
|
||||
if len(payload.Data) < 1 {
|
||||
return nil, errors.New("no polls found")
|
||||
}
|
||||
|
||||
c.apiCache.Set(cacheKey, pollCacheTimeout, payload.Data[0])
|
||||
|
||||
return payload.Data[0], nil
|
||||
}
|
|
@ -218,6 +218,21 @@ Example:
|
|||
< example string
|
||||
```
|
||||
|
||||
#### `lastPoll`
|
||||
|
||||
Gets the last (currently running or archived) poll for the given channel (the channel must have given extended permission for poll access!)
|
||||
|
||||
Syntax: `lastPoll <channel>`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
# Last Poll: {{ (lastPoll .channel).Title }}
|
||||
< Last Poll: Und wie siehts im Template aus?
|
||||
```
|
||||
|
||||
See schema of returned object in [`pkg/twitch/polls.go#L13`](https://github.com/Luzifer/twitch-bot/blob/master/pkg/twitch/polls.go#L13)
|
||||
|
||||
#### `lastQuoteIndex`
|
||||
|
||||
Gets the last quote index in the quote database for the current channel
|
||||
|
|
Loading…
Reference in a new issue