[template] Add subCount, subPoints template functions

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2023-04-22 22:23:35 +02:00
parent f562c2fec5
commit f9c6be800b
Signed by: luzifer
GPG Key ID: D91C3E91E4CAD6F5
6 changed files with 142 additions and 5 deletions

View File

@ -0,0 +1,56 @@
package subscriber
import (
"context"
"strings"
"github.com/pkg/errors"
"github.com/Luzifer/twitch-bot/v3/pkg/twitch"
"github.com/Luzifer/twitch-bot/v3/plugins"
)
var (
permCheckFn plugins.ChannelPermissionCheckFunc
tcGetter func(string) (*twitch.Client, error)
)
func Register(args plugins.RegistrationArguments) error {
permCheckFn = args.HasPermissionForChannel
tcGetter = args.GetTwitchClientForChannel
args.RegisterTemplateFunction("subCount", plugins.GenericTemplateFunctionGetter(subCount))
args.RegisterTemplateFunction("subPoints", plugins.GenericTemplateFunctionGetter(subPoints))
return nil
}
func getSubInfo(broadcasterName string) (subCount, subPoints int64, err error) {
broadcasterName = strings.TrimLeft(broadcasterName, "#")
ok, err := permCheckFn(broadcasterName, twitch.ScopeChannelReadSubscriptions)
if err != nil {
return 0, 0, errors.Wrap(err, "checking for channel permissions")
}
if !ok {
return 0, 0, errors.Errorf("channel %q is missing permission %s", broadcasterName, twitch.ScopeChannelReadSubscriptions)
}
tc, err := tcGetter(broadcasterName)
if err != nil {
return 0, 0, errors.Wrap(err, "getting channel twitch-client")
}
sc, sp, err := tc.GetBroadcasterSubscriptionCount(context.Background(), broadcasterName)
return sc, sp, errors.Wrap(err, "fetching sub info")
}
func subCount(broadcasterName string) (int64, error) {
sc, _, err := getSubInfo(broadcasterName)
return sc, err
}
func subPoints(broadcasterName string) (int64, error) {
_, sp, err := getSubInfo(broadcasterName)
return sp, err
}

View File

@ -12,6 +12,7 @@ const (
ScopeChannelManageVIPS = "channel:manage:vips" ScopeChannelManageVIPS = "channel:manage:vips"
ScopeChannelManageWhispers = "user:manage:whispers" ScopeChannelManageWhispers = "user:manage:whispers"
ScopeChannelReadRedemptions = "channel:read:redemptions" ScopeChannelReadRedemptions = "channel:read:redemptions"
ScopeChannelReadSubscriptions = "channel:read:subscriptions"
ScopeModeratorManageAnnoucements = "moderator:manage:announcements" ScopeModeratorManageAnnoucements = "moderator:manage:announcements"
ScopeModeratorManageBannedUsers = "moderator:manage:banned_users" ScopeModeratorManageBannedUsers = "moderator:manage:banned_users"
ScopeModeratorManageChatMessages = "moderator:manage:chat_messages" ScopeModeratorManageChatMessages = "moderator:manage:chat_messages"

View File

@ -0,0 +1,51 @@
package twitch
import (
"context"
"fmt"
"net/http"
"time"
"github.com/pkg/errors"
)
const subInfoCacheTimeout = 300 * time.Second
type (
subInfo struct {
Total int64 `json:"total"`
Points int64 `json:"points"`
}
)
// GetBroadcasterSubscriptionCount gets a list of users that subscribe to the specified broadcaster.
func (c *Client) GetBroadcasterSubscriptionCount(ctx context.Context, broadcasterName string) (subCount, subPoints int64, err error) {
cacheKey := []string{"broadcasterSubscriptionCountByChannel", broadcasterName}
if d := c.apiCache.Get(cacheKey); d != nil {
data := d.(subInfo)
return data.Total, data.Points, nil
}
broadcaster, err := c.GetIDForUsername(broadcasterName)
if err != nil {
return 0, 0, errors.Wrap(err, "getting ID for broadcaster name")
}
var data subInfo
if err = c.request(clientRequestOpts{
AuthType: authTypeBearerToken,
Context: ctx,
Method: http.MethodGet,
OKStatus: http.StatusOK,
Out: &data,
URL: fmt.Sprintf("https://api.twitch.tv/helix/subscriptions?broadcaster_id=%s", broadcaster),
}); err != nil {
return 0, 0, errors.Wrap(err, "executing request")
}
// Lets not annoy the API but only ask every 5m
c.apiCache.Set(cacheKey, subInfoCacheTimeout, data)
return data.Total, data.Points, nil
}

View File

@ -43,6 +43,7 @@ import (
"github.com/Luzifer/twitch-bot/v3/internal/template/numeric" "github.com/Luzifer/twitch-bot/v3/internal/template/numeric"
"github.com/Luzifer/twitch-bot/v3/internal/template/random" "github.com/Luzifer/twitch-bot/v3/internal/template/random"
"github.com/Luzifer/twitch-bot/v3/internal/template/slice" "github.com/Luzifer/twitch-bot/v3/internal/template/slice"
"github.com/Luzifer/twitch-bot/v3/internal/template/subscriber"
"github.com/Luzifer/twitch-bot/v3/pkg/database" "github.com/Luzifer/twitch-bot/v3/pkg/database"
"github.com/Luzifer/twitch-bot/v3/pkg/twitch" "github.com/Luzifer/twitch-bot/v3/pkg/twitch"
"github.com/Luzifer/twitch-bot/v3/plugins" "github.com/Luzifer/twitch-bot/v3/plugins"
@ -84,6 +85,7 @@ var (
numeric.Register, numeric.Register,
random.Register, random.Register,
slice.Register, slice.Register,
subscriber.Register,
// API-only modules // API-only modules
customevent.Register, customevent.Register,

View File

@ -11,6 +11,7 @@ var (
twitch.ScopeChannelManageRaids: "start raids", twitch.ScopeChannelManageRaids: "start raids",
twitch.ScopeChannelManageVIPS: "manage VIPs", twitch.ScopeChannelManageVIPS: "manage VIPs",
twitch.ScopeChannelReadRedemptions: "see channel-point redemptions", twitch.ScopeChannelReadRedemptions: "see channel-point redemptions",
twitch.ScopeChannelReadSubscriptions: "see subscribed users / sub count / points",
twitch.ScopeModeratorReadFollowers: "see who follows this channel", twitch.ScopeModeratorReadFollowers: "see who follows this channel",
twitch.ScopeModeratorReadShoutouts: "see shoutouts created / received", twitch.ScopeModeratorReadShoutouts: "see shoutouts created / received",
} }

View File

@ -284,6 +284,19 @@ Example:
< Die Oper haben wir überlebt, mal sehen was uns sonst noch alles töten möchte - none < Die Oper haben wir überlebt, mal sehen was uns sonst noch alles töten möchte - none
``` ```
#### `seededRandom`
Returns a float value stable for the given seed
Syntax: `seededRandom <string-seed>`
Example:
```
# Your int this hour: {{ printf "%.0f" (multiply (seededRandom (list "int" .username (now "2006-01-02 15") | join ":")) 100) }}%
< Your int this hour: 17%
```
#### `streamUptime` #### `streamUptime`
Returns the duration the stream is online (causes an error if no current stream is found) Returns the duration the stream is online (causes an error if no current stream is found)
@ -297,17 +310,30 @@ Example:
< 3 hours, 56 minutes < 3 hours, 56 minutes
``` ```
#### `seededRandom` #### `subCount`
Returns a float value stable for the given seed Returns the number of subscribers (accounts) currently subscribed to the given channel
Syntax: `seededRandom <string-seed>` Syntax: `subCount <channel>`
Example: Example:
``` ```
# Your int this hour: {{ printf "%.0f" (multiply (seededRandom (list "int" .username (now "2006-01-02 15") | join ":")) 100) }}% # {{ subCount "luziferus" }}
< Your int this hour: 17% < 26
```
#### `subPoints`
Returns the number of sub-points currently given through the T1 / T2 / T3 subscriptions to the given channel
Syntax: `subPoints <channel>`
Example:
```
# {{ subPoints "luziferus" }}
< 26
``` ```
#### `tag` #### `tag`