mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2025-01-08 20:41:30 +00:00
Compare commits
13 commits
abe839df3a
...
4dd903288c
Author | SHA1 | Date | |
---|---|---|---|
4dd903288c | |||
9d1ede2b1e | |||
60abc308fb | |||
e8eb6cd0f4 | |||
bc9c3eeb15 | |||
bb83c34344 | |||
f684abc29f | |||
1d4cbd9a66 | |||
0e4a963bc7 | |||
3f376cb2ce | |||
46db72b2cc | |||
c3085ea7f9 | |||
031ad331e4 |
30 changed files with 594 additions and 106 deletions
|
@ -9,7 +9,9 @@ run:
|
|||
modules-download-mode: readonly
|
||||
|
||||
output:
|
||||
format: tab
|
||||
formats:
|
||||
- format: tab
|
||||
path: stdout
|
||||
|
||||
issues:
|
||||
# This disables the included exclude-list in golangci-lint as that
|
||||
|
|
35
History.md
35
History.md
|
@ -1,3 +1,38 @@
|
|||
# 3.28.1 / 2024-04-02
|
||||
|
||||
* New Features
|
||||
* [spotify] Add `spotifyLink` template function
|
||||
* [templating] add `humanDateDiff` and `formatHumanDateDiff` functions
|
||||
|
||||
* Improvements
|
||||
* [eventsub] Suppress error on abnormal closure and reconnect
|
||||
* [overlays] Lower socket abnormal closure log-level to warning
|
||||
|
||||
* Bugfixes
|
||||
* [core] Update dependencies
|
||||
* [docs] Fix: Add missing documentation for `adbreak_begin`
|
||||
* [eventsub] Fix: Do not retry subscription on collision
|
||||
* [eventsub] Fix: Twitch renamed field in `adbreak_begin`
|
||||
|
||||
> [!NOTE]
|
||||
> Re-release of v3.28.0 as of broken tests in that release, no functional changes.
|
||||
|
||||
# 3.28.0 / 2024-04-02
|
||||
|
||||
* New Features
|
||||
* [spotify] Add `spotifyLink` template function
|
||||
* [templating] add `humanDateDiff` and `formatHumanDateDiff` functions
|
||||
|
||||
* Improvements
|
||||
* [eventsub] Suppress error on abnormal closure and reconnect
|
||||
* [overlays] Lower socket abnormal closure log-level to warning
|
||||
|
||||
* Bugfixes
|
||||
* [core] Update dependencies
|
||||
* [docs] Fix: Add missing documentation for `adbreak_begin`
|
||||
* [eventsub] Fix: Do not retry subscription on collision
|
||||
* [eventsub] Fix: Twitch renamed field in `adbreak_begin`
|
||||
|
||||
# 3.27.0 / 2024-03-20
|
||||
|
||||
* New Features
|
||||
|
|
|
@ -2,6 +2,17 @@
|
|||
title: "Available Events"
|
||||
---
|
||||
|
||||
## `adbreak_begin`
|
||||
|
||||
Ad-break has begun and ads are playing now in mentioned channel.
|
||||
|
||||
Fields:
|
||||
|
||||
- `channel` - The channel the event occurred in
|
||||
- `duration` - Duration of the ads in seconds
|
||||
- `is_automatic` - Were the ads started by the ad-manager?
|
||||
- `started_at` - When did the ad-break start
|
||||
|
||||
## `ban`
|
||||
|
||||
Moderator action caused a user to be banned from chat.
|
||||
|
|
|
@ -256,6 +256,19 @@ Example:
|
|||
< 5 hours, 33 minutes, 12 seconds - 5 hours, 33 minutes
|
||||
```
|
||||
|
||||
### `formatHumanDateDiff`
|
||||
|
||||
Formats a DateInterval object according to the format (%Y, %M, %D, %H, %I, %S for years, months, days, hours, minutes, seconds - Lowercase letters without leading zeros)
|
||||
|
||||
Syntax: `formatHumanDateDiff <format> <obj>`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
# {{ humanDateDiff (mustToDate "2006-01-02 -0700" "2024-05-05 +0200") (mustToDate "2006-01-02 -0700" "2023-01-09 +0100") | formatHumanDateDiff "%Y years, %M months, %D days" }}
|
||||
< 01 years, 03 months, 25 days
|
||||
```
|
||||
|
||||
### `group`
|
||||
|
||||
Gets matching group specified by index from `match_message` regular expression, when `fallback` is defined, it is used when group has an empty match
|
||||
|
@ -271,6 +284,19 @@ Example:
|
|||
< test - oops
|
||||
```
|
||||
|
||||
### `humanDateDiff`
|
||||
|
||||
Returns a DateInterval object describing the time difference between a and b in a "human" way of counting the time (2023-02-05 -> 2024-03-05 = 1 Year, 1 Month)
|
||||
|
||||
Syntax: `humanDateDiff <a> <b>`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
# {{ humanDateDiff (mustToDate "2006-01-02 -0700" "2024-05-05 +0200") (mustToDate "2006-01-02 -0700" "2023-01-09 +0100") }}
|
||||
< {1 3 25 23 0 0}
|
||||
```
|
||||
|
||||
### `idForUsername`
|
||||
|
||||
Returns the user-id for the given username
|
||||
|
@ -441,7 +467,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: 88%
|
||||
< Your int this hour: 70%
|
||||
```
|
||||
|
||||
### `spotifyCurrentPlaying`
|
||||
|
@ -459,6 +485,21 @@ Example:
|
|||
* Beast in Black - Die By The Blade
|
||||
```
|
||||
|
||||
### `spotifyLink`
|
||||
|
||||
Retrieves the link for the playing track for the given channel
|
||||
|
||||
Syntax: `spotifyLink <channel>`
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
! ^!spotifylink
|
||||
> !spotifylink
|
||||
# {{ spotifyLink .channel }}
|
||||
* https://open.spotify.com/track/3HCzXf0lNpekSqsGBcGrCd
|
||||
```
|
||||
|
||||
### `streamUptime`
|
||||
|
||||
Returns the duration the stream is online (causes an error if no current stream is found)
|
||||
|
|
45
go.mod
45
go.mod
|
@ -4,14 +4,14 @@ go 1.21
|
|||
|
||||
require (
|
||||
github.com/Luzifer/go-openssl/v4 v4.2.2
|
||||
github.com/Luzifer/go_helpers/v2 v2.22.0
|
||||
github.com/Luzifer/go_helpers/v2 v2.23.0
|
||||
github.com/Luzifer/korvike/functions v0.11.0
|
||||
github.com/Luzifer/rconfig/v2 v2.5.0
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/getsentry/sentry-go v0.27.0
|
||||
github.com/glebarez/sqlite v1.10.0
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
github.com/go-git/go-git/v5 v5.11.0
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/go-sql-driver/mysql v1.8.1
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
github.com/gofrs/uuid/v3 v3.1.2
|
||||
github.com/gorilla/mux v1.8.1
|
||||
|
@ -22,20 +22,21 @@ require (
|
|||
github.com/pkg/errors v0.9.1
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/wzshiming/openapi v0.0.0-20200703171632-c7220b3c9cfb
|
||||
golang.org/x/crypto v0.19.0
|
||||
golang.org/x/net v0.21.0
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
golang.org/x/crypto v0.21.0
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/oauth2 v0.18.0
|
||||
gopkg.in/irc.v4 v4.0.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
gorm.io/driver/mysql v1.5.4
|
||||
gorm.io/driver/postgres v1.5.6
|
||||
gorm.io/gorm v1.25.7
|
||||
gorm.io/driver/mysql v1.5.6
|
||||
gorm.io/driver/postgres v1.5.7
|
||||
gorm.io/gorm v1.25.8
|
||||
)
|
||||
|
||||
require (
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
filippo.io/edwards25519 v1.1.0 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.1 // indirect
|
||||
|
@ -46,13 +47,12 @@ require (
|
|||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/emirpasic/gods v1.18.1 // indirect
|
||||
github.com/fatih/color v1.14.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
|
||||
github.com/go-git/go-billy/v5 v5.5.0 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.1 // indirect
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.3.1 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
|
@ -64,13 +64,13 @@ require (
|
|||
github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.6 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/vault/api v1.12.0 // indirect
|
||||
github.com/hashicorp/vault/api v1.12.2 // indirect
|
||||
github.com/huandu/xstrings v1.4.0 // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/itchyny/timefmt-go v0.1.5 // indirect
|
||||
github.com/jackc/pgpassfile v1.0.0 // indirect
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
|
||||
github.com/jackc/pgx/v5 v5.5.3 // indirect
|
||||
github.com/jackc/pgx/v5 v5.5.5 // indirect
|
||||
github.com/jackc/puddle/v2 v2.2.1 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
|
@ -89,21 +89,22 @@ require (
|
|||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/sergi/go-diff v1.3.1 // indirect
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/skeema/knownhosts v1.2.1 // indirect
|
||||
github.com/skeema/knownhosts v1.2.2 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/xanzy/ssh-agent v0.3.3 // indirect
|
||||
golang.org/x/mod v0.15.0 // indirect
|
||||
golang.org/x/mod v0.16.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
golang.org/x/tools v0.18.0 // indirect
|
||||
google.golang.org/appengine v1.4.0 // indirect
|
||||
golang.org/x/tools v0.19.0 // indirect
|
||||
google.golang.org/appengine v1.6.8 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/validator.v2 v2.0.1 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
modernc.org/libc v1.41.0 // indirect
|
||||
modernc.org/libc v1.49.0 // indirect
|
||||
modernc.org/mathutil v1.6.0 // indirect
|
||||
modernc.org/memory v1.7.2 // indirect
|
||||
modernc.org/sqlite v1.29.1 // indirect
|
||||
modernc.org/sqlite v1.29.5 // indirect
|
||||
)
|
||||
|
|
121
go.sum
121
go.sum
|
@ -1,11 +1,13 @@
|
|||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/Luzifer/go-openssl/v4 v4.2.2 h1:wKF/GhSKGJtHFQYTkN61wXig7mPvDj/oPpW6MmnBpjc=
|
||||
github.com/Luzifer/go-openssl/v4 v4.2.2/go.mod h1:+kAwI4NpyYXoWil85gKSCEJNoCQlMeFikEMn2f+5ffc=
|
||||
github.com/Luzifer/go_helpers/v2 v2.22.0 h1:rJrZkJDzAiq4J0RUbwPI7kQ5rUy7BYQ/GUpo3fSM0y0=
|
||||
github.com/Luzifer/go_helpers/v2 v2.22.0/go.mod h1:cIIqMPu3NT8/6kHke+03hVznNDLLKVGA74Lz47CWJyA=
|
||||
github.com/Luzifer/go_helpers/v2 v2.23.0 h1:VowDwOCl6nOt+GVqKUX/do6a94pEeqNTRHb29MsoGX4=
|
||||
github.com/Luzifer/go_helpers/v2 v2.23.0/go.mod h1:BSGkJ/dxqs7AxsfZt8zjJb4R6YB5dONS+/ad7foLUrk=
|
||||
github.com/Luzifer/korvike/functions v0.11.0 h1:2hr3nnt9hy8Esu1W3h50+RggcLRXvrw92kVQLvxzd2Q=
|
||||
github.com/Luzifer/korvike/functions v0.11.0/go.mod h1:osumwH64mWgbwZIfE7rE0BB7Y5HXxrzyO4JfO7fhduU=
|
||||
github.com/Luzifer/rconfig/v2 v2.5.0 h1:zx5lfQbNX3za4VegID97IeY+M+BmfgHxWJTYA94sxok=
|
||||
|
@ -49,8 +51,8 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc
|
|||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w=
|
||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
|
@ -58,8 +60,8 @@ github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK
|
|||
github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY=
|
||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
|
||||
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
|
||||
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
|
@ -72,12 +74,12 @@ github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMj
|
|||
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
|
||||
github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
|
||||
github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
|
||||
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
|
||||
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k=
|
||||
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
|
||||
github.com/go-ldap/ldap v3.0.2+incompatible/go.mod h1:qfd9rJvER9Q0/D/Sqn1DfHRoBp40uXYvFoEVrNEPqRc=
|
||||
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||
github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw=
|
||||
github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
|
@ -90,11 +92,15 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l
|
|||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
|
@ -144,8 +150,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
|
|||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/vault/api v1.0.4/go.mod h1:gDcqh3WGcR1cpF5AJz/B1UFheUEneMoIospckxBxk6Q=
|
||||
github.com/hashicorp/vault/api v1.12.0 h1:meCpJSesvzQyao8FCOgk2fGdoADAnbDu2WPJN1lDLJ4=
|
||||
github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck=
|
||||
github.com/hashicorp/vault/api v1.12.2 h1:7YkCTE5Ni90TcmYHDBExdt4WGJxhpzaHqR6uGbQb/rE=
|
||||
github.com/hashicorp/vault/api v1.12.2/go.mod h1:LSGf1NGT1BnvFFnKVtnvcaLBM2Lz+gJdpL6HUYed8KE=
|
||||
github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
|
@ -163,8 +169,8 @@ github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsI
|
|||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
|
||||
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
|
||||
github.com/jackc/pgx/v5 v5.5.3 h1:Ces6/M3wbDXYpM8JyyPD57ivTtJACFZJd885pdIaV2s=
|
||||
github.com/jackc/pgx/v5 v5.5.3/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
|
||||
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
|
||||
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
|
||||
github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
|
@ -248,8 +254,8 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV
|
|||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
|
||||
github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
|
||||
github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A=
|
||||
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
|
@ -261,35 +267,34 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
|
|||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/wzshiming/openapi v0.0.0-20200703171632-c7220b3c9cfb h1:G0Rrif8QdbAz7Xy53H4Xumy6TuyKHom8pu8z/jdLwwM=
|
||||
github.com/wzshiming/openapi v0.0.0-20200703171632-c7220b3c9cfb/go.mod h1:398xiAftMV/w8frjipnUzjr/WQ+E2fnGRv9yXobxyyk=
|
||||
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
|
||||
golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic=
|
||||
golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
|
@ -302,10 +307,12 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug
|
|||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -320,7 +327,6 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||
golang.org/x/sys v0.0.0-20190129075346-302c3dd5f1cc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
@ -338,23 +344,29 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|||
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
|
||||
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20181227161524-e6919f6577db/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
|
@ -369,18 +381,23 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
|
|||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ=
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw=
|
||||
golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
|
||||
google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190404172233-64821d5d2107/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.22.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
@ -400,20 +417,36 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
|||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/mysql v1.5.4 h1:igQmHfKcbaTVyAIHNhhB888vvxh8EdQ2uSUT0LPcBso=
|
||||
gorm.io/driver/mysql v1.5.4/go.mod h1:9rYxJph/u9SWkWc9yY4XJ1F/+xO0S/ChOmbk3+Z5Tvs=
|
||||
gorm.io/driver/postgres v1.5.6 h1:ydr9xEd5YAM0vxVDY0X139dyzNz10spDiDlC7+ibLeU=
|
||||
gorm.io/driver/postgres v1.5.6/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A=
|
||||
gorm.io/driver/mysql v1.5.6 h1:Ld4mkIickM+EliaQZQx3uOJDJHtrd70MxAUqWqlx3Y8=
|
||||
gorm.io/driver/mysql v1.5.6/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
|
||||
gorm.io/driver/postgres v1.5.7 h1:8ptbNJTDbEmhdr62uReG5BGkdQyeasu/FZHxI0IMGnM=
|
||||
gorm.io/driver/postgres v1.5.7/go.mod h1:3e019WlBaYI5o5LIdNV+LyxCMNtLOQETBXL2h4chKpA=
|
||||
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo=
|
||||
gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk=
|
||||
modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY=
|
||||
modernc.org/cc/v4 v4.19.5 h1:QlsZyQ1zf78DGeqnQ9ILi9hXyMdoC5e1qoGNUyBjHQw=
|
||||
modernc.org/cc/v4 v4.19.5/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
||||
modernc.org/ccgo/v4 v4.13.1 h1:qBttaSxEHNze36VBivw1/vkHuyjMDN3RY5wQX+p1Oxg=
|
||||
modernc.org/ccgo/v4 v4.13.1/go.mod h1:Td6RI9W9G2ZpKHaJ7UeGEiB2aIpoDqLBnm4wtkbJTbQ=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/libc v1.49.0 h1:/kkNBuCXvlTbOGwrQdgR67eK1Y9+kR+fhdBd89C64VM=
|
||||
modernc.org/libc v1.49.0/go.mod h1:DNz0lgQgT6FPIPm8rHtjFj0FL5/YOr/NYFXWYBcSxMw=
|
||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
||||
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
|
||||
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
|
||||
modernc.org/sqlite v1.29.1 h1:19GY2qvWB4VPw0HppFlZCPAbmxFU41r+qjKZQdQ1ryA=
|
||||
modernc.org/sqlite v1.29.1/go.mod h1:hG41jCYxOAOoO6BRK66AdRlmOcDzXf7qnwlwjUIOqa0=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.29.5 h1:8l/SQKAjDtZFo9lkJLdk8g9JEOeYRG4/ghStDCCTiTE=
|
||||
modernc.org/sqlite v1.29.5/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U=
|
||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
|
|
|
@ -34,7 +34,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("counter", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, &counter{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, &counter{})
|
||||
})
|
||||
|
||||
formatMessage = args.FormatMessage
|
||||
|
|
|
@ -40,7 +40,7 @@ func Register(args plugins.RegistrationArguments) error {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("punish", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, &punishLevel{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, &punishLevel{})
|
||||
})
|
||||
|
||||
botTwitchClient = args.GetTwitchClient()
|
||||
|
|
|
@ -94,7 +94,7 @@ func getPunishment(db database.Connector, channel, user, uuid string) (*levelCon
|
|||
err := helpers.Retry(func() error {
|
||||
err := db.DB().First(&p, "key = ?", getDBKey(channel, user, uuid)).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return backoff.NewErrCannotRetry(err) //nolint:wrapcheck // we get our internal error
|
||||
return backoff.NewErrCannotRetry(err)
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
|
|
@ -36,7 +36,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("quote", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, "e{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, "e{})
|
||||
})
|
||||
|
||||
formatMessage = args.FormatMessage
|
||||
|
|
|
@ -11,17 +11,17 @@ import (
|
|||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
func getCurrentTrackForChannel(channel string) (track string, err error) {
|
||||
func getCurrentTrackForChannel(channel string) (track currentPlayingTrackResponse, err error) {
|
||||
channel = strings.TrimLeft(channel, "#")
|
||||
|
||||
conf, err := oauthConfig(channel, "")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting oauth config: %w", err)
|
||||
return track, fmt.Errorf("getting oauth config: %w", err)
|
||||
}
|
||||
|
||||
var token *oauth2.Token
|
||||
if err = db.ReadEncryptedCoreMeta(strings.Join([]string{"spotify-auth", channel}, ":"), &token); err != nil {
|
||||
return "", fmt.Errorf("loading oauth token: %w", err)
|
||||
return track, fmt.Errorf("loading oauth token: %w", err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), spotifyRequestTimeout)
|
||||
|
@ -29,12 +29,12 @@ func getCurrentTrackForChannel(channel string) (track string, err error) {
|
|||
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.spotify.com/v1/me/player/currently-playing", nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("creating currently-playing request: %w", err)
|
||||
return track, fmt.Errorf("creating currently-playing request: %w", err)
|
||||
}
|
||||
|
||||
resp, err := conf.Client(context.Background(), token).Do(req)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("executing request: %w", err)
|
||||
return track, fmt.Errorf("executing request: %w", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := resp.Body.Close(); err != nil {
|
||||
|
@ -48,18 +48,35 @@ func getCurrentTrackForChannel(channel string) (track string, err error) {
|
|||
}
|
||||
}()
|
||||
|
||||
var payload currentPlayingTrackResponse
|
||||
if err = json.NewDecoder(resp.Body).Decode(&payload); err != nil {
|
||||
return "", fmt.Errorf("decoding response: %w", err)
|
||||
if err = json.NewDecoder(resp.Body).Decode(&track); err != nil {
|
||||
return track, fmt.Errorf("decoding response: %w", err)
|
||||
}
|
||||
|
||||
return track, nil
|
||||
}
|
||||
|
||||
func getCurrentArtistTitleForChannel(channel string) (artistTitle string, err error) {
|
||||
track, err := getCurrentTrackForChannel(channel)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting track info: %w", err)
|
||||
}
|
||||
|
||||
var artistNames []string
|
||||
for _, artist := range payload.Item.Artists {
|
||||
for _, artist := range track.Item.Artists {
|
||||
artistNames = append(artistNames, artist.Name)
|
||||
}
|
||||
|
||||
return strings.Join([]string{
|
||||
strings.Join(artistNames, ", "),
|
||||
payload.Item.Name,
|
||||
track.Item.Name,
|
||||
}, " - "), nil
|
||||
}
|
||||
|
||||
func getCurrentLinkForChannel(channel string) (link string, err error) {
|
||||
track, err := getCurrentTrackForChannel(channel)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("getting track info: %w", err)
|
||||
}
|
||||
|
||||
return track.Item.ExternalUrls.Spotify, nil
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
|
||||
args.RegisterTemplateFunction(
|
||||
"spotifyCurrentPlaying",
|
||||
plugins.GenericTemplateFunctionGetter(getCurrentTrackForChannel),
|
||||
plugins.GenericTemplateFunctionGetter(getCurrentArtistTitleForChannel),
|
||||
plugins.TemplateFuncDocumentation{
|
||||
Name: "spotifyCurrentPlaying",
|
||||
Description: "Retrieves the current playing track for the given channel",
|
||||
|
@ -43,7 +43,24 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
Template: "{{ spotifyCurrentPlaying .channel }}",
|
||||
FakedOutput: "Beast in Black - Die By The Blade",
|
||||
},
|
||||
})
|
||||
},
|
||||
)
|
||||
|
||||
args.RegisterTemplateFunction(
|
||||
"spotifyLink",
|
||||
plugins.GenericTemplateFunctionGetter(getCurrentLinkForChannel),
|
||||
plugins.TemplateFuncDocumentation{
|
||||
Name: "spotifyLink",
|
||||
Description: "Retrieves the link for the playing track for the given channel",
|
||||
Syntax: "spotifyLink <channel>",
|
||||
Example: &plugins.TemplateFuncDocumentationExample{
|
||||
MatchMessage: "^!spotifylink",
|
||||
MessageContent: "!spotifylink",
|
||||
Template: "{{ spotifyLink .channel }}",
|
||||
FakedOutput: "https://open.spotify.com/track/3HCzXf0lNpekSqsGBcGrCd",
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if err = args.RegisterAPIRoute(plugins.HTTPRouteRegistrationArgs{
|
||||
Description: "Starts authorization of an Spotify Account for a {channel}",
|
||||
|
|
|
@ -33,7 +33,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("variable", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, &variable{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, &variable{})
|
||||
})
|
||||
|
||||
formatMessage = args.FormatMessage
|
||||
|
|
|
@ -22,7 +22,7 @@ func getVariable(db database.Connector, key string) (string, error) {
|
|||
err := helpers.Retry(func() error {
|
||||
err := db.DB().First(&v, "name = ?", key).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return backoff.NewErrCannotRetry(err) //nolint:wrapcheck // we get our internal error
|
||||
return backoff.NewErrCannotRetry(err)
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
|
|
@ -37,7 +37,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("custom_event", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, &storedCustomEvent{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, &storedCustomEvent{})
|
||||
})
|
||||
|
||||
mc = &memoryCache{dbc: db}
|
||||
|
|
|
@ -75,7 +75,7 @@ func getEventByID(db database.Connector, eventID uint64) (socketMessage, error)
|
|||
if err := helpers.Retry(func() (err error) {
|
||||
err = db.DB().Where("id = ?", eventID).First(&evt).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return backoff.NewErrCannotRetry(err) //nolint:wrapcheck // we get our internal error
|
||||
return backoff.NewErrCannotRetry(err)
|
||||
}
|
||||
return err
|
||||
}); err != nil {
|
||||
|
|
|
@ -92,7 +92,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("overlay_events", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, &overlaysEvent{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, &overlaysEvent{})
|
||||
})
|
||||
|
||||
validateToken = args.ValidateToken
|
||||
|
@ -405,8 +405,17 @@ func handleSocketSubscription(w http.ResponseWriter, r *http.Request) {
|
|||
case err == nil:
|
||||
// We use nil-error to close the connection
|
||||
|
||||
case errors.As(err, &cErr) && websocket.IsCloseError(cErr, websocket.CloseNormalClosure, websocket.CloseGoingAway):
|
||||
// We don't need to log when the remote closes the websocket gracefully
|
||||
case errors.As(err, &cErr):
|
||||
switch cErr.Code {
|
||||
case websocket.CloseAbnormalClosure:
|
||||
logger.WithError(err).Warn("overlay websocket was closed abnormally")
|
||||
|
||||
case websocket.CloseNormalClosure, websocket.CloseGoingAway:
|
||||
// We don't need to log when the remote closes the websocket gracefully
|
||||
|
||||
default:
|
||||
logger.WithError(err).Error("message processing caused error")
|
||||
}
|
||||
|
||||
default:
|
||||
logger.WithError(err).Error("message processing caused error")
|
||||
|
|
|
@ -29,7 +29,7 @@ func Register(args plugins.RegistrationArguments) (err error) {
|
|||
}
|
||||
|
||||
args.RegisterCopyDatabaseFunc("raffle", func(src, target *gorm.DB) error {
|
||||
return database.CopyObjects(src, target, &raffle{}, &raffleEntry{}) //nolint:wrapcheck // internal helper
|
||||
return database.CopyObjects(src, target, &raffle{}, &raffleEntry{})
|
||||
})
|
||||
|
||||
dbc = newDBClient(db)
|
||||
|
|
|
@ -23,6 +23,6 @@ func Retry(fn func() error) error {
|
|||
// database and will be retried as if executed using Retry
|
||||
func RetryTransaction(db *gorm.DB, fn func(tx *gorm.DB) error) error {
|
||||
return Retry(func() error {
|
||||
return db.Transaction(fn) //nolint:wrapcheck
|
||||
return db.Transaction(fn)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -172,7 +172,7 @@ func (s Service) GetTwitchClientForChannel(channel string, cfg ClientConfig) (*t
|
|||
if err = helpers.Retry(func() error {
|
||||
err = s.db.DB().First(&perm, "channel = ?", strings.TrimLeft(channel, "#")).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return backoff.NewErrCannotRetry(ErrChannelNotAuthorized) //nolint:wrapcheck // We get our own error
|
||||
return backoff.NewErrCannotRetry(ErrChannelNotAuthorized)
|
||||
}
|
||||
return errors.Wrap(err, "getting twitch credential from database")
|
||||
}); err != nil {
|
||||
|
@ -251,7 +251,7 @@ func (s Service) HasTokensForChannel(channel string) (bool, error) {
|
|||
if err = helpers.Retry(func() error {
|
||||
err = s.db.DB().First(&perm, "channel = ?", strings.TrimLeft(channel, "#")).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return backoff.NewErrCannotRetry(ErrChannelNotAuthorized) //nolint:wrapcheck // We'll get our own error
|
||||
return backoff.NewErrCannotRetry(ErrChannelNotAuthorized)
|
||||
}
|
||||
return errors.Wrap(err, "getting twitch credential from database")
|
||||
}); err != nil {
|
||||
|
|
|
@ -103,7 +103,7 @@ func (s Service) HasTimer(id string) (bool, error) {
|
|||
err := helpers.Retry(func() error {
|
||||
err := s.db.DB().First(&t, "id = ? AND expires_at >= ?", id, time.Now().UTC()).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return backoff.NewErrCannotRetry(err) //nolint:wrapcheck // We'll get our own error
|
||||
return backoff.NewErrCannotRetry(err)
|
||||
}
|
||||
return err
|
||||
})
|
||||
|
|
31
internal/template/date/date.go
Normal file
31
internal/template/date/date.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Package date adds date-based helper functions for templating
|
||||
package date
|
||||
|
||||
import (
|
||||
"github.com/Luzifer/twitch-bot/v3/plugins"
|
||||
)
|
||||
|
||||
// Register provides the plugins.RegisterFunc
|
||||
func Register(args plugins.RegistrationArguments) error {
|
||||
args.RegisterTemplateFunction("humanDateDiff", plugins.GenericTemplateFunctionGetter(NewInterval), plugins.TemplateFuncDocumentation{
|
||||
Description: `Returns a DateInterval object describing the time difference between a and b in a "human" way of counting the time (2023-02-05 -> 2024-03-05 = 1 Year, 1 Month)`,
|
||||
Syntax: "humanDateDiff <a> <b>",
|
||||
Example: &plugins.TemplateFuncDocumentationExample{
|
||||
Template: `{{ humanDateDiff (mustToDate "2006-01-02 -0700" "2024-05-05 +0200") (mustToDate "2006-01-02 -0700" "2023-01-09 +0100") }}`,
|
||||
ExpectedOutput: "{1 3 25 23 0 0}",
|
||||
},
|
||||
})
|
||||
|
||||
args.RegisterTemplateFunction("formatHumanDateDiff", plugins.GenericTemplateFunctionGetter(func(format string, d Interval) string {
|
||||
return d.Format(format)
|
||||
}), plugins.TemplateFuncDocumentation{
|
||||
Description: "Formats a DateInterval object according to the format (%Y, %M, %D, %H, %I, %S for years, months, days, hours, minutes, seconds - Lowercase letters without leading zeros)",
|
||||
Syntax: "formatHumanDateDiff <format> <obj>",
|
||||
Example: &plugins.TemplateFuncDocumentationExample{
|
||||
Template: `{{ humanDateDiff (mustToDate "2006-01-02 -0700" "2024-05-05 +0200") (mustToDate "2006-01-02 -0700" "2023-01-09 +0100") | formatHumanDateDiff "%Y years, %M months, %D days" }}`,
|
||||
ExpectedOutput: "01 years, 03 months, 25 days",
|
||||
},
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
94
internal/template/date/interval.go
Normal file
94
internal/template/date/interval.go
Normal file
|
@ -0,0 +1,94 @@
|
|||
package date
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type (
|
||||
// Interval represents a human-minded diff of two dates which is in
|
||||
// no way interchangeable with a time.Duration: The DateInterval
|
||||
// takes each date component and subtracts them. This causes the
|
||||
// 03/25 to be exactly one month distant from 02/25 even though the
|
||||
// distance would be different than with 03/25 and 04/25 which is
|
||||
// also exactly one month.
|
||||
Interval struct {
|
||||
Years int
|
||||
Months int
|
||||
Days int
|
||||
Hours int
|
||||
Minutes int
|
||||
Seconds int
|
||||
}
|
||||
)
|
||||
|
||||
// NewInterval creates an Interval from two given dates
|
||||
func NewInterval(a, b time.Time) (i Interval) {
|
||||
var l, u time.Time
|
||||
if a.Before(b) {
|
||||
l, u = a.UTC(), b.UTC()
|
||||
} else {
|
||||
l, u = b.UTC(), a.UTC()
|
||||
}
|
||||
|
||||
i.Years = u.Year() - l.Year()
|
||||
i.Months = int(u.Month() - l.Month())
|
||||
i.Days = u.Day() - l.Day()
|
||||
i.Hours = u.Hour() - l.Hour()
|
||||
i.Minutes = u.Minute() - l.Minute()
|
||||
i.Seconds = u.Second() - l.Second()
|
||||
|
||||
if i.Seconds < 0 {
|
||||
i.Minutes, i.Seconds = i.Minutes-1, i.Seconds+60 //nolint:gomnd
|
||||
}
|
||||
|
||||
if i.Minutes < 0 {
|
||||
i.Hours, i.Minutes = i.Hours-1, i.Minutes+60 //nolint:gomnd
|
||||
}
|
||||
|
||||
if i.Hours < 0 {
|
||||
i.Days, i.Hours = i.Days-1, i.Hours+24 //nolint:gomnd
|
||||
}
|
||||
|
||||
if i.Days < 0 {
|
||||
// oh boi.
|
||||
i.Months, i.Days = i.Months-1, daysInMonth(u.Year(), int(u.Month())-1)+i.Days
|
||||
}
|
||||
|
||||
if i.Months < 0 {
|
||||
i.Years, i.Months = i.Years-1, i.Months+12 //nolint:gomnd
|
||||
}
|
||||
|
||||
return i
|
||||
}
|
||||
|
||||
func daysInMonth(year, month int) int {
|
||||
return time.Date(year, time.Month(month+1), 1, 0, 0, 0, 0, time.Local).Add(-time.Second).Day()
|
||||
}
|
||||
|
||||
// Format takes a template string analog to a strftime string and formats
|
||||
// the Interval accordingly:
|
||||
//
|
||||
// %Y / %y = Years with / without leading digit to 2 places
|
||||
// %M / %m = Months with / without leading digit to 2 places
|
||||
// %D / %d = Days with / without leading digit to 2 places
|
||||
// %H / %h = Hours with / without leading digit to 2 places
|
||||
// %I / %i = Minutes with / without leading digit to 2 places
|
||||
// %S / %s = Seconds with / without leading digit to 2 places
|
||||
func (i Interval) Format(tplString string) string {
|
||||
return strings.NewReplacer(
|
||||
"%Y", fmt.Sprintf("%02d", i.Years),
|
||||
"%y", fmt.Sprintf("%d", i.Years),
|
||||
"%M", fmt.Sprintf("%02d", i.Months),
|
||||
"%m", fmt.Sprintf("%d", i.Months),
|
||||
"%D", fmt.Sprintf("%02d", i.Days),
|
||||
"%d", fmt.Sprintf("%d", i.Days),
|
||||
"%H", fmt.Sprintf("%02d", i.Hours),
|
||||
"%h", fmt.Sprintf("%d", i.Hours),
|
||||
"%I", fmt.Sprintf("%02d", i.Minutes),
|
||||
"%i", fmt.Sprintf("%d", i.Minutes),
|
||||
"%S", fmt.Sprintf("%02d", i.Seconds),
|
||||
"%s", fmt.Sprintf("%d", i.Seconds),
|
||||
).Replace(tplString)
|
||||
}
|
134
internal/template/date/interval_test.go
Normal file
134
internal/template/date/interval_test.go
Normal file
|
@ -0,0 +1,134 @@
|
|||
package date
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
//go:embed tzdata
|
||||
var tzDataEuropeBerlin []byte
|
||||
|
||||
//nolint:funlen // This is just a collection of test cases
|
||||
func TestNewInterval(t *testing.T) {
|
||||
tz, err := time.LoadLocationFromTZData("Europe/Berlin", tzDataEuropeBerlin)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i, tc := range []struct {
|
||||
A, B time.Time
|
||||
Exp Interval
|
||||
}{
|
||||
{
|
||||
// Plain and simple: 1 Month
|
||||
A: time.Date(2024, 3, 3, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 2, 3, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 1, 0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// Plain and simple: 1 Month, reversed
|
||||
A: time.Date(2024, 2, 3, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 3, 3, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 1, 0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// Plain and simple: 1 Year, 1 Month
|
||||
A: time.Date(2023, 2, 3, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 3, 3, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{1, 1, 0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// 11 Months, so Year and Month needs to be adjusted
|
||||
A: time.Date(2023, 3, 3, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 2, 3, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 11, 0, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// Plain and simple: 2 Days
|
||||
A: time.Date(2024, 3, 3, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 3, 5, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 0, 2, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// 1 Month and a few days, so Month and Day needs to be adjusted
|
||||
A: time.Date(2024, 3, 25, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 5, 5, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 1, 9, 23, 0, 0},
|
||||
},
|
||||
{
|
||||
// 1 Month and a few days, so Month and Day needs to be adjusted
|
||||
A: time.Date(2024, 2, 25, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 4, 5, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 1, 10, 23, 0, 0},
|
||||
},
|
||||
{
|
||||
// 1 Month and a few days, so Month and Day needs to be adjusted
|
||||
A: time.Date(2024, 1, 25, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 3, 5, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 1, 9, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// 1 Month and a few days, so Month and Day needs to be adjusted
|
||||
A: time.Date(2023, 1, 25, 0, 0, 0, 0, tz),
|
||||
B: time.Date(2023, 3, 5, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 1, 8, 0, 0, 0},
|
||||
},
|
||||
{
|
||||
// 1 Day and a few hours, so Day and Hours needs to be adjusted
|
||||
A: time.Date(2024, 3, 5, 14, 0, 0, 0, tz),
|
||||
B: time.Date(2024, 3, 7, 0, 0, 0, 0, tz),
|
||||
Exp: Interval{0, 0, 1, 10, 0, 0},
|
||||
},
|
||||
{
|
||||
// 1 Hour and a few minutes, so Hours and Minutes needs to be adjusted
|
||||
A: time.Date(2024, 3, 5, 14, 25, 0, 0, tz),
|
||||
B: time.Date(2024, 3, 5, 16, 12, 0, 0, tz),
|
||||
Exp: Interval{0, 0, 0, 1, 47, 0},
|
||||
},
|
||||
{
|
||||
// 1 Minute and a few seconds, so Minutes and Seconds needs to be adjusted
|
||||
A: time.Date(2024, 3, 5, 14, 25, 13, 0, tz),
|
||||
B: time.Date(2024, 3, 5, 14, 27, 0, 0, tz),
|
||||
Exp: Interval{0, 0, 0, 0, 1, 47},
|
||||
},
|
||||
{
|
||||
// Nearly one year but a few seconds, everything needs to be adjusted
|
||||
A: time.Date(2024, 3, 5, 14, 25, 0, 0, tz),
|
||||
B: time.Date(2023, 3, 5, 14, 25, 13, 0, tz),
|
||||
Exp: Interval{0, 11, 28, 23, 59, 47},
|
||||
},
|
||||
{
|
||||
// Nearly one year but a few seconds, everything needs to be adjusted
|
||||
A: time.Date(2024, 8, 5, 14, 25, 0, 0, tz),
|
||||
B: time.Date(2023, 8, 5, 14, 25, 13, 0, tz),
|
||||
Exp: Interval{0, 11, 30, 23, 59, 47},
|
||||
},
|
||||
{
|
||||
// Nearly one year but a few seconds, everything needs to be adjusted
|
||||
A: time.Date(2024, 7, 5, 14, 25, 0, 0, tz),
|
||||
B: time.Date(2023, 7, 5, 14, 25, 13, 0, tz),
|
||||
Exp: Interval{0, 11, 29, 23, 59, 47},
|
||||
},
|
||||
{
|
||||
// Nearly one year but a few seconds, everything needs to be adjusted
|
||||
A: time.Date(2024, 2, 5, 14, 25, 0, 0, tz),
|
||||
B: time.Date(2023, 2, 5, 14, 25, 13, 0, tz),
|
||||
Exp: Interval{0, 11, 30, 23, 59, 47},
|
||||
},
|
||||
} {
|
||||
assert.Equal(t,
|
||||
tc.Exp,
|
||||
NewInterval(tc.A, tc.B),
|
||||
fmt.Sprintf("%d: %s -> %s", i, tc.A, tc.B))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatInterval(t *testing.T) {
|
||||
ti := Interval{1, 2, 3, 4, 5, 6}
|
||||
assert.Equal(t,
|
||||
"01 1 years 02 2 months 03 3 days 04 4 hours 05 5 minutes 06 6 seconds",
|
||||
ti.Format("%Y %y years %M %m months %D %d days %H %h hours %I %i minutes %S %s seconds"))
|
||||
}
|
BIN
internal/template/date/tzdata
Normal file
BIN
internal/template/date/tzdata
Normal file
Binary file not shown.
|
@ -6,10 +6,12 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/hashstructure/v2"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Collection of known EventSub event-types
|
||||
|
@ -60,7 +62,7 @@ type (
|
|||
// EventSubEventAdBreakBegin contains the payload for an AdBreak event
|
||||
EventSubEventAdBreakBegin struct {
|
||||
Duration int64 `json:"duration_seconds"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
StartedAt time.Time `json:"started_at"`
|
||||
IsAutomatic bool `json:"is_automatic"`
|
||||
BroadcasterUserID string `json:"broadcaster_user_id"`
|
||||
BroadcasterUserLogin string `json:"broadcaster_user_login"`
|
||||
|
@ -277,8 +279,10 @@ func (c *Client) createEventSubSubscriptionWebsocket(ctx context.Context, sub ev
|
|||
|
||||
func (c *Client) createEventSubSubscription(ctx context.Context, auth AuthType, sub eventSubSubscription) (*eventSubSubscription, error) {
|
||||
var (
|
||||
buf = new(bytes.Buffer)
|
||||
resp struct {
|
||||
buf = new(bytes.Buffer)
|
||||
err error
|
||||
mustFetchSubsctiption bool
|
||||
resp struct {
|
||||
Total int64 `json:"total"`
|
||||
Data []eventSubSubscription `json:"data"`
|
||||
Pagination struct {
|
||||
|
@ -287,20 +291,73 @@ func (c *Client) createEventSubSubscription(ctx context.Context, auth AuthType,
|
|||
}
|
||||
)
|
||||
|
||||
if err := json.NewEncoder(buf).Encode(sub); err != nil {
|
||||
conHash, err := sub.Condition.Hash()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("hashing input condition: %w", err)
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(buf).Encode(sub); err != nil {
|
||||
return nil, errors.Wrap(err, "assemble subscribe payload")
|
||||
}
|
||||
|
||||
if err := c.Request(ctx, ClientRequestOpts{
|
||||
if err = c.Request(ctx, ClientRequestOpts{
|
||||
AuthType: auth,
|
||||
Body: buf,
|
||||
Method: http.MethodPost,
|
||||
OKStatus: http.StatusAccepted,
|
||||
Out: &resp,
|
||||
URL: "https://api.twitch.tv/helix/eventsub/subscriptions",
|
||||
ValidateFunc: func(opts ClientRequestOpts, resp *http.Response) error {
|
||||
if resp.StatusCode == http.StatusConflict {
|
||||
// This is fine: We needed that subscription, it exists
|
||||
mustFetchSubsctiption = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Fallback to default handling
|
||||
return ValidateStatus(opts, resp)
|
||||
},
|
||||
}); err != nil {
|
||||
return nil, errors.Wrap(err, "executing request")
|
||||
return nil, fmt.Errorf("creating subscription: %w", err)
|
||||
}
|
||||
|
||||
return &resp.Data[0], nil
|
||||
if mustFetchSubsctiption {
|
||||
params := make(url.Values)
|
||||
params.Set("status", "enabled")
|
||||
params.Set("type", sub.Type)
|
||||
|
||||
if err = c.Request(ctx, ClientRequestOpts{
|
||||
AuthType: auth,
|
||||
Method: http.MethodGet,
|
||||
OKStatus: http.StatusOK,
|
||||
Out: &resp,
|
||||
URL: fmt.Sprintf("https://api.twitch.tv/helix/eventsub/subscriptions?%s", params.Encode()),
|
||||
}); err != nil {
|
||||
return nil, fmt.Errorf("fetching subscription: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
for i := range resp.Data {
|
||||
s := resp.Data[i]
|
||||
|
||||
if s.Type != sub.Type || s.Version != sub.Version {
|
||||
// Not the subscription we're searching for
|
||||
continue
|
||||
}
|
||||
|
||||
sConHash, err := s.Condition.Hash()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Error("hashing eventsub subscription condition")
|
||||
continue
|
||||
}
|
||||
|
||||
if sConHash != conHash {
|
||||
// Different conditions
|
||||
continue
|
||||
}
|
||||
|
||||
return &s, nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no subscription matching input found")
|
||||
}
|
||||
|
|
|
@ -385,6 +385,10 @@ func (e *EventSubSocketClient) handleSocketError(err error, msgC chan eventSubSo
|
|||
e.logger.Debug("websocket was closed normally")
|
||||
return nil
|
||||
|
||||
case websocket.CloseAbnormalClosure:
|
||||
e.logger.Warn("websocket reported abnormal closure")
|
||||
return errors.Wrap(e.connect(e.socketDest, msgC, errC, "network-error"), "re-connecting after abnormal closure")
|
||||
|
||||
default:
|
||||
// Some non-twitch close code we did not expect
|
||||
e.logger.WithError(closeErr).Error("websocket reported unexpected error code")
|
||||
|
@ -441,7 +445,7 @@ func (e *EventSubSocketClient) retryBackgroundSubscribe(st eventSubSocketSubscri
|
|||
if err := e.runCtx.Err(); err != nil {
|
||||
// Our run-context was cancelled, stop retrying to subscribe
|
||||
// to topics as this client was closed
|
||||
return backoff.NewErrCannotRetry(err) //nolint:wrapcheck // We get our internal error
|
||||
return backoff.NewErrCannotRetry(err)
|
||||
}
|
||||
|
||||
return e.subscribe(st)
|
||||
|
|
|
@ -46,6 +46,7 @@ import (
|
|||
"github.com/Luzifer/twitch-bot/v3/internal/apimodules/raffle"
|
||||
"github.com/Luzifer/twitch-bot/v3/internal/service/access"
|
||||
"github.com/Luzifer/twitch-bot/v3/internal/template/api"
|
||||
"github.com/Luzifer/twitch-bot/v3/internal/template/date"
|
||||
"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/slice"
|
||||
|
@ -93,6 +94,7 @@ var (
|
|||
|
||||
// Template functions
|
||||
api.Register,
|
||||
date.Register,
|
||||
numeric.Register,
|
||||
random.Register,
|
||||
slice.Register,
|
||||
|
@ -189,7 +191,6 @@ func getRegistrationArguments() plugins.RegistrationArguments {
|
|||
},
|
||||
|
||||
GetTwitchClientForChannel: func(channel string) (*twitch.Client, error) {
|
||||
//nolint:wrapcheck // own package, no need to wrap
|
||||
return accessService.GetTwitchClientForChannel(channel, access.ClientConfig{
|
||||
TwitchClient: cfg.TwitchClient,
|
||||
TwitchClientSecret: cfg.TwitchClientSecret,
|
||||
|
|
|
@ -80,6 +80,7 @@ func handleStatusRequest(w http.ResponseWriter, r *http.Request) {
|
|||
{
|
||||
Name: "Twitch Client Authorized",
|
||||
Description: "Twitch Client is authorized and can fetch authorized user",
|
||||
//nolint:contextcheck // Check is too stupid to see the context IS passed
|
||||
checkFn: func() error {
|
||||
if twitchClient == nil {
|
||||
return errors.New("not initialized")
|
||||
|
|
|
@ -245,7 +245,7 @@ func (*twitchWatcher) handleEventSubChannelAdBreakBegin(m json.RawMessage) error
|
|||
"channel": "#" + payload.BroadcasterUserLogin,
|
||||
"duration": payload.Duration,
|
||||
"is_automatic": payload.IsAutomatic,
|
||||
"timestamp": payload.Timestamp,
|
||||
"started_at": payload.StartedAt,
|
||||
})
|
||||
|
||||
log.WithFields(log.Fields(fields.Data())).Info("Ad-Break started")
|
||||
|
|
Loading…
Reference in a new issue