mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-09-19 18:12:55 +00:00
[template] Add subCount
, subPoints
template functions
Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
parent
f562c2fec5
commit
f9c6be800b
56
internal/template/subscriber/subscriber.go
Normal file
56
internal/template/subscriber/subscriber.go
Normal 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
|
||||||
|
}
|
@ -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"
|
||||||
|
51
pkg/twitch/subscriptions.go
Normal file
51
pkg/twitch/subscriptions.go
Normal 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
|
||||||
|
}
|
@ -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,
|
||||||
|
@ -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",
|
||||||
}
|
}
|
||||||
|
@ -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`
|
||||||
|
Loading…
Reference in New Issue
Block a user