Compare commits

...

19 Commits
v1.0.3 ... main

Author SHA1 Message Date
efiordeliso 18e708215c Merge pull request 'Actual Release v1.2.1' (#2) from dev into main
Reviewed-on: #2
2024-03-08 13:46:29 -05:00
efiordeliso 9ab3748026 Merge pull request 'Release v1.2.1' (#1) from dev into main
Reviewed-on: #1
2024-03-08 13:45:28 -05:00
Evan Fiordeliso 7eaf43a29a chore(release): release v1.2.1 2024-03-08 13:44:51 -05:00
Evan Fiordeliso 11633a86ce fix(devenv): Fix version variable in release script 2024-03-08 13:44:49 -05:00
Evan Fiordeliso 3fd6ca3495 chore(release): release 2024-03-08 13:40:25 -05:00
Evan Fiordeliso 08f0281e98 fix(devenv): Fix release changelog generation and commit message 2024-03-08 13:40:10 -05:00
Evan Fiordeliso 7fa9815a37 chore(devenv): Add release script and rename changelog script to gen-changelog 2024-03-08 13:24:43 -05:00
Evan Fiordeliso 9c4e63c200 refactor: Change api client to pass http client to auth client 2024-03-08 13:12:13 -05:00
Evan Fiordeliso 02d09446ce refactor: Move GetToken method into auth client and rename auth client from Client to Auth 2024-03-08 13:08:54 -05:00
Evan Fiordeliso adf49ce4bb feat: Add context to GetToken endpoint 2024-03-08 13:05:54 -05:00
Evan Fiordeliso 01bc01979e chore: Add git cliff for auto generated changelog 2024-03-08 01:28:33 -05:00
Evan Fiordeliso fce339d8c5 fix: Create endpoint make utility to build endpoints 2024-03-07 20:52:42 -05:00
Evan Fiordeliso 858c3c5adc Add log messages to GetUsers endpoint 2024-03-07 19:44:38 -05:00
Evan Fiordeliso b11a712ecc Add http status handling to all endpoint requests 2024-03-07 19:41:05 -05:00
Evan Fiordeliso fc50a199ef Add custom transport to api client 2024-03-07 19:06:02 -05:00
Evan Fiordeliso f33aef6e4a Add log messages to GetUsers endpoint 2024-03-07 18:58:42 -05:00
Evan Fiordeliso 5c76a4b1c3 Remove log messages from token endpoint 2024-03-07 18:56:09 -05:00
Evan Fiordeliso a937cb9f58 Add more log messages to get token function 2024-03-07 18:53:40 -05:00
Evan Fiordeliso 3d97b0174b Re-add debug message to get token function 2024-03-07 18:45:59 -05:00
143 changed files with 1481 additions and 592 deletions

11
CHANGELOG.md Normal file
View File

@ -0,0 +1,11 @@
# Changelog
All notable changes to this project will be documented in this file.
## [1.2.1] - 2024-03-08
### 🐛 Bug Fixes
- *(devenv)* Fix version variable in release script
<!-- generated by git-cliff -->

5
api.go
View File

@ -2,9 +2,8 @@ package twitch
import (
"go.fifitido.net/twitch/api"
"go.fifitido.net/twitch/auth"
)
func NewAPI(authClient *auth.Client) *api.API {
return api.NewDefault(authClient)
func NewAPI(clientId, clientSecret, redirectUri string) *api.API {
return api.NewDefault(clientId, clientSecret, redirectUri)
}

View File

@ -3,9 +3,12 @@ package ads
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"go.fifitido.net/twitch/api/endpoint"
)
type GetAdScheduleResponse struct {
@ -38,21 +41,25 @@ type GetAdScheduleData struct {
//
// Requires a user access token that includes the channel:read:ads scope.
// The user_id in the user access token must match the broadcaster_id.
func (e *Ads) GetAdSchedule(ctx context.Context, broadcasterID string) (*GetAdScheduleResponse, error) {
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "channels/ads", RawQuery: "broadcaster_id=" + broadcasterID})
func (a *Ads) GetAdSchedule(ctx context.Context, broadcasterID string) (*GetAdScheduleResponse, error) {
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(a.baseUrl, "channels/ads", v), nil)
if err != nil {
return nil, err
}
res, err := e.client.Do(req)
res, err := a.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get ad schedule (%d)", res.StatusCode)
}
var data GetAdScheduleResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,12 @@ package ads
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"go.fifitido.net/twitch/api/endpoint"
)
type SnoozeNextAdResponse struct {
@ -30,9 +33,9 @@ type SnoozeNextAdData struct {
// Requires a user access token that includes the channel:manage:ads scope.
// The user_id in the user access token must match the broadcaster_id.
func (e *Ads) SnoozeNextAd(ctx context.Context, broadcasterID string) (*SnoozeNextAdResponse, error) {
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "channels/ads/schedule/snooze", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequest(http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequest(http.MethodPost, endpoint.Make(e.baseUrl, "channels/ads/schedule/snooze", v), nil)
if err != nil {
return nil, err
}
@ -41,9 +44,13 @@ func (e *Ads) SnoozeNextAd(ctx context.Context, broadcasterID string) (*SnoozeNe
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to snooze next ad (%d)", res.StatusCode)
}
var data SnoozeNextAdResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,11 @@ package ads
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type StartCommercialRequest struct {
@ -41,8 +43,7 @@ type StartCommercialData struct {
// NOTE: Only the broadcaster may start a commercial; the broadcasters editors and moderators may not start commercials on behalf of the broadcaster.
//
// Requires a user access token that includes the channel:edit:commercial scope.
func (e *Ads) StartCommercial(ctx context.Context, body *StartCommercialRequest) (*StartCommercialResponse, error) {
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "channels/commercial"})
func (a *Ads) StartCommercial(ctx context.Context, body *StartCommercialRequest) (*StartCommercialResponse, error) {
r, w := io.Pipe()
@ -54,18 +55,22 @@ func (e *Ads) StartCommercial(ctx context.Context, body *StartCommercialRequest)
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(a.baseUrl, "channels/commercial"), r)
if err != nil {
return nil, err
}
res, err := e.client.Do(req)
res, err := a.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to start commercial (%d)", res.StatusCode)
}
var data StartCommercialResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package analytics
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -80,22 +81,25 @@ type ExtensionAnalyticsReport struct {
// Learn More: https://dev.twitch.tv/docs/insights
//
// Requires a user access token that includes the analytics:read:extensions scope.
func (e *Analytics) GetExtensionAnalytics(ctx context.Context, params GetExtensionAnalyticsParams) (*GetExtensionAnalyticsResponse, error) {
func (a *Analytics) GetExtensionAnalytics(ctx context.Context, params GetExtensionAnalyticsParams) (*GetExtensionAnalyticsResponse, error) {
v, _ := query.Values(params)
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "analytics/extensions", RawQuery: v.Encode()})
req, err := http.NewRequest(http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequest(http.MethodGet, endpoint.Make(a.baseUrl, "analytics/extensions", v), nil)
if err != nil {
return nil, err
}
res, err := e.client.Do(req)
res, err := a.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extension analytics (%d)", res.StatusCode)
}
var data GetExtensionAnalyticsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package analytics
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -81,22 +82,25 @@ type GameAnalyticsReport struct {
// Learn more: https://dev.twitch.tv/docs/insights
//
// Requires a user access token that includes the analytics:read:games scope.
func (e *Analytics) GetGameAnalytics(ctx context.Context, params GetGameAnalyticsParams) (*GetGameAnalyticsResponse, error) {
func (a *Analytics) GetGameAnalytics(ctx context.Context, params GetGameAnalyticsParams) (*GetGameAnalyticsResponse, error) {
v, _ := query.Values(params)
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "analytics/games", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(a.baseUrl, "analytics/games", v), nil)
if err != nil {
return nil, err
}
res, err := e.client.Do(req)
res, err := a.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get game analytics (%d)", res.StatusCode)
}
var data GetGameAnalyticsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -39,9 +39,9 @@ import (
const HelixBaseUrl = "https://api.twitch.tv/helix"
type API struct {
client *http.Client
baseUrl *url.URL
authClient *auth.Client
client *http.Client
baseUrl *url.URL
Auth *auth.Auth
Ads *ads.Ads
Analytics *analytics.Analytics
@ -73,11 +73,11 @@ type API struct {
Whispers *whispers.Whispers
}
func New(client *http.Client, baseUrl *url.URL, authClient *auth.Client) *API {
func New(client *http.Client, baseUrl *url.URL, authClient *auth.Auth) *API {
return &API{
client: client,
baseUrl: baseUrl,
authClient: authClient,
client: client,
baseUrl: baseUrl,
Auth: authClient,
Ads: ads.New(client, baseUrl),
Analytics: analytics.New(client, baseUrl),
@ -110,21 +110,26 @@ func New(client *http.Client, baseUrl *url.URL, authClient *auth.Client) *API {
}
}
func NewDefault(authClient *auth.Client) *API {
client := &http.Client{}
func NewDefault(clientId, clientSecret, redirectUri string) *API {
client := &http.Client{
Transport: &apiTransport{
clientId: clientId,
},
}
baseUrl, _ := url.Parse(HelixBaseUrl)
authClient := auth.NewWithClient(clientId, clientSecret, redirectUri, client)
return New(client, baseUrl, authClient)
}
func (a *API) WithClient(client *http.Client) *API {
return New(client, a.baseUrl, a.authClient)
return New(client, a.baseUrl, a.Auth)
}
func (a *API) WithAuthToken(token *auth.Token) *API {
return a.WithClient(&http.Client{
Transport: &oauth2.Transport{
Source: a.authClient.TokenSource(token),
Source: a.Auth.TokenSource(token),
Base: a.client.Transport,
},
})

View File

@ -3,11 +3,12 @@ package bits
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -70,9 +71,8 @@ type LeaderboardEntry struct {
// Requires a user access token that includes the bits:read scope.
func (b *Bits) GetBitsLeaderboard(ctx context.Context, params *GetBitsLeaderboardParams) (*GetBitsLeaderboardResponse, error) {
v, _ := query.Values(params)
endpoint := b.baseUrl.ResolveReference(&url.URL{Path: "bits/leaderboard", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(b.baseUrl, "bits/leaderboard", v), nil)
if err != nil {
return nil, err
}
@ -81,9 +81,13 @@ func (b *Bits) GetBitsLeaderboard(ctx context.Context, params *GetBitsLeaderboar
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get bits leaderboard (%d)", res.StatusCode)
}
var data GetBitsLeaderboardResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,12 @@ package bits
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"go.fifitido.net/twitch/api/endpoint"
)
type GetCheermotesResponse struct {
@ -82,9 +85,9 @@ type CheermoteImageSizes struct {
//
// Requires an app access token or user access token.
func (b *Bits) GetCheermotes(ctx context.Context, broadcasterID string) (*GetCheermotesResponse, error) {
endpoint := b.baseUrl.ResolveReference(&url.URL{Path: "bits/cheermotes", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(b.baseUrl, "bits/cheermotes", v), nil)
if err != nil {
return nil, err
}
@ -93,9 +96,13 @@ func (b *Bits) GetCheermotes(ctx context.Context, broadcasterID string) (*GetChe
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get cheermotes (%d)", res.StatusCode)
}
var data GetCheermotesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package bits
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -97,9 +98,8 @@ type ProductDataCost struct {
// Requires an app access token.
func (b *Bits) GetExtensionTransactions(ctx context.Context, params *GetExtensionTransactionsParams) (*GetExtensionTransactionsResponse, error) {
v, _ := query.Values(params)
endpoint := b.baseUrl.ResolveReference(&url.URL{Path: "extensions/transactions", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(b.baseUrl, "extensions/transactions", v), nil)
if err != nil {
return nil, err
}
@ -108,9 +108,13 @@ func (b *Bits) GetExtensionTransactions(ctx context.Context, params *GetExtensio
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extension transactions (%d)", res.StatusCode)
}
var data GetExtensionTransactionsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package ccls
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -38,9 +39,8 @@ type ContentClassificationLabelData struct {
// Requires an app access token or user access token.
func (c *CCLS) GetContentClassificationLabels(ctx context.Context, params GetContentClassificationLabelsParams) (*GetContentClassificationLabelsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "content_classification_labels", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "content_classification_labels", v), nil)
if err != nil {
return nil, err
}
@ -51,6 +51,11 @@ func (c *CCLS) GetContentClassificationLabels(ctx context.Context, params GetCon
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get content classification labels (%d)", res.StatusCode)
}
var data GetContentClassificationLabelsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,12 @@ package channelpoints
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type CreateCustomRewardsRequest struct {
@ -70,7 +73,7 @@ type CreateCustomRewardsResponse struct {
//
// Requires a user access token that includes the channel:manage:redemptions scope.
func (c *ChannelPoints) CreateCustomRewards(ctx context.Context, broadcastID string, body *CreateCustomRewardsRequest) (*CreateCustomRewardsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channel_points/custom_rewards", RawQuery: "broadcaster_id=" + broadcastID})
v := url.Values{"broadcaster_id": {broadcastID}}
r, w := io.Pipe()
@ -82,7 +85,7 @@ func (c *ChannelPoints) CreateCustomRewards(ctx context.Context, broadcastID str
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(c.baseUrl, "channel_points/custom_rewards", v), r)
if err != nil {
return nil, err
}
@ -91,9 +94,13 @@ func (c *ChannelPoints) CreateCustomRewards(ctx context.Context, broadcastID str
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to create custom rewards (%d)", res.StatusCode)
}
var data CreateCustomRewardsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package channelpoints
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type DeleteCustomRewardParams struct {
@ -24,9 +25,8 @@ type DeleteCustomRewardParams struct {
// Requires a user access token that includes the channel:manage:redemptions scope.
func (c *ChannelPoints) DeleteCustomReward(ctx context.Context, params *DeleteCustomRewardParams) error {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channel_points/custom_rewards", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(c.baseUrl, "channel_points/custom_rewards", v), nil)
if err != nil {
return err
}
@ -35,8 +35,12 @@ func (c *ChannelPoints) DeleteCustomReward(ctx context.Context, params *DeleteCu
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to delete custom reward (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,10 +3,11 @@ package channelpoints
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetCustomRewardParams struct {
@ -37,9 +38,8 @@ type GetCustomRewardResponse struct {
// Requires a user access token that includes the channel:read:redemptions or channel:manage:redemptions scope.
func (c *ChannelPoints) GetCustomReward(ctx context.Context, params *GetCustomRewardParams) (*GetCustomRewardResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channel_points/custom_rewards", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "channel_points/custom_rewards", v), nil)
if err != nil {
return nil, err
}
@ -48,9 +48,13 @@ func (c *ChannelPoints) GetCustomReward(ctx context.Context, params *GetCustomRe
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get custom rewards (%d)", res.StatusCode)
}
var data GetCustomRewardResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package channelpoints
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -53,9 +54,8 @@ type GetCustomRewardRedemptionResponse struct {
// Requires a user access token that includes the channel:read:redemptions or channel:manage:redemptions scope.
func (c *ChannelPoints) GetCustomRewardRedemption(ctx context.Context, params *GetCustomRewardRedemptionParams) (*GetCustomRewardRedemptionResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channel_points/custom_rewards/redemptions", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "channel_points/custom_rewards/redemptions", v), nil)
if err != nil {
return nil, err
}
@ -64,9 +64,13 @@ func (c *ChannelPoints) GetCustomRewardRedemption(ctx context.Context, params *G
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get custom reward redemptions (%d)", res.StatusCode)
}
var data GetCustomRewardRedemptionResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package channelpoints
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateCustomRewardParams struct {
@ -82,7 +83,6 @@ type UpdateCustomRewardResponse struct {
// Requires a user access token that includes the channel:manage:redemptions scope.
func (c *ChannelPoints) UpdateCustomReward(ctx context.Context, params *UpdateCustomRewardParams, body *UpdateCustomRewardRequest) (*UpdateCustomRewardResponse, error) {
v, _ := query.Values(body)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channel_points/custom_rewards", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -94,7 +94,7 @@ func (c *ChannelPoints) UpdateCustomReward(ctx context.Context, params *UpdateCu
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(c.baseUrl, "channel_points/custom_rewards", v), r)
if err != nil {
return nil, err
}
@ -103,9 +103,13 @@ func (c *ChannelPoints) UpdateCustomReward(ctx context.Context, params *UpdateCu
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update custom reward (%d)", res.StatusCode)
}
var data UpdateCustomRewardResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package channelpoints
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateRedemptionStatusParams struct {
@ -42,7 +43,6 @@ type UpdateRedemptionStatusResponse struct {
// Requires a user access token that includes the channel:manage:redemptions scope.
func (c *ChannelPoints) UpdateRedemptionStatus(ctx context.Context, params *UpdateRedemptionStatusParams, body *UpdateRedemptionStatusRequest) (*UpdateRedemptionStatusResponse, error) {
v, _ := query.Values(body)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channel_points/custom_rewards/redemptions", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -54,7 +54,7 @@ func (c *ChannelPoints) UpdateRedemptionStatus(ctx context.Context, params *Upda
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(c.baseUrl, "channel_points/custom_rewards/redemptions", v), r)
if err != nil {
return nil, err
}
@ -63,9 +63,13 @@ func (c *ChannelPoints) UpdateRedemptionStatus(ctx context.Context, params *Upda
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update redemption status (%d)", res.StatusCode)
}
var data UpdateRedemptionStatusResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,12 @@ package channels
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"go.fifitido.net/twitch/api/endpoint"
)
type GetChannelEditorsResponse struct {
@ -28,9 +31,9 @@ type ChannelEditor struct {
//
// Requires a user access token that includes the channel:read:editors scope.
func (c *Channels) GetChannelEditors(ctx context.Context, broadcasterID string) (*GetChannelEditorsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channels/editors", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "channels/editors", v), nil)
if err != nil {
return nil, err
}
@ -39,9 +42,13 @@ func (c *Channels) GetChannelEditors(ctx context.Context, broadcasterID string)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get channel editors (%d)", res.StatusCode)
}
var data GetChannelEditorsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package channels
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -71,9 +72,8 @@ type ChannelFollower struct {
// only the total follower count will be included in the response.
func (c *Channels) GetChannelFollowers(ctx context.Context, params *GetChannelFollowersParams) (*GetChannelFollowersResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channels/followers", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "channels/followers", v), nil)
if err != nil {
return nil, err
}
@ -82,9 +82,13 @@ func (c *Channels) GetChannelFollowers(ctx context.Context, params *GetChannelFo
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get channel followers (%d)", res.StatusCode)
}
var data GetChannelFollowersResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package channels
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/ccls"
"go.fifitido.net/twitch/api/endpoint"
)
type GetChannelInformationParams struct {
@ -70,9 +71,8 @@ type ChannelInformation struct {
// Requires an app access token or user access token.
func (c *Channels) GetChannelInformation(ctx context.Context, params *GetChannelInformationParams) (*GetChannelInformdationResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channels", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "channels", v), nil)
if err != nil {
return nil, err
}
@ -81,9 +81,13 @@ func (c *Channels) GetChannelInformation(ctx context.Context, params *GetChannel
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get channel information (%d)", res.StatusCode)
}
var data GetChannelInformdationResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package channels
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -62,9 +63,8 @@ type FollowedChannel struct {
// Requires a user access token that includes the user:read:follows scope.
func (c *Channels) GetFollowedChannels(ctx context.Context, params *GetFollowedChannelsParams) (*GetFollowedChannelsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "users/follows", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "users/follows", v), nil)
if err != nil {
return nil, err
}
@ -76,6 +76,11 @@ func (c *Channels) GetFollowedChannels(ctx context.Context, params *GetFollowedC
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get followed channels (%d)", res.StatusCode)
}
var data GetFollowedChannelsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,13 @@ package channels
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/ccls"
"go.fifitido.net/twitch/api/endpoint"
)
type ModifyChannelInformationRequest struct {
@ -54,7 +56,7 @@ type ModifyContentClassificationLabel struct {
//
// Requires a user access token that includes the channel:manage:broadcast scope.
func (c *Channels) ModifyChannelInformation(ctx context.Context, broadcasterID string, body *ModifyChannelInformationRequest) error {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "channels", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
r, w := io.Pipe()
@ -66,14 +68,21 @@ func (c *Channels) ModifyChannelInformation(ctx context.Context, broadcasterID s
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(c.baseUrl, "channels", v), r)
if err != nil {
return err
}
if _, err := c.client.Do(req); err != nil {
res, err := c.client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to modify channel information (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,9 +3,11 @@ package charity
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -55,9 +57,9 @@ type CharityCampaign struct {
//
// Requires a user access token that includes the channel:read:charity scope.
func (c *Charity) GetCharityCampaign(ctx context.Context, broadcasterID string) (*GetCharityCampaignResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "charity/campaigns", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "charity/campaigns", v), nil)
if err != nil {
return nil, err
}
@ -69,6 +71,11 @@ func (c *Charity) GetCharityCampaign(ctx context.Context, broadcasterID string)
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get charity campaign (%d)", res.StatusCode)
}
var data GetCharityCampaignResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package charity
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -60,9 +61,8 @@ type CharityCampaignDonation struct {
// Requires a user access token that includes the channel:read:charity scope.
func (c *Charity) GetCharityCampaignDonations(ctx context.Context, params *GetCharityCampaignDonationsParams) (*GetCharityCampaignDonationsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "charity/campaigns/donations", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "charity/campaigns/donations", v), nil)
if err != nil {
return nil, err
}
@ -71,6 +71,12 @@ func (c *Charity) GetCharityCampaignDonations(ctx context.Context, params *GetCh
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get charity campaign donations (%d)", res.StatusCode)
}
var respBody GetCharityCampaignDonationsResponse
if err := json.NewDecoder(res.Body).Decode(&respBody); err != nil {

View File

@ -3,8 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type GetChannelChatBadgesResponse struct {
@ -19,9 +22,9 @@ type GetChannelChatBadgesResponse struct {
//
// Requires an app access token or user access token.
func (c *Chat) GetChannelChatBadges(ctx context.Context, broadcasterID string) (*GetChannelChatBadgesResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/badges", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/badges", v), nil)
if err != nil {
return nil, err
}
@ -32,6 +35,11 @@ func (c *Chat) GetChannelChatBadges(ctx context.Context, broadcasterID string) (
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get channel chat badges (%d)", res.StatusCode)
}
var data GetChannelChatBadgesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,8 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type GetChannelEmotesResponse struct {
@ -88,21 +91,26 @@ type ChannelEmote struct {
//
// Requires an app access token or user access token.
func (c *Chat) GetChannelEmotes(ctx context.Context, broadcasterID string) (*GetChannelEmotesResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/emotes", RawQuery: "broadcaster_id=" + broadcasterID})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/emotes", v), nil)
if err != nil {
return nil, err
}
resp, err := c.client.Do(req)
res, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get channel emotes (%d)", res.StatusCode)
}
var response GetChannelEmotesResponse
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, err
}

View File

@ -3,10 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetChatSettingsParams struct {
@ -35,9 +36,8 @@ type GetChatSettingsResponse struct {
// Requires an app access token or user access token.
func (c *Chat) GetChatSettings(ctx context.Context, params *GetChatSettingsParams) (*GetChatSettingsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/settings", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/settings", v), nil)
if err != nil {
return nil, err
}
@ -48,6 +48,11 @@ func (c *Chat) GetChatSettings(ctx context.Context, params *GetChatSettingsParam
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get chat settings (%d)", res.StatusCode)
}
var data GetChatSettingsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -62,21 +63,25 @@ type Chatter struct {
// Requires a user access token that includes the moderator:read:chatters scope.
func (c *Chat) GetChatters(ctx context.Context, params *GetChattersParams) (*GetChattersResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/chatters", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/chatters", v), nil)
if err != nil {
return nil, err
}
resp, err := c.client.Do(req)
res, err := c.client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get chatters (%d)", res.StatusCode)
}
var response GetChattersResponse
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, err
}

View File

@ -3,10 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetEmoteSetsParams struct {
@ -94,9 +95,8 @@ type EmoteSetEmote struct {
// Requires an app access token or user access token.
func (c *Chat) GetEmoteSets(ctx context.Context, params *GetEmoteSetsParams) (*GetEmoteSetsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/emotes/set", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/emotes/set", v), nil)
if err != nil {
return nil, err
}
@ -107,6 +107,11 @@ func (c *Chat) GetEmoteSets(ctx context.Context, params *GetEmoteSetsParams) (*G
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get emote sets (%d)", res.StatusCode)
}
var data GetEmoteSetsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,8 +3,10 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type GetGlobalChatBadgesResponse struct {
@ -17,9 +19,7 @@ type GetGlobalChatBadgesResponse struct {
//
// Requires an app access token or user access token.
func (c *Chat) GetGlobalChatBadges(ctx context.Context) (*GetGlobalChatBadgesResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/badges/global"})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/badges/global"), nil)
if err != nil {
return nil, err
}
@ -30,6 +30,11 @@ func (c *Chat) GetGlobalChatBadges(ctx context.Context) (*GetGlobalChatBadgesRes
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get global chat badges (%d)", res.StatusCode)
}
var data GetGlobalChatBadgesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,8 +3,10 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type GetGlobalEmotesResponse struct {
@ -64,9 +66,7 @@ type GlobalEmote struct {
//
// Requires an app access token or user access token.
func (c *Chat) GetGlobalEmotes(ctx context.Context) (*GetGlobalEmotesResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/emotes/global"})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/emotes/global"), nil)
if err != nil {
return nil, err
}
@ -77,6 +77,11 @@ func (c *Chat) GetGlobalEmotes(ctx context.Context) (*GetGlobalEmotesResponse, e
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get global emotes (%d)", res.StatusCode)
}
var data GetGlobalEmotesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetUserChatColorParams struct {
@ -43,9 +44,8 @@ type UserChatColor struct {
// Requires an app access token or user access token.
func (c *Chat) GetUserChatColor(ctx context.Context, params *GetUserChatColorParams) (*GetUserChatColorResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/color", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "chat/color", v), nil)
if err != nil {
return nil, err
}
@ -56,6 +56,11 @@ func (c *Chat) GetUserChatColor(ctx context.Context, params *GetUserChatColorPar
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get user chat color (%d)", res.StatusCode)
}
var data GetUserChatColorResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -37,7 +38,6 @@ type SendChatAnnouncementRequest struct {
// Requires a user access token that includes the moderator:manage:announcements scope.
func (c *Chat) SendChatAnnouncement(ctx context.Context, params *SendChatAnnouncementParams, body *SendChatAnnouncementRequest) error {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/announcements", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -49,7 +49,7 @@ func (c *Chat) SendChatAnnouncement(ctx context.Context, params *SendChatAnnounc
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(c.baseUrl, "chat/announcements", v), r)
if err != nil {
return err
}
@ -60,5 +60,10 @@ func (c *Chat) SendChatAnnouncement(ctx context.Context, params *SendChatAnnounc
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to send chat announcement (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,9 +3,11 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type SendChatMessageRequest struct {
@ -53,8 +55,6 @@ type DropReason struct {
// If app access token used, then additionally requires user:bot scope from chatting user,
// and either channel:bot scope from broadcaster or moderator status.
func (c *Chat) SendChatMessage(ctx context.Context, body *SendChatMessageRequest) (*SendChatMessageResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/messages"})
r, w := io.Pipe()
go func() {
@ -65,7 +65,7 @@ func (c *Chat) SendChatMessage(ctx context.Context, body *SendChatMessageRequest
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(c.baseUrl, "chat/messages"), r)
if err != nil {
return nil, err
}
@ -76,6 +76,11 @@ func (c *Chat) SendChatMessage(ctx context.Context, body *SendChatMessageRequest
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to send chat message (%d)", res.StatusCode)
}
var data SendChatMessageResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package chat
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type SendShoutoutParams struct {
@ -38,9 +39,8 @@ type SendShoutoutParams struct {
// Requires a user access token that includes the moderator:manage:shoutouts scope.
func (c *Chat) SendShoutout(ctx context.Context, params *SendShoutoutParams) error {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/shoutouts", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(c.baseUrl, "chat/shoutouts", v), nil)
if err != nil {
return err
}
@ -51,5 +51,10 @@ func (c *Chat) SendShoutout(ctx context.Context, params *SendShoutoutParams) err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to send shoutout (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,11 +3,12 @@ package chat
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateChatSettingsParams struct {
@ -93,7 +94,6 @@ type UpdateChatSettingsResponse struct {
// Requires a user access token that includes the moderator:manage:chat_settings scope.
func (c *Chat) UpdateChatSettings(ctx context.Context, params *UpdateChatSettingsParams, body *UpdateChatSettingsRequest) (*UpdateChatSettingsResponse, error) {
v, _ := query.Values(body)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/settings", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -105,7 +105,7 @@ func (c *Chat) UpdateChatSettings(ctx context.Context, params *UpdateChatSetting
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(c.baseUrl, "chat/settings", v), r)
if err != nil {
return nil, err
}
@ -116,6 +116,11 @@ func (c *Chat) UpdateChatSettings(ctx context.Context, params *UpdateChatSetting
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update chat settings (%d)", res.StatusCode)
}
var data UpdateChatSettingsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package chat
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateUserChatColorParams struct {
@ -26,9 +27,8 @@ type UpdateUserChatColorParams struct {
// Requires a user access token that includes the user:manage:chat_color scope.
func (c *Chat) UpdateUserChatColor(ctx context.Context, params *UpdateUserChatColorParams) error {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/color", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.Make(c.baseUrl, "chat/color", v), nil)
if err != nil {
return err
}
@ -39,5 +39,10 @@ func (c *Chat) UpdateUserChatColor(ctx context.Context, params *UpdateUserChatCo
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to update user chat color (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,9 +3,11 @@ package conduit
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type CreateConduitsRequest struct {
@ -21,8 +23,6 @@ type CreateConduitsResponse struct {
//
// Requires an app access token.
func (c *Conduit) CreateConduits(ctx context.Context, body *CreateConduitsRequest) (*CreateConduitsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "eventsub/conduits"})
r, w := io.Pipe()
go func() {
@ -33,7 +33,7 @@ func (c *Conduit) CreateConduits(ctx context.Context, body *CreateConduitsReques
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(c.baseUrl, "eventsub/conduits"), r)
if err != nil {
return nil, err
}
@ -44,6 +44,11 @@ func (c *Conduit) CreateConduits(ctx context.Context, body *CreateConduitsReques
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to create conduit (%d)", res.StatusCode)
}
var data CreateConduitsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,8 +2,11 @@ package conduit
import (
"context"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
// Deletes a specified conduit.
@ -11,9 +14,9 @@ import (
//
// Requires an app access token.
func (c *Conduit) DeleteConduit(ctx context.Context, id string) error {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "eventsub/conduits", RawQuery: "id=" + id})
v := url.Values{"id": {id}}
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(c.baseUrl, "eventsub/conduits", v), nil)
if err != nil {
return err
}
@ -24,5 +27,10 @@ func (c *Conduit) DeleteConduit(ctx context.Context, id string) error {
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to delete conduit (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,10 +3,11 @@ package conduit
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -34,9 +35,8 @@ type GetConduitShardsResponse struct {
// Requires an app access token.
func (c *Conduit) GetConduitShards(ctx context.Context, params *GetConduitShardsParams) (*GetConduitShardsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "eventsub/conduits/shards", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "eventsub/conduits/shards", v), nil)
if err != nil {
return nil, err
}
@ -47,6 +47,11 @@ func (c *Conduit) GetConduitShards(ctx context.Context, params *GetConduitShards
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get conduit shards (%d)", res.StatusCode)
}
var data GetConduitShardsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,8 +3,10 @@ package conduit
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type GetConduitsResponse struct {
@ -16,9 +18,7 @@ type GetConduitsResponse struct {
//
// Requires an app access token.
func (c *Conduit) GetConduits(ctx context.Context) (*GetConduitsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "eventsub/conduits"})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(c.baseUrl, "eventsub/conduits"), nil)
if err != nil {
return nil, err
}
@ -29,6 +29,11 @@ func (c *Conduit) GetConduits(ctx context.Context) (*GetConduitsResponse, error)
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get conduits (%d)", res.StatusCode)
}
var data GetConduitsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package conduit
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/eventsub"
)
@ -68,8 +69,6 @@ type UpdateConduitShardsError struct {
//
// Requires an app access token.
func (c *Conduit) UpdateConduitShards(ctx context.Context, body *UpdateConduitShardsRequest) (*UpdateConduitShardsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "eventsub/conduits/shards"})
r, w := io.Pipe()
go func() {
@ -80,7 +79,7 @@ func (c *Conduit) UpdateConduitShards(ctx context.Context, body *UpdateConduitSh
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(c.baseUrl, "eventsub/conduits/shards"), r)
if err != nil {
return nil, err
}
@ -91,6 +90,11 @@ func (c *Conduit) UpdateConduitShards(ctx context.Context, body *UpdateConduitSh
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update conduit shards (%d)", res.StatusCode)
}
var data UpdateConduitShardsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,11 @@ package conduit
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateConduitsRequest struct {
@ -26,8 +28,6 @@ type UpdateConduitsResponse struct {
//
// Requires an app access token.
func (c *Conduit) UpdateConduits(ctx context.Context, body *UpdateConduitsRequest) (*UpdateConduitsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "eventsub/conduits"})
r, w := io.Pipe()
go func() {
@ -38,7 +38,7 @@ func (c *Conduit) UpdateConduits(ctx context.Context, body *UpdateConduitsReques
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(c.baseUrl, "eventsub/conduits"), r)
if err != nil {
return nil, err
}
@ -49,6 +49,11 @@ func (c *Conduit) UpdateConduits(ctx context.Context, body *UpdateConduitsReques
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update conduit (%d)", res.StatusCode)
}
var data UpdateConduitsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

19
api/endpoint/endpoint.go Normal file
View File

@ -0,0 +1,19 @@
package endpoint
import (
"net/url"
"strings"
)
func Make(baseUrl *url.URL, path string, vals ...url.Values) string {
var sb strings.Builder
sb.WriteString(baseUrl.String())
sb.WriteString("/")
sb.WriteString(path)
if len(vals) > 0 {
sb.WriteString("?")
sb.WriteString(vals[0].Encode())
}
return sb.String()
}

View File

@ -3,11 +3,12 @@ package entitlements
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -88,19 +89,24 @@ type Entitlement struct {
// User | game_id | The request returns all entitlements that the specified game granted to the user identified in the access token.
//
// Requires an app access token or user access token. The client ID in the access token must own the game.
func (c *Entitlements) GetDropsEntitlements(ctx context.Context, params *GetDropsEntitlementsParams) (*GetDropsEntitlementsResponse, error) {
func (e *Entitlements) GetDropsEntitlements(ctx context.Context, params *GetDropsEntitlementsParams) (*GetDropsEntitlementsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "entitlements/drops", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "entitlements/drops", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get drops entitlements (%d)", res.StatusCode)
}
var data GetDropsEntitlementsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {

View File

@ -3,9 +3,11 @@ package entitlements
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateDropsEntitlementsRequest struct {
@ -38,9 +40,7 @@ type UpdateDropsEntitlementsData struct {
// User | Updates all entitlements owned by the user in the access token and where the benefits are owned by the organization in the access token.
//
// Requires an app access token or user access token. The client ID in the access token must own the game.
func (c *Entitlements) UpdateDropsEntitlements(ctx context.Context, request *UpdateDropsEntitlementsRequest) (*UpdateDropsEntitlementsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "entitlements/drops"})
func (e *Entitlements) UpdateDropsEntitlements(ctx context.Context, request *UpdateDropsEntitlementsRequest) (*UpdateDropsEntitlementsResponse, error) {
r, w := io.Pipe()
go func() {
@ -51,15 +51,21 @@ func (c *Entitlements) UpdateDropsEntitlements(ctx context.Context, request *Upd
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(e.baseUrl, "entitlements/drops"), r)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update drops entitlements (%d)", res.StatusCode)
}
var data UpdateDropsEntitlementsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {

View File

@ -3,9 +3,11 @@ package eventsub
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type CreateEventSubSubscriptionRequest struct {
@ -50,7 +52,6 @@ type CreateEventSubSubscriptionResponse struct {
// If you use Conduits to receive events, the request must specify an app access token.
// The request will fail if you use a user access token.
func (e *EventSub) CreateEventSubSubscription(ctx context.Context, body *CreateEventSubSubscriptionRequest) (*CreateEventSubSubscriptionResponse, error) {
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "eventsub/subscriptions"})
r, w := io.Pipe()
@ -62,7 +63,7 @@ func (e *EventSub) CreateEventSubSubscription(ctx context.Context, body *CreateE
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(e.baseUrl, "eventsub/subscriptions"), r)
if err != nil {
return nil, err
}
@ -74,6 +75,11 @@ func (e *EventSub) CreateEventSubSubscription(ctx context.Context, body *CreateE
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to create EventSub subscription (%d)", res.StatusCode)
}
var data CreateEventSubSubscriptionResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,8 +2,11 @@ package eventsub
import (
"context"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
// Deletes an EventSub subscription.
@ -14,16 +17,23 @@ import (
// If you use WebSockets to receive events, the request must specify a user access token.
// The request will fail if you use an app access token. The token may include any scopes.
func (e *EventSub) DeleteEventSubSubscription(ctx context.Context, id string) error {
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "eventsub/subscriptions", RawQuery: "id=" + id})
v := url.Values{"id": {id}}
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(e.baseUrl, "eventsub/subscriptions", v), nil)
if err != nil {
return err
}
if _, err := e.client.Do(req); err != nil {
res, err := e.client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to delete EventSub subscription (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,10 +3,11 @@ package eventsub
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -57,9 +58,8 @@ type GetEventSubSubscriptionsResponse struct {
// The request will fail if you use an app access token. The token may include any scopes.
func (e *EventSub) GetEventSubSubscriptions(ctx context.Context, params *GetEventSubSubscriptionsParams) (*GetEventSubSubscriptionsResponse, error) {
v, _ := query.Values(params)
endpoint := e.baseUrl.ResolveReference(&url.URL{Path: "eventsub/subscriptions", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "eventsub/subscriptions", v), nil)
if err != nil {
return nil, err
}
@ -71,6 +71,11 @@ func (e *EventSub) GetEventSubSubscriptions(ctx context.Context, params *GetEven
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get EventSub subscriptions (%d)", res.StatusCode)
}
var data GetEventSubSubscriptionsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type CreateExtensionSecretParams struct {
@ -34,21 +35,25 @@ type CreateExtensionSecretResponse struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// The role field must be set to external.
func (c *Extensions) CreateExtensionSecret(ctx context.Context, params *CreateExtensionSecretParams) (*CreateExtensionSecretResponse, error) {
func (e *Extensions) CreateExtensionSecret(ctx context.Context, params *CreateExtensionSecretParams) (*CreateExtensionSecretResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/jwt/secrets", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(e.baseUrl, "extensions/jwt/secrets", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to create extension secret (%d)", res.StatusCode)
}
var data CreateExtensionSecretResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetExtensionBitsProductsParams struct {
@ -22,21 +23,25 @@ type GetExtensionBitsProductsResponse struct {
// Gets the list of Bits products that belongs to the extension. The client ID in the app access token identifies the extension.
//
// Requires an app access token. The client ID in the app access token must be the extensions client ID.
func (c *Extensions) GetExtensionBitsProducts(ctx context.Context, params *GetExtensionBitsProductsParams) (*GetExtensionBitsProductsResponse, error) {
func (e *Extensions) GetExtensionBitsProducts(ctx context.Context, params *GetExtensionBitsProductsParams) (*GetExtensionBitsProductsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "bits/extensions", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "bits/extensions", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extension bits products (%d)", res.StatusCode)
}
var data GetExtensionBitsProductsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetExtensionConfigurationSegmentParams struct {
@ -57,21 +58,25 @@ type ConfigurationSegmentData struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// The role field must be set to external.
func (c *Extensions) GetExtensionConfigurationSegment(ctx context.Context, params *GetExtensionConfigurationSegmentParams) (*GetExtensionConfigurationSegmentResponse, error) {
func (e *Extensions) GetExtensionConfigurationSegment(ctx context.Context, params *GetExtensionConfigurationSegmentParams) (*GetExtensionConfigurationSegmentResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/configurations", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "extensions/configurations", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extension configuration segment (%d)", res.StatusCode)
}
var data GetExtensionConfigurationSegmentResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -49,21 +50,25 @@ type ExtensionLiveChannel struct {
// It may take a few minutes for the list to include or remove broadcasters that have recently gone live or stopped broadcasting.
//
// Requires an app access token or user access token.
func (c *Extensions) GetExtensionLiveChannels(ctx context.Context, params *GetExtensionLiveChannelsParams) (*GetExtensionLiveChannelsResponse, error) {
func (e *Extensions) GetExtensionLiveChannels(ctx context.Context, params *GetExtensionLiveChannelsParams) (*GetExtensionLiveChannelsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/live", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "extensions/live", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extension live channels (%d)", res.StatusCode)
}
var response GetExtensionLiveChannelsResponse
if err := json.NewDecoder(res.Body).Decode(&response); err != nil {
return nil, err

View File

@ -3,8 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type GetExtensionSecretsResponse struct {
@ -19,20 +22,25 @@ type GetExtensionSecretsResponse struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// The role field must be set to external.
func (c *Extensions) GetExtensionSecrets(ctx context.Context, extensionID string) (*GetExtensionSecretsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/jwt/secrets", RawQuery: "extension_id=" + extensionID})
func (e *Extensions) GetExtensionSecrets(ctx context.Context, extensionID string) (*GetExtensionSecretsResponse, error) {
v := url.Values{"extension_id": {extensionID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "extensions/jwt/secrets", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extension secrets (%d)", res.StatusCode)
}
var data GetExtensionSecretsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetExtensionsParams struct {
@ -30,21 +31,25 @@ type GetExtensionsResponse struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// The role field must be set to external.
func (c *Extensions) GetExtensions(ctx context.Context, params *GetExtensionsParams) (*GetExtensionsResponse, error) {
func (e *Extensions) GetExtensions(ctx context.Context, params *GetExtensionsParams) (*GetExtensionsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "extensions", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get extensions (%d)", res.StatusCode)
}
var data GetExtensionsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetReleasedExtensionsParams struct {
@ -25,21 +26,25 @@ type GetReleasedExtensionsResponse struct {
// Gets information about a released extension. Returns the extension if its state is Released.
//
// Requires an app access token or user access token.
func (c *Extensions) GetReleasedExtensions(ctx context.Context, params *GetReleasedExtensionsParams) (*GetReleasedExtensionsResponse, error) {
func (e *Extensions) GetReleasedExtensions(ctx context.Context, params *GetReleasedExtensionsParams) (*GetReleasedExtensionsResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/released", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(e.baseUrl, "extensions/released", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get released extensions (%d)", res.StatusCode)
}
var data GetReleasedExtensionsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,12 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type SendExtensionChatMessageRequest struct {
@ -30,8 +33,8 @@ type SendExtensionChatMessageRequest struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// The role field must be set to external.
func (c *Extensions) SendExtensionChatMessage(ctx context.Context, broadcasterID string, body *SendExtensionChatMessageRequest) error {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/chat", RawQuery: "broadcaster_id=" + broadcasterID})
func (e *Extensions) SendExtensionChatMessage(ctx context.Context, broadcasterID string, body *SendExtensionChatMessageRequest) error {
v := url.Values{"broadcaster_id": {broadcasterID}}
r, w := io.Pipe()
@ -43,16 +46,21 @@ func (c *Extensions) SendExtensionChatMessage(ctx context.Context, broadcasterID
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(e.baseUrl, "extensions/chat", v), r)
if err != nil {
return err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to send extension chat message (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,9 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type SendExtensionPubsubMessageRequest struct {
@ -41,9 +43,7 @@ type SendExtensionPubsubMessageRequest struct {
// To send the message to a specific channel, set the channel_id field in the JWT to the channels ID and set the pubsub_perms.send array to broadcast.
//
// To send the message to all channels on which your extension is active, set the channel_id field to all and set the pubsub_perms.send array to global.
func (c *Extensions) SendExtensionPubsubMessage(ctx context.Context, body *SendExtensionPubsubMessageRequest) error {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/pubsub"})
func (e *Extensions) SendExtensionPubsubMessage(ctx context.Context, body *SendExtensionPubsubMessageRequest) error {
r, w := io.Pipe()
go func() {
@ -54,16 +54,21 @@ func (c *Extensions) SendExtensionPubsubMessage(ctx context.Context, body *SendE
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(e.baseUrl, "extensions/pubsub"), r)
if err != nil {
return err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to send extension pubsub message (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,9 +3,11 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type SetExtensionConfigurationSegmentRequest struct {
@ -37,8 +39,7 @@ type SetExtensionConfigurationSegmentRequest struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// The role field must be set to external.
func (c *Extensions) SetExtensionConfigurationSegment(ctx context.Context, body *SetExtensionConfigurationSegmentRequest) error {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/configurations"})
func (e *Extensions) SetExtensionConfigurationSegment(ctx context.Context, body *SetExtensionConfigurationSegmentRequest) error {
r, w := io.Pipe()
@ -50,16 +51,21 @@ func (c *Extensions) SetExtensionConfigurationSegment(ctx context.Context, body
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.Make(e.baseUrl, "extensions/configurations"), r)
if err != nil {
return err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to set extension configuration segment: %s", res.Status)
}
return nil
}

View File

@ -3,9 +3,12 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type SetExtensionRequiredConfigurationRequest struct {
@ -31,8 +34,8 @@ type SetExtensionRequiredConfigurationRequest struct {
// The signed JWT must include the role, user_id, and exp fields
// (see JWT Schema: https://dev.twitch.tv/docs/extensions/reference/#jwt-schema).
// Set the role field to external and the user_id field to the ID of the user that owns the extension.
func (c *Extensions) SetExtensionRequiredConfiguration(ctx context.Context, broadcasterID string, body *SetExtensionRequiredConfigurationRequest) error {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "extensions/required_configuration", RawQuery: "broadcaster_id=" + broadcasterID})
func (e *Extensions) SetExtensionRequiredConfiguration(ctx context.Context, broadcasterID string, body *SetExtensionRequiredConfigurationRequest) error {
v := url.Values{"broadcaster_id": {broadcasterID}}
r, w := io.Pipe()
@ -44,16 +47,21 @@ func (c *Extensions) SetExtensionRequiredConfiguration(ctx context.Context, broa
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.Make(e.baseUrl, "extensions/required_configuration", v), r)
if err != nil {
return err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to set extension required configuration (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,10 +3,12 @@ package extensions
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateExtensionBitsProductRequest struct {
@ -51,9 +53,7 @@ type UpdateExtensionBitsProductResponse struct {
// If the SKU doesnt exist, the product is added. You may update all fields except the sku field.
//
// Requires an app access token. The client ID in the app access token must match the extensions client ID.
func (c *Extensions) UpdateExtensionBitsProduct(ctx context.Context, body *UpdateExtensionBitsProductRequest) (*UpdateExtensionBitsProductResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "bits/extensions"})
func (e *Extensions) UpdateExtensionBitsProduct(ctx context.Context, body *UpdateExtensionBitsProductRequest) (*UpdateExtensionBitsProductResponse, error) {
r, w := io.Pipe()
go func() {
@ -64,17 +64,22 @@ func (c *Extensions) UpdateExtensionBitsProduct(ctx context.Context, body *Updat
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.Make(e.baseUrl, "bits/extensions"), r)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := e.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update extension bits product (%d)", res.StatusCode)
}
var data UpdateExtensionBitsProductResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package games
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetGamesParams struct {
@ -34,21 +35,25 @@ type GetGamesResponse struct {
// You may get up to 100 categories or games by specifying their ID or name. You may specify all IDs, all names, or a combination of IDs and names. If you specify a combination of IDs and names, the total number of IDs and names must not exceed 100.
//
// Requires an app access token or user access token.
func (c *Games) GetGames(ctx context.Context, params *GetGamesParams) (*GetGamesResponse, error) {
func (g *Games) GetGames(ctx context.Context, params *GetGamesParams) (*GetGamesResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "games", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(g.baseUrl, "games", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := g.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get games (%d)", res.StatusCode)
}
var data GetGamesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package games
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -37,21 +38,25 @@ type GetTopGamesResponse struct {
// Gets information about all broadcasts on Twitch.
//
// Requires an app access token or user access token.
func (c *Games) GetTopGames(ctx context.Context, params *GetTopGamesParams) (*GetTopGamesResponse, error) {
func (g *Games) GetTopGames(ctx context.Context, params *GetTopGamesParams) (*GetTopGamesResponse, error) {
v, _ := query.Values(params)
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "games/top", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(g.baseUrl, "games/top", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := g.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get top games (%d)", res.StatusCode)
}
var data GetTopGamesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,12 @@ package goals
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"go.fifitido.net/twitch/api/endpoint"
)
type GetCreatorGoalsResponse struct {
@ -81,20 +84,25 @@ type Goal struct {
// using the channel.goal.progress subscription type. Read More: https://dev.twitch.tv/docs/api/goals#requesting-event-notifications
//
// Requires a user access token that includes the channel:read:goals scope.
func (c *Goals) GetCreatorGoals(ctx context.Context, broadcasterID string) (*GetCreatorGoalsResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "goals", RawQuery: "broadcaster_id=" + broadcasterID})
func (g *Goals) GetCreatorGoals(ctx context.Context, broadcasterID string) (*GetCreatorGoalsResponse, error) {
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(g.baseUrl, "goals", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := g.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get creator goals (%d)", res.StatusCode)
}
var data GetCreatorGoalsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type AssignGuestStarSlot struct {
@ -34,9 +35,8 @@ type AssignGuestStarSlot struct {
// Requires OAuth Scope: channel:manage:guest_star or moderator:manage:guest_star
func (g *GuestStar) AssignGuestStarSlot(ctx context.Context, params *AssignGuestStarSlot) error {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/slot", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(g.baseUrl, "guest_star/slot", v), nil)
if err != nil {
return err
}
@ -47,5 +47,10 @@ func (g *GuestStar) AssignGuestStarSlot(ctx context.Context, params *AssignGuest
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to assign guest star slot (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,8 +3,11 @@ package gueststar
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type CreateGuestStarSessionResponse struct {
@ -17,9 +20,9 @@ type CreateGuestStarSessionResponse struct {
// Query parameter broadcaster_id must match the user_id in the User-Access token
// Requires OAuth Scope: channel:manage:guest_star
func (g *GuestStar) CreateGuestStarSession(ctx context.Context, broadcasterID string) (*CreateGuestStarSessionResponse, error) {
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/session", RawQuery: url.Values{"broadcaster_id": {broadcasterID}}.Encode()})
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(g.baseUrl, "guest_star/session", v), nil)
if err != nil {
return nil, err
}
@ -30,6 +33,11 @@ func (g *GuestStar) CreateGuestStarSession(ctx context.Context, broadcasterID st
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to create guest star session (%d)", res.StatusCode)
}
var data CreateGuestStarSessionResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type DeleteGuestStarInviteParams struct {
@ -29,9 +30,8 @@ type DeleteGuestStarInviteParams struct {
// Requires OAuth Scope: channel:manage:guest_star or moderator:manage:guest_star
func (g *GuestStar) DeleteGuestStarInvite(ctx context.Context, params *DeleteGuestStarInviteParams) error {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/invite", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(g.baseUrl, "guest_star/invite", v), nil)
if err != nil {
return err
}
@ -42,5 +42,10 @@ func (g *GuestStar) DeleteGuestStarInvite(ctx context.Context, params *DeleteGue
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to delete guest star invite (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type DeleteGuestStarSlotParams struct {
@ -36,9 +37,8 @@ type DeleteGuestStarSlotParams struct {
// Requires OAuth Scope: channel:manage:guest_star or moderator:manage:guest_star
func (g *GuestStar) DeleteGuestStarSlot(ctx context.Context, params *DeleteGuestStarSlotParams) error {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/slot", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(g.baseUrl, "guest_star/slot", v), nil)
if err != nil {
return err
}
@ -49,5 +49,10 @@ func (g *GuestStar) DeleteGuestStarSlot(ctx context.Context, params *DeleteGuest
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to delete guest star slot (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,10 +3,11 @@ package gueststar
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type EndGuestStarSession struct {
@ -29,9 +30,8 @@ type EndGuestStarSessionResponse struct {
// Requires OAuth Scope: channel:manage:guest_star
func (g *GuestStar) EndGuestStarSession(ctx context.Context, params *EndGuestStarSession) (*EndGuestStarSessionResponse, error) {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/session", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(g.baseUrl, "guest_star/session", v), nil)
if err != nil {
return nil, err
}
@ -42,6 +42,11 @@ func (g *GuestStar) EndGuestStarSession(ctx context.Context, params *EndGuestSta
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to end guest star session (%d)", res.StatusCode)
}
var data EndGuestStarSessionResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package gueststar
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetChannelGuestStarSettingsParams struct {
@ -28,9 +29,8 @@ type GetChannelGuestStarSettingsResponse struct {
// Requires OAuth Scope: channel:read:guest_star, channel:manage:guest_star, moderator:read:guest_star or moderator:manage:guest_star
func (g *GuestStar) GetChannelGuestStarSettings(ctx context.Context, params *GetChannelGuestStarSettingsParams) (*GetChannelGuestStarSettingsResponse, error) {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/channel_settings", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(g.baseUrl, "guest_star/channel_settings", v), nil)
if err != nil {
return nil, err
}
@ -41,6 +41,11 @@ func (g *GuestStar) GetChannelGuestStarSettings(ctx context.Context, params *Get
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get channel guest star settings (%d)", res.StatusCode)
}
var data GetChannelGuestStarSettingsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package gueststar
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetGuestStarInvitesParams struct {
@ -32,9 +33,8 @@ type GetGuestStarInvitesResponse struct {
// Requires OAuth Scope: channel:read:guest_star, channel:manage:guest_star, moderator:read:guest_star or moderator:manage:guest_star
func (g *GuestStar) GetGuestStarInvites(ctx context.Context, params *GetGuestStarInvitesParams) (*GetGuestStarInvitesResponse, error) {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/invites", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(g.baseUrl, "guest_star/invites", v), nil)
if err != nil {
return nil, err
}
@ -45,6 +45,11 @@ func (g *GuestStar) GetGuestStarInvites(ctx context.Context, params *GetGuestSta
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get guest star invites (%d)", res.StatusCode)
}
var data GetGuestStarInvitesResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package gueststar
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetGuestStarSessionParams struct {
@ -29,9 +30,8 @@ type GetGuestStarSessionResponse struct {
// Guests must be either invited or assigned a slot within the session
func (g *GuestStar) GetGuestStarSession(ctx context.Context, params *GetGuestStarSessionParams) (*GetGuestStarSessionResponse, error) {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/session", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(g.baseUrl, "guest_star/session", v), nil)
if err != nil {
return nil, err
}
@ -42,6 +42,11 @@ func (g *GuestStar) GetGuestStarSession(ctx context.Context, params *GetGuestSta
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get guest star session (%d)", res.StatusCode)
}
var data GetGuestStarSessionResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type SendGuestStarInviteParams struct {
@ -29,9 +30,8 @@ type SendGuestStarInviteParams struct {
// Requires OAuth Scope: channel:manage:guest_star or moderator:manage:guest_star
func (g *GuestStar) SendGuestStarInvite(ctx context.Context, params *SendGuestStarInviteParams) error {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/invite", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(g.baseUrl, "guest_star/invite", v), nil)
if err != nil {
return err
}
@ -42,5 +42,10 @@ func (g *GuestStar) SendGuestStarInvite(ctx context.Context, params *SendGuestSt
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to send guest star invite (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,8 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateChannelGuestStarSettingsRequest struct {
@ -38,9 +41,9 @@ type UpdateChannelGuestStarSettingsRequest struct {
// Query parameter broadcaster_id must match the user_id in the User-Access token
// Requires OAuth Scope: channel:manage:guest_star
func (g *GuestStar) UpdateChannelGuestStarSettings(ctx context.Context, BroadcasterID string, body *UpdateChannelGuestStarSettingsRequest) error {
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/channel_settings", RawQuery: url.Values{"broadcaster_id": {BroadcasterID}}.Encode()})
v := url.Values{"broadcaster_id": {BroadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.Make(g.baseUrl, "guest_star/channel_settings", v), nil)
if err != nil {
return err
}
@ -51,5 +54,10 @@ func (g *GuestStar) UpdateChannelGuestStarSettings(ctx context.Context, Broadcas
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to update channel guest star settings (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateGuestStarSlot struct {
@ -32,9 +33,8 @@ type UpdateGuestStarSlot struct {
// Requires OAuth Scope: channel:manage:guest_star or moderator:manage:guest_star
func (g *GuestStar) UpdateGuestStarSlot(ctx context.Context, params *UpdateGuestStarSlot) error {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/slot", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(g.baseUrl, "guest_star/slot", v), nil)
if err != nil {
return err
}
@ -45,5 +45,10 @@ func (g *GuestStar) UpdateGuestStarSlot(ctx context.Context, params *UpdateGuest
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to update guest star slot (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package gueststar
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateGuestStarSlotSettingsParams struct {
@ -44,9 +45,8 @@ type UpdateGuestStarSlotSettingsParams struct {
// Requires OAuth Scope: channel:manage:guest_star or moderator:manage:guest_star
func (g *GuestStar) UpdateGuestStarSlotSettings(ctx context.Context, params *UpdateGuestStarSlotSettingsParams) error {
v, _ := query.Values(params)
endpoint := g.baseUrl.ResolveReference(&url.URL{Path: "guest_star/slot_settings", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(g.baseUrl, "guest_star/slot_settings", v), nil)
if err != nil {
return err
}
@ -57,5 +57,10 @@ func (g *GuestStar) UpdateGuestStarSlotSettings(ctx context.Context, params *Upd
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to update guest star slot settings (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,11 +3,12 @@ package hypetrain
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -118,9 +119,8 @@ type GetHypeTrainEventsResponse struct {
// Requires a user access token that includes the channel:read:hype_train scope.
func (h *Hypetrain) GetHypeTrainEvents(ctx context.Context, params *GetHypeTrainEventsParams) (*GetHypeTrainEventsResponse, error) {
v, _ := query.Values(params)
endpoint := h.baseUrl.ResolveReference(&url.URL{Path: "hypetrain/events", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(h.baseUrl, "hypetrain/events", v), nil)
if err != nil {
return nil, err
}
@ -131,6 +131,11 @@ func (h *Hypetrain) GetHypeTrainEvents(ctx context.Context, params *GetHypeTrain
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get Hype Train events (%d)", res.StatusCode)
}
var data GetHypeTrainEventsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type AddBlockedTermParams struct {
@ -42,7 +43,6 @@ type AddBlockedTermResponse struct {
// Requires a user access token that includes the moderator:manage:blocked_terms scope.
func (m *Moderation) AddBlockedTerm(ctx context.Context, params *AddBlockedTermParams, body *AddBlockedTermRequest) (*AddBlockedTermResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/blocked_terms", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -54,7 +54,7 @@ func (m *Moderation) AddBlockedTerm(ctx context.Context, params *AddBlockedTermP
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(m.baseUrl, "moderation/blocked_terms", v), r)
if err != nil {
return nil, err
}
@ -65,6 +65,11 @@ func (m *Moderation) AddBlockedTerm(ctx context.Context, params *AddBlockedTermP
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to add blocked term (%d)", res.StatusCode)
}
var data AddBlockedTermResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type AddChannelModeratorParams struct {
@ -23,9 +24,8 @@ type AddChannelModeratorParams struct {
// Requires a user access token that includes the channel:manage:moderators scope.
func (m *Moderation) AddChannelModerator(ctx context.Context, params *AddChannelModeratorParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/moderators", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(m.baseUrl, "moderation/moderators", v), nil)
if err != nil {
return err
}
@ -36,5 +36,10 @@ func (m *Moderation) AddChannelModerator(ctx context.Context, params *AddChannel
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to add channel moderator (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type AddChannelVIPParams struct {
@ -23,9 +24,8 @@ type AddChannelVIPParams struct {
// Requires a user access token that includes the channel:manage:vips scope.
func (m *Moderation) AddChannelVIP(ctx context.Context, params *AddChannelVIPParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "channels/vips", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(m.baseUrl, "channels/vips", v), nil)
if err != nil {
return err
}
@ -36,5 +36,10 @@ func (m *Moderation) AddChannelVIP(ctx context.Context, params *AddChannelVIPPar
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to add channel VIP (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,12 +3,13 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type BanUserParams struct {
@ -69,7 +70,6 @@ type BanUserResponseData struct {
// Requires a user access token that includes the moderator:manage:banned_users scope.
func (m *Moderation) BanUser(ctx context.Context, params *BanUserParams, body *BanUserRequest) (*BanUserResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/bans", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -81,7 +81,7 @@ func (m *Moderation) BanUser(ctx context.Context, params *BanUserParams, body *B
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(m.baseUrl, "moderation/bans", v), r)
if err != nil {
return nil, err
}
@ -92,6 +92,11 @@ func (m *Moderation) BanUser(ctx context.Context, params *BanUserParams, body *B
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to ban user (%d)", res.StatusCode)
}
var data BanUserResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,8 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type CheckAutoModStatusRequest struct {
@ -50,20 +53,25 @@ type CheckAutoModStatusResponseData struct {
// The rate limit headers in the response represent the Twitch rate limits and not the above limits.
//
// Requires a user access token that includes the moderation:read scope.
func (c *Moderation) CheckAutoModStatus(ctx context.Context, broadcasterID string, params *CheckAutoModStatusRequest) (*CheckAutoModStatusResponse, error) {
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "modetation/enforcements/status", RawQuery: url.Values{"broadcaster_id": {broadcasterID}}.Encode()})
func (m *Moderation) CheckAutoModStatus(ctx context.Context, broadcasterID string, params *CheckAutoModStatusRequest) (*CheckAutoModStatusResponse, error) {
v := url.Values{"broadcaster_id": {broadcasterID}}
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(m.baseUrl, "moderation/enforcements/status", v), nil)
if err != nil {
return nil, err
}
res, err := c.client.Do(req)
res, err := m.client.Do(req)
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to check automod status (%d)", res.StatusCode)
}
var data CheckAutoModStatusResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type DeleteChatMessagesParams struct {
@ -33,9 +34,8 @@ type DeleteChatMessagesParams struct {
// Requires a user access token that includes the moderator:manage:chat_messages scope.
func (m *Moderation) DeleteChatMessages(ctx context.Context, params *DeleteChatMessagesParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/chat", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(m.baseUrl, "moderation/chat", v), nil)
if err != nil {
return err
}
@ -46,5 +46,10 @@ func (m *Moderation) DeleteChatMessages(ctx context.Context, params *DeleteChatM
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to delete chat messages (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,10 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetAutoModSettingsParams struct {
@ -29,9 +30,8 @@ type GetAutoModSettingsResponse struct {
// Requires a user access token that includes the moderator:read:automod_settings scope.
func (m *Moderation) GetAutoModSettings(ctx context.Context, params *GetAutoModSettingsParams) (*GetAutoModSettingsResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/automod/settings", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/automod/settings", v), nil)
if err != nil {
return nil, err
}
@ -42,6 +42,11 @@ func (m *Moderation) GetAutoModSettings(ctx context.Context, params *GetAutoModS
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get automod settings (%d)", res.StatusCode)
}
var data GetAutoModSettingsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -82,9 +83,8 @@ type GetBannedUsersResponseData struct {
// Requires a user access token that includes the moderation:read or moderator:manage:banned_users scope.
func (m *Moderation) GetBannedUsers(ctx context.Context, params *GetBannedUsersParams) (*GetBannedUsersResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/banned", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/banned", v), nil)
if err != nil {
return nil, err
}
@ -95,6 +95,11 @@ func (m *Moderation) GetBannedUsers(ctx context.Context, params *GetBannedUsersP
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get banned users (%d)", res.StatusCode)
}
var data GetBannedUsersResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -43,9 +44,8 @@ type GetBlockedTermsResponse struct {
// Requires a user access token that includes the moderator:read:blocked_terms or moderator:manage:blocked_terms scope.
func (m *Moderation) GetBlockedTerms(ctx context.Context, params *GetBlockedTermsParams) (*GetBlockedTermsResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/blocked_terms", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/blocked_terms", v), nil)
if err != nil {
return nil, err
}
@ -56,6 +56,11 @@ func (m *Moderation) GetBlockedTerms(ctx context.Context, params *GetBlockedTerm
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get blocked terms (%d)", res.StatusCode)
}
var data GetBlockedTermsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -50,9 +51,8 @@ type GetModeratedChannelsResponseData struct {
// Requires OAuth Scope: user:read:moderated_channels
func (m *Moderation) GetModeratedChannels(ctx context.Context, params *GetModeratedChannelsParams) (*GetModeratedChannelsResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/channels", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/channels", v), nil)
if err != nil {
return nil, err
}
@ -63,6 +63,11 @@ func (m *Moderation) GetModeratedChannels(ctx context.Context, params *GetModera
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get moderated channels (%d)", res.StatusCode)
}
var data GetModeratedChannelsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -60,9 +61,8 @@ type GetModeratorsResponseData struct {
// If your app also adds and removes moderators, you can use the channel:manage:moderators scope instead.
func (m *Moderation) GetModerators(ctx context.Context, params *GetModeratorsParams) (*GetModeratorsResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/moderators", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/moderators", v), nil)
if err != nil {
return nil, err
}
@ -73,6 +73,11 @@ func (m *Moderation) GetModerators(ctx context.Context, params *GetModeratorsPar
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get moderators (%d)", res.StatusCode)
}
var data GetModeratorsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type GetShieldModeStatusParams struct {
@ -30,9 +31,8 @@ type GetShieldModeStatusResponse struct {
// Requires a user access token that includes the moderator:read:shield_mode or moderator:manage:shield_mode scope.
func (m *Moderation) GetShieldModeStatus(ctx context.Context, params *GetShieldModeStatusParams) (*GetShieldModeStatusResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/shield_mode", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/shield_mode", v), nil)
if err != nil {
return nil, err
}
@ -43,6 +43,11 @@ func (m *Moderation) GetShieldModeStatus(ctx context.Context, params *GetShieldM
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get shield mode status (%d)", res.StatusCode)
}
var data GetShieldModeStatusResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,10 +3,11 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
"go.fifitido.net/twitch/api/types"
)
@ -58,9 +59,8 @@ type GetVIPsResponseData struct {
// If your app also adds and removes VIP status, you can use the channel:manage:vips scope instead.
func (m *Moderation) GetVIPs(ctx context.Context, params GetVIPsParams) (*GetVIPsResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/vips", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.Make(m.baseUrl, "moderation/vips", v), nil)
if err != nil {
return nil, err
}
@ -69,6 +69,12 @@ func (m *Moderation) GetVIPs(ctx context.Context, params GetVIPsParams) (*GetVIP
if err != nil {
return nil, err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to get VIPs (%d)", res.StatusCode)
}
var data GetVIPsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {

View File

@ -2,8 +2,10 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type AutoModAction string
@ -32,9 +34,8 @@ type ManageHeldAutoModMessagesRequest struct {
//
// Requires a user access token that includes the moderator:manage:automod scope.
func (m *Moderation) ManageHeldAutoModMessages(ctx context.Context, body *ManageHeldAutoModMessagesRequest) error {
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/automod/message"})
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(m.baseUrl, "moderation/automod/message"), nil)
if err != nil {
return err
}
@ -45,5 +46,10 @@ func (m *Moderation) ManageHeldAutoModMessages(ctx context.Context, body *Manage
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to manage held AutoMod messages (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type RemoveBlockedTermParams struct {
@ -25,9 +26,8 @@ type RemoveBlockedTermParams struct {
// Requires a user access token that includes the moderator:manage:blocked_terms scope.
func (m *Moderation) RemoveBlockedTerm(ctx context.Context, params *RemoveBlockedTermParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/blocks", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(m.baseUrl, "moderation/blocks", v), nil)
if err != nil {
return err
}
@ -38,5 +38,10 @@ func (m *Moderation) RemoveBlockedTerm(ctx context.Context, params *RemoveBlocke
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to remove blocked term (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type RemoveChannelModeratorParams struct {
@ -23,9 +24,8 @@ type RemoveChannelModeratorParams struct {
// Requires a user access token that includes the channel:manage:moderators scope.
func (m *Moderation) RemoveChannelModerator(ctx context.Context, params *RemoveChannelModeratorParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/moderators", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(m.baseUrl, "moderation/moderators", v), nil)
if err != nil {
return err
}
@ -36,5 +36,10 @@ func (m *Moderation) RemoveChannelModerator(ctx context.Context, params *RemoveC
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to remove channel moderator (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type RemoveChannelVIPParams struct {
@ -26,9 +27,8 @@ type RemoveChannelVIPParams struct {
// Requires a user access token that includes the channel:manage:vips scope.
func (m *Moderation) RemoveChannelVIP(ctx context.Context, params *RemoveChannelVIPParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "channels/vips", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(m.baseUrl, "channels/vips", v), nil)
if err != nil {
return err
}
@ -39,5 +39,10 @@ func (m *Moderation) RemoveChannelVIP(ctx context.Context, params *RemoveChannel
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to remove channel VIP (%d)", res.StatusCode)
}
return nil
}

View File

@ -2,10 +2,11 @@ package moderation
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UnbanUserParams struct {
@ -27,9 +28,8 @@ type UnbanUserParams struct {
// Requires a user access token that includes the moderator:manage:banned_users scope.
func (m *Moderation) UnbanUser(ctx context.Context, params *UnbanUserParams) error {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/bans", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.Make(m.baseUrl, "moderation/bans", v), nil)
if err != nil {
return err
}
@ -40,5 +40,10 @@ func (m *Moderation) UnbanUser(ctx context.Context, params *UnbanUserParams) err
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to unban user (%d)", res.StatusCode)
}
return nil
}

View File

@ -3,11 +3,12 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateAutoModSettingsParams struct {
@ -78,7 +79,6 @@ type UpdateAutoModSettingsResponse struct {
// Requires a user access token that includes the moderator:manage:automod_settings scope.
func (m *Moderation) UpdateAutoModSettings(ctx context.Context, params *UpdateAutoModSettingsParams, body *UpdateAutoModSettingsRequest) (*UpdateAutoModSettingsResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/automod/settings", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -90,7 +90,7 @@ func (m *Moderation) UpdateAutoModSettings(ctx context.Context, params *UpdateAu
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.Make(m.baseUrl, "moderation/automod/settings", v), r)
if err != nil {
return nil, err
}
@ -101,6 +101,11 @@ func (m *Moderation) UpdateAutoModSettings(ctx context.Context, params *UpdateAu
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update automod settings (%d)", res.StatusCode)
}
var data UpdateAutoModSettingsResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,11 +3,12 @@ package moderation
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type UpdateShieldModeStatusParams struct {
@ -37,7 +38,6 @@ type UpdateShieldModeStatusResponse struct {
// Requires a user access token that includes the moderator:manage:shield_mode scope.
func (m *Moderation) UpdateShieldModeStatus(ctx context.Context, params *UpdateShieldModeStatusParams) (*UpdateShieldModeStatusResponse, error) {
v, _ := query.Values(params)
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/shield_mode", RawQuery: v.Encode()})
r, w := io.Pipe()
@ -49,7 +49,7 @@ func (m *Moderation) UpdateShieldModeStatus(ctx context.Context, params *UpdateS
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(m.baseUrl, "moderation/shield_mode", v), r)
if err != nil {
return nil, err
}
@ -60,6 +60,11 @@ func (m *Moderation) UpdateShieldModeStatus(ctx context.Context, params *UpdateS
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to update shield mode status (%d)", res.StatusCode)
}
var data UpdateShieldModeStatusResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -3,9 +3,11 @@ package polls
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"go.fifitido.net/twitch/api/endpoint"
)
type CreatePollRequest struct {
@ -48,8 +50,6 @@ type CreatePollResponse struct {
//
// Requires a user access token that includes the channel:manage:polls scope.
func (p *Polls) CreatePoll(ctx context.Context, body *CreatePollRequest) (*CreatePollResponse, error) {
endpoint := p.baseUrl.ResolveReference(&url.URL{Path: "polls"})
r, w := io.Pipe()
go func() {
@ -60,7 +60,7 @@ func (p *Polls) CreatePoll(ctx context.Context, body *CreatePollRequest) (*Creat
}
}()
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.Make(p.baseUrl, "polls"), r)
if err != nil {
return nil, err
}
@ -71,6 +71,11 @@ func (p *Polls) CreatePoll(ctx context.Context, body *CreatePollRequest) (*Creat
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return nil, fmt.Errorf("failed to create poll (%d)", res.StatusCode)
}
var data CreatePollResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return nil, err

View File

@ -2,10 +2,11 @@ package polls
import (
"context"
"fmt"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
"go.fifitido.net/twitch/api/endpoint"
)
type EndPollParams struct {
@ -29,9 +30,8 @@ type EndPollParams struct {
// Requires a user access token that includes the channel:manage:polls scope.
func (p *Polls) EndPoll(ctx context.Context, params *EndPollParams) error {
v, _ := query.Values(params)
endpoint := p.baseUrl.ResolveReference(&url.URL{Path: "polls", RawQuery: v.Encode()})
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), nil)
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.Make(p.baseUrl, "polls", v), nil)
if err != nil {
return err
}
@ -42,5 +42,10 @@ func (p *Polls) EndPoll(ctx context.Context, params *EndPollParams) error {
}
defer res.Body.Close()
statusOK := res.StatusCode >= 200 && res.StatusCode < 300
if !statusOK {
return fmt.Errorf("failed to end poll (%d)", res.StatusCode)
}
return nil
}

Some files were not shown because too many files have changed in this diff Show More