@@ -29,25 +29,15 @@ public class TwitchApiProxy : ITwitchApiProxy {
29
29
/// </summary>
30
30
private static readonly ILog Log = LogManager . GetLogger ( typeof ( TwitchApiProxy ) ) ;
31
31
32
- /// <summary>
33
- /// The, public, twitch client id.
34
- /// </summary>
35
- private static readonly string ClientId = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_ID" ) ! ;
36
-
37
- /// <summary>
38
- /// The, private, twitch client secret.
39
- /// </summary>
40
- private static readonly string ClientSecret = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_SECRET" ) ! ;
41
-
42
- /// <summary>
43
- /// The redirect url.
44
- /// </summary>
45
- private static readonly string ClientRedirect = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_REDIRECT" ) ! ;
46
-
47
32
/// <summary>
48
33
/// Initializes a new instance of the <see cref="TwitchApiProxy" /> class.
49
34
/// </summary>
50
35
public TwitchApiProxy ( ) {
36
+ TwitchAppConfig = new ( ) {
37
+ ClientId = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_ID" ) ,
38
+ ClientSecret = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_SECRET" ) ,
39
+ ClientRedirect = Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_REDIRECT" )
40
+ } ;
51
41
}
52
42
53
43
/// <summary>
@@ -56,12 +46,25 @@ public TwitchApiProxy() {
56
46
/// <param name="token">The access token.</param>
57
47
/// <param name="refreshToken">The refresh token.</param>
58
48
/// <param name="tokenExpires">When the token expires (utc).</param>
59
- public TwitchApiProxy ( string token , string refreshToken , DateTime tokenExpires ) {
49
+ /// <param name="clientId">The client id of the registered twitch app, uses environment variable
50
+ /// "TWITCH_BOT_CLIENT_ID" when null.</param>
51
+ /// <param name="clientSecret">The client secret of the registered twitch app, uses environment variable
52
+ /// "TWITCH_BOT_CLIENT_SECRET" when null.</param>
53
+ /// <param name="clientRedirect">The url to redirect to from the registered twitch app, uses environment variable
54
+ /// "TWITCH_BOT_CLIENT_REDIRECT" when null.</param>
55
+ public TwitchApiProxy ( string token , string refreshToken , DateTime tokenExpires , string ? clientId = null ,
56
+ string ? clientSecret = null , string ? clientRedirect = null ) {
60
57
OAuth = new TwitchAccessToken {
61
58
AccessToken = token ,
62
59
RefreshToken = refreshToken ,
63
60
ExpiresUtc = tokenExpires
64
61
} ;
62
+
63
+ TwitchAppConfig = new ( ) {
64
+ ClientId = clientId ?? Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_ID" ) ,
65
+ ClientSecret = clientSecret ?? Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_SECRET" ) ,
66
+ ClientRedirect = clientRedirect ?? Environment . GetEnvironmentVariable ( "TWITCH_BOT_CLIENT_REDIRECT" )
67
+ } ;
65
68
}
66
69
67
70
/// <summary>
@@ -70,12 +73,16 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
70
73
public int Retries { get ; set ; } = 3 ;
71
74
72
75
/// <inheritdoc />
73
- public TwitchAccessToken ? OAuth { get ; set ; }
76
+ public virtual TwitchAccessToken ? OAuth { get ; set ; }
77
+
78
+ /// <inheritdoc />
79
+ public virtual TwitchAppConfig ? TwitchAppConfig { get ; set ; }
74
80
75
81
/// <inheritdoc />
76
- public async Task < TwitchAccessToken ? > CreateAccessToken ( string code , CancellationToken token = new ( ) ) {
82
+ public virtual async Task < TwitchAccessToken ? > CreateAccessToken ( string code , CancellationToken token = new ( ) ) {
77
83
ITwitchAPI api = GetApi ( ) ;
78
- AuthCodeResponse ? response = await api . Auth . GetAccessTokenFromCodeAsync ( code , ClientSecret , ClientRedirect ) ;
84
+ AuthCodeResponse ? response = await api . Auth . GetAccessTokenFromCodeAsync ( code , TwitchAppConfig ? . ClientSecret ,
85
+ TwitchAppConfig ? . ClientRedirect ) ;
79
86
if ( null == response ) {
80
87
return null ;
81
88
}
@@ -89,10 +96,14 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
89
96
}
90
97
91
98
/// <inheritdoc />
92
- public async Task < TwitchAccessToken ? > RefreshAccessToken ( CancellationToken token = new ( ) ) {
99
+ public virtual async Task < TwitchAccessToken ? > RefreshAccessToken ( CancellationToken token = new ( ) ) {
93
100
try {
101
+ if ( string . IsNullOrWhiteSpace ( TwitchAppConfig ? . ClientSecret ) || string . IsNullOrWhiteSpace ( TwitchAppConfig ? . ClientId ) ) {
102
+ return null ;
103
+ }
104
+
94
105
ITwitchAPI api = GetApi ( ) ;
95
- RefreshResponse ? response = await api . Auth . RefreshAuthTokenAsync ( OAuth ? . RefreshToken , ClientSecret , ClientId ) ;
106
+ RefreshResponse ? response = await api . Auth . RefreshAuthTokenAsync ( OAuth ? . RefreshToken , TwitchAppConfig ? . ClientSecret , TwitchAppConfig ? . ClientId ) ;
96
107
if ( null == response ) {
97
108
return null ;
98
109
}
@@ -111,11 +122,16 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
111
122
112
123
/// <inheritdoc />
113
124
public async Task < bool > GetAccessTokenIsValid ( CancellationToken token = new ( ) ) {
114
- return ! string . IsNullOrWhiteSpace ( ( await GetUser ( token ) ) . id ) ;
125
+ try {
126
+ return ! string . IsNullOrWhiteSpace ( ( await GetUser ( token ) ) . id ) ;
127
+ }
128
+ catch {
129
+ return false ;
130
+ }
115
131
}
116
132
117
133
/// <inheritdoc />
118
- public async Task < ( string ? id , string ? username ) > GetUser ( CancellationToken token = new ( ) ) {
134
+ public virtual async Task < ( string ? id , string ? username ) > GetUser ( CancellationToken token = new ( ) ) {
119
135
return await Retry . Execute ( async ( ) => {
120
136
ITwitchAPI api = GetApi ( ) ;
121
137
GetUsersResponse ? response = await api . Helix . Users . GetUsersAsync ( ) ;
@@ -129,7 +145,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
129
145
}
130
146
131
147
/// <inheritdoc />
132
- public async Task < string ? > GetUserEmail ( CancellationToken token = new ( ) ) {
148
+ public virtual async Task < string ? > GetUserEmail ( CancellationToken token = new ( ) ) {
133
149
return await Retry . Execute ( async ( ) => {
134
150
ITwitchAPI api = GetApi ( ) ;
135
151
GetUsersResponse ? response = await api . Helix . Users . GetUsersAsync ( ) ;
@@ -142,7 +158,7 @@ public TwitchApiProxy(string token, string refreshToken, DateTime tokenExpires)
142
158
}
143
159
144
160
/// <inheritdoc />
145
- public async Task < IEnumerable < TwitchModeratedChannel > > GetUserModChannels ( string userId ) {
161
+ public virtual async Task < IEnumerable < TwitchModeratedChannel > > GetUserModChannels ( string userId ) {
146
162
using var client = new HttpClient ( ) ;
147
163
148
164
var ret = new List < TwitchModeratedChannel > ( ) ;
@@ -155,7 +171,7 @@ public async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string
155
171
156
172
var request = new HttpRequestMessage ( HttpMethod . Get , url ) ;
157
173
request . Headers . Add ( "Authorization" , $ "Bearer { OAuth ? . AccessToken } ") ;
158
- request . Headers . Add ( "Client-Id" , ClientId ) ;
174
+ request . Headers . Add ( "Client-Id" , TwitchAppConfig ? . ClientId ) ;
159
175
160
176
using HttpResponseMessage response = await client . SendAsync ( request ) ;
161
177
response . EnsureSuccessStatusCode ( ) ;
@@ -173,7 +189,7 @@ public async Task<IEnumerable<TwitchModeratedChannel>> GetUserModChannels(string
173
189
}
174
190
175
191
/// <inheritdoc />
176
- public async Task < IEnumerable < BannedUser > > BanChannelUsers ( string channelId , string botId ,
192
+ public virtual async Task < IEnumerable < BannedUser > > BanChannelUsers ( string channelId , string botId ,
177
193
IEnumerable < ( string Id , string Username ) > users , string reason , CancellationToken token = new ( ) ) {
178
194
return await Retry . Execute ( async ( ) => {
179
195
ITwitchAPI api = GetApi ( ) ;
@@ -207,7 +223,7 @@ public async Task<IEnumerable<BannedUser>> BanChannelUsers(string channelId, str
207
223
}
208
224
209
225
/// <inheritdoc />
210
- public async Task < IEnumerable < Chatter > > GetChannelUsers ( string channelId , string botId ,
226
+ public virtual async Task < IEnumerable < Chatter > > GetChannelUsers ( string channelId , string botId ,
211
227
CancellationToken token = new ( ) ) {
212
228
return await Retry . Execute ( async ( ) => {
213
229
ITwitchAPI api = GetApi ( ) ;
@@ -231,7 +247,7 @@ public async Task<IEnumerable<Chatter>> GetChannelUsers(string channelId, string
231
247
}
232
248
233
249
/// <inheritdoc />
234
- public async Task < IEnumerable < string > > GetChannelsLive ( IEnumerable < string > userIds ) {
250
+ public virtual async Task < IEnumerable < string > > GetChannelsLive ( IEnumerable < string > userIds ) {
235
251
ITwitchAPI api = GetApi ( ) ;
236
252
237
253
// We can only query 100 at a time, so throttle the search.
@@ -255,7 +271,7 @@ public async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userI
255
271
}
256
272
257
273
/// <inheritdoc />
258
- public async Task < IEnumerable < Moderator > > GetChannelMods ( string channelId , CancellationToken token = new ( ) ) {
274
+ public virtual async Task < IEnumerable < Moderator > > GetChannelMods ( string channelId , CancellationToken token = new ( ) ) {
259
275
return await Retry . Execute ( async ( ) => {
260
276
ITwitchAPI api = GetApi ( ) ;
261
277
@@ -282,7 +298,7 @@ public async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userI
282
298
}
283
299
284
300
/// <inheritdoc />
285
- public async Task < bool > AddChannelMod ( string channelId , string userId , CancellationToken token = new ( ) ) {
301
+ public virtual async Task < bool > AddChannelMod ( string channelId , string userId , CancellationToken token = new ( ) ) {
286
302
return await Retry . Execute ( async ( ) => {
287
303
ITwitchAPI api = GetApi ( ) ;
288
304
await api . Helix . Moderation . AddChannelModeratorAsync ( channelId , userId ) ;
@@ -294,10 +310,10 @@ public async Task<IEnumerable<string>> GetChannelsLive(IEnumerable<string> userI
294
310
/// Gets a new instance of the <see cref="TwitchAPI" />.
295
311
/// </summary>
296
312
/// <returns>A new instance of the <see cref="TwitchAPI" />.</returns>
297
- protected ITwitchAPI GetApi ( ) {
313
+ protected virtual ITwitchAPI GetApi ( ) {
298
314
var api = new TwitchAPI {
299
315
Settings = {
300
- ClientId = ClientId ,
316
+ ClientId = TwitchAppConfig ? . ClientId ,
301
317
AccessToken = OAuth ? . AccessToken
302
318
}
303
319
} ;
0 commit comments