@@ -32,17 +32,17 @@ public class TwitchApiProxy : ITwitchApiProxy {
32
32
/// <summary>
33
33
/// The, public, twitch client id.
34
34
/// </summary>
35
- private static readonly string ClientId = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_ID" ) ! ;
35
+ protected readonly string ? _clientId ;
36
36
37
37
/// <summary>
38
38
/// The, private, twitch client secret.
39
39
/// </summary>
40
- private static readonly string ClientSecret = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_SECRET" ) ! ;
40
+ protected readonly string ? _clientSecret ;
41
41
42
42
/// <summary>
43
43
/// The redirect url.
44
44
/// </summary>
45
- private static readonly string ClientRedirect = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_REDIRECT" ) ! ;
45
+ protected readonly string ? _clientRedirect ;
46
46
47
47
/// <summary>
48
48
/// Initializes a new instance of the <see cref="TwitchApiProxy" /> class.
@@ -56,7 +56,18 @@ public TwitchApiProxy() {
56
56
/// <param name="token">The access token.</param>
57
57
/// <param name="refreshToken">The refresh token.</param>
58
58
/// <param name="tokenExpires">When the token expires (utc).</param>
59
- public TwitchApiProxy ( string token , string refreshToken , DateTime tokenExpires ) {
59
+ /// <param name="clientId">The client id of the registered twitch app, uses environment variable
60
+ /// "TWITCH_BOT_CLIENT_ID" when null.</param>
61
+ /// <param name="clientSecret">The client secret of the registered twitch app, uses environment variable
62
+ /// "TWITCH_BOT_CLIENT_SECRET" when null.</param>
63
+ /// <param name="clientRedirect">The url to redirect to from the registered twitch app, uses environment variable
64
+ /// "TWITCH_BOT_CLIENT_REDIRECT" when null.</param>
65
+ public TwitchApiProxy ( string token , string refreshToken , DateTime tokenExpires , string ? clientId = null ,
66
+ string ? clientSecret = null , string ? clientRedirect = null ) {
67
+ _clientId = clientId ?? Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_ID" ) ;
68
+ _clientSecret = clientSecret ?? Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_SECRET" ) ;
69
+ _clientRedirect = clientRedirect ?? Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_REDIRECT" ) ;
70
+
60
71
OAuth = new TwitchAccessToken {
61
72
AccessToken = token ,
62
73
RefreshToken = refreshToken ,
@@ -73,9 +84,9 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
73
84
public TwitchAccessToken ? OAuth { get ; set ; }
74
85
75
86
/// <inheritdoc />
76
- public async Task < TwitchAccessToken ? > CreateAccessToken ( string code , CancellationToken token = new ( ) ) {
87
+ public virtual async Task < TwitchAccessToken ? > CreateAccessToken ( string code , CancellationToken token = new ( ) ) {
77
88
ITwitchAPI api = GetApi ( ) ;
78
- AuthCodeResponse ? response = await api . Auth . GetAccessTokenFromCodeAsync ( code , ClientSecret , ClientRedirect ) ;
89
+ AuthCodeResponse ? response = await api . Auth . GetAccessTokenFromCodeAsync ( code , _clientSecret , _clientRedirect ) ;
79
90
if ( null == response ) {
80
91
return null ;
81
92
}
@@ -89,10 +100,14 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
89
100
}
90
101
91
102
/// <inheritdoc />
92
- public async Task < TwitchAccessToken ? > RefreshAccessToken ( CancellationToken token = new ( ) ) {
103
+ public virtual async Task < TwitchAccessToken ? > RefreshAccessToken ( CancellationToken token = new ( ) ) {
93
104
try {
105
+ if ( string . IsNullOrWhiteSpace ( _clientSecret ) || string . IsNullOrWhiteSpace ( _clientId ) ) {
106
+ return null ;
107
+ }
108
+
94
109
ITwitchAPI api = GetApi ( ) ;
95
- RefreshResponse ? response = await api . Auth . RefreshAuthTokenAsync ( OAuth ? . RefreshToken , ClientSecret , ClientId ) ;
110
+ RefreshResponse ? response = await api . Auth . RefreshAuthTokenAsync ( OAuth ? . RefreshToken , _clientSecret , _clientId ) ;
96
111
if ( null == response ) {
97
112
return null ;
98
113
}
@@ -111,11 +126,16 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
111
126
112
127
/// <inheritdoc />
113
128
public async Task < bool > GetAccessTokenIsValid ( CancellationToken token = new ( ) ) {
114
- return ! string . IsNullOrWhiteSpace ( ( await GetUser ( token ) ) . id ) ;
129
+ try {
130
+ return ! string . IsNullOrWhiteSpace ( ( await GetUser ( token ) ) . id ) ;
131
+ }
132
+ catch {
133
+ return false ;
134
+ }
115
135
}
116
136
117
137
/// <inheritdoc />
118
- public async Task < ( string ? id , string ? username ) > GetUser ( CancellationToken token = new ( ) ) {
138
+ public virtual async Task < ( string ? id , string ? username ) > GetUser ( CancellationToken token = new ( ) ) {
119
139
return await Retry . Execute ( async ( ) => {
120
140
ITwitchAPI api = GetApi ( ) ;
121
141
GetUsersResponse ? response = await api . Helix . Users . GetUsersAsync ( ) ;
@@ -129,7 +149,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
129
149
}
130
150
131
151
/// <inheritdoc />
132
- public async Task < string ? > GetUserEmail ( CancellationToken token = new ( ) ) {
152
+ public virtual async Task < string ? > GetUserEmail ( CancellationToken token = new ( ) ) {
133
153
return await Retry . Execute ( async ( ) => {
134
154
ITwitchAPI api = GetApi ( ) ;
135
155
GetUsersResponse ? response = await api . Helix . Users . GetUsersAsync ( ) ;
@@ -142,7 +162,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
142
162
}
143
163
144
164
/// <inheritdoc />
145
- public async Task < IEnumerable < TwitchModeratedChannel > > GetUserModChannels ( string userId ) {
165
+ public virtual async Task < IEnumerable < TwitchModeratedChannel > > GetUserModChannels ( string userId ) {
146
166
using var client = new HttpClient ( ) ;
147
167
148
168
var ret = new List < TwitchModeratedChannel > ( ) ;
@@ -155,7 +175,7 @@ public async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string
155
175
156
176
var request = new HttpRequestMessage ( HttpMethod . Get , url ) ;
157
177
request . Headers . Add ( "Authorization" , $ "Bearer { OAuth ? . AccessToken } ") ;
158
- request . Headers . Add ( "Client-Id" , ClientId ) ;
178
+ request . Headers . Add ( "Client-Id" , _clientId ) ;
159
179
160
180
using HttpResponseMessage response = await client . SendAsync ( request ) ;
161
181
response . EnsureSuccessStatusCode ( ) ;
@@ -173,7 +193,7 @@ public async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string
173
193
}
174
194
175
195
/// <inheritdoc />
176
- public async Task < IEnumerable < BannedUser > > BanChannelUsers ( string channelId , string botId ,
196
+ public virtual async Task < IEnumerable < BannedUser > > BanChannelUsers ( string channelId , string botId ,
177
197
IEnumerable < ( string Id , string Username ) > users , string reason , CancellationToken token = new ( ) ) {
178
198
return await Retry . Execute ( async ( ) => {
179
199
ITwitchAPI api = GetApi ( ) ;
@@ -207,7 +227,7 @@ public async Task<IEnumerable<BannedUser>> BanChannelUsers(string channelId, str
207
227
}
208
228
209
229
/// <inheritdoc />
210
- public async Task < IEnumerable < Chatter > > GetChannelUsers ( string channelId , string botId ,
230
+ public virtual async Task < IEnumerable < Chatter > > GetChannelUsers ( string channelId , string botId ,
211
231
CancellationToken token = new ( ) ) {
212
232
return await Retry . Execute ( async ( ) => {
213
233
ITwitchAPI api = GetApi ( ) ;
@@ -231,7 +251,7 @@ public async Task<IEnumerable<Chatter>> GetChannelUsers(string channelId, string
231
251
}
232
252
233
253
/// <inheritdoc />
234
- public async Task < IEnumerable < string > > GetChannelsLive ( IEnumerable < string > userIds ) {
254
+ public virtual async Task < IEnumerable < string > > GetChannelsLive ( IEnumerable < string > userIds ) {
235
255
ITwitchAPI api = GetApi ( ) ;
236
256
237
257
// We can only query 100 at a time, so throttle the search.
@@ -255,7 +275,7 @@ public async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userI
255
275
}
256
276
257
277
/// <inheritdoc />
258
- public async Task < IEnumerable < Moderator > > GetChannelMods ( string channelId , CancellationToken token = new ( ) ) {
278
+ public virtual async Task < IEnumerable < Moderator > > GetChannelMods ( string channelId , CancellationToken token = new ( ) ) {
259
279
return await Retry . Execute ( async ( ) => {
260
280
ITwitchAPI api = GetApi ( ) ;
261
281
@@ -282,7 +302,7 @@ public async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userI
282
302
}
283
303
284
304
/// <inheritdoc />
285
- public async Task < bool > AddChannelMod ( string channelId , string userId , CancellationToken token = new ( ) ) {
305
+ public virtual async Task < bool > AddChannelMod ( string channelId , string userId , CancellationToken token = new ( ) ) {
286
306
return await Retry . Execute ( async ( ) => {
287
307
ITwitchAPI api = GetApi ( ) ;
288
308
await api . Helix . Moderation . AddChannelModeratorAsync ( channelId , userId ) ;
@@ -294,10 +314,10 @@ public async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userI
294
314
/// Gets a new instance of the <see cref="TwitchAPI" />.
295
315
/// </summary>
296
316
/// <returns>A new instance of the <see cref="TwitchAPI" />.</returns>
297
- protected ITwitchAPI GetApi ( ) {
317
+ protected virtual ITwitchAPI GetApi ( ) {
298
318
var api = new TwitchAPI {
299
319
Settings = {
300
- ClientId = ClientId ,
320
+ ClientId = _clientId ,
301
321
AccessToken = OAuth ? . AccessToken
302
322
}
303
323
} ;
0 commit comments