final
This commit is contained in:
parent
09c69bcd19
commit
f56176fafb
157
Httpd.cs
Normal file
157
Httpd.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
namespace twitcher
|
||||||
|
{
|
||||||
|
public class Httpd
|
||||||
|
{
|
||||||
|
public class ResponseSet
|
||||||
|
{
|
||||||
|
public string Text { get; set; } = ":)";
|
||||||
|
public HttpStatusCode statusCode { get; set; } = HttpStatusCode.OK;
|
||||||
|
}
|
||||||
|
public delegate ResponseSet RequestHandler(HttpListenerRequest request);
|
||||||
|
private Dictionary<string, RequestHandler> psuedoResources = new Dictionary<string, RequestHandler>();
|
||||||
|
private HttpListener server;
|
||||||
|
public Httpd(int port)
|
||||||
|
{
|
||||||
|
server = new HttpListener();
|
||||||
|
server.Prefixes.Add($"http://*:{port}/");
|
||||||
|
server.Start();
|
||||||
|
}
|
||||||
|
public void HandleEndpoint(string destination, RequestHandler handler)
|
||||||
|
{
|
||||||
|
lock (psuedoResources)
|
||||||
|
{
|
||||||
|
psuedoResources[destination] = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void UnhandleEndpoint(string destination, RequestHandler handler)
|
||||||
|
{
|
||||||
|
lock (psuedoResources)
|
||||||
|
{
|
||||||
|
psuedoResources.Remove(destination);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public async Task go()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
HttpListenerContext context = await server.GetContextAsync();
|
||||||
|
HttpListenerResponse response = context.Response;
|
||||||
|
|
||||||
|
string page = context.Request.Url.LocalPath.Substring(1);
|
||||||
|
var resp = "no resource";
|
||||||
|
response.StatusCode = (int)HttpStatusCode.NotFound;
|
||||||
|
lock (psuedoResources)
|
||||||
|
{
|
||||||
|
if (psuedoResources.ContainsKey(page))
|
||||||
|
{
|
||||||
|
string responseText;
|
||||||
|
int responseCode;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var responseSet = psuedoResources[page](context.Request);
|
||||||
|
responseText = responseSet.Text;
|
||||||
|
responseCode = (int)responseSet.statusCode;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
responseText = ":(";
|
||||||
|
Console.Error.WriteLine(JsonConvert.SerializeObject(e));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.StatusCode != (int)HttpStatusCode.OK)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"returning status code {response.StatusCode}");
|
||||||
|
}
|
||||||
|
byte[] buffer = Encoding.UTF8.GetBytes(resp);
|
||||||
|
response.ContentLength64 = buffer.Length;
|
||||||
|
Stream st = response.OutputStream;
|
||||||
|
st.Write(buffer, 0, buffer.Length);
|
||||||
|
response.Close();
|
||||||
|
}
|
||||||
|
// if (page == "twitcherize")
|
||||||
|
// {
|
||||||
|
// byte[] rawIncomingBytes = new byte[context.Request.ContentLength64];
|
||||||
|
// var readBytes = context.Request.InputStream.Read(rawIncomingBytes, 0, (int)context.Request.ContentLength64);
|
||||||
|
|
||||||
|
|
||||||
|
// if (VerifySignature(context.Request.Headers["Twitch-Eventsub-Message-Signature"],
|
||||||
|
// context.Request.ContentEncoding,
|
||||||
|
// context.Request.Headers["Twitch-Eventsub-Message-Id"],
|
||||||
|
// context.Request.Headers["Twitch-Eventsub-Message-Timestamp"],
|
||||||
|
// rawIncomingBytes))
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (twitchogrambuffer.Contains(context.Request.Headers["Twitch-Eventsub-Message-Id"]))
|
||||||
|
// {
|
||||||
|
// Console.WriteLine("duplicate message received. Ignoring.");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// var incomingText = context.Request.ContentEncoding.GetString(rawIncomingBytes);
|
||||||
|
// //Console.WriteLine($"{context.Request.Headers["Twitch-Eventsub-Message-Id"]} looks new to me.");
|
||||||
|
// lock (twitchogrambuffer)
|
||||||
|
// {
|
||||||
|
// var fromTwitch = SubscribableTypesTranslation.RefineTwitchogram(incomingText);
|
||||||
|
// if (fromTwitch.challenge != null)
|
||||||
|
// {
|
||||||
|
// resp = fromTwitch.challenge;
|
||||||
|
// Console.WriteLine("challenge responded to, should be subscribed");
|
||||||
|
// }
|
||||||
|
// else if (fromTwitch.subscription.status == "authorization_revoked")
|
||||||
|
// {
|
||||||
|
// resp = "ok... :(";
|
||||||
|
// Console.WriteLine($"auth revoked for {fromTwitch.subscription.type} ({fromTwitch.subscription.id})");
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// var foundAHandler = false;
|
||||||
|
// foreach (var kvp in psuedoResources)
|
||||||
|
// {
|
||||||
|
// if (kvp.Key.id == fromTwitch.subscription.id)
|
||||||
|
// {
|
||||||
|
// kvp.Value(fromTwitch);
|
||||||
|
// resp = ":)";
|
||||||
|
// foundAHandler = true;
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (!foundAHandler)
|
||||||
|
// {
|
||||||
|
// Console.WriteLine($"I don't have a handler for {fromTwitch.subscription.type} ({fromTwitch.subscription.id})? o_O");
|
||||||
|
// resp = ":S";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// tasksToNotActuallyAwait.Add(logMessageId(context.Request.Headers["Twitch-Eventsub-Message-Id"]));
|
||||||
|
// response.StatusCode = (int)HttpStatusCode.OK;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception e)
|
||||||
|
// {
|
||||||
|
// Console.Error.WriteLine("something went wrong calling resource.");
|
||||||
|
// Console.Error.WriteLine(JsonConvert.SerializeObject(e));
|
||||||
|
// response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||||
|
// resp = "error :(";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// Console.WriteLine("couldn't verify signature.");
|
||||||
|
// response.StatusCode = (int)HttpStatusCode.Forbidden;
|
||||||
|
// resp = "VoteNay";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,40 +1,71 @@
|
|||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
public class OAuthTokenGetter
|
namespace twitcher
|
||||||
{
|
{
|
||||||
public static OAuthToken DoIt(HttpClient client, string clientId, string clientSecret, string[] scopes = null)
|
public class OAuthTokenGetter
|
||||||
{
|
{
|
||||||
var scopeString = "";
|
private static readonly AutoResetEvent _signal = new AutoResetEvent(false);
|
||||||
if (scopes != null && scopes.Length > 0)
|
public static string GetUser(Httpd server, string clientId, string redirectUri)
|
||||||
{
|
{
|
||||||
scopeString = "&scope=" + string.Join(' ', scopes);
|
server.HandleEndpoint("login", (HttpListenerRequest request) =>
|
||||||
|
{
|
||||||
|
var toReturn = new Httpd.ResponseSet();
|
||||||
|
Console.WriteLine($"query string: {request.QueryString}");
|
||||||
|
Console.WriteLine($"RawUrl: {request.RawUrl}");
|
||||||
|
toReturn.Text = File.ReadAllText("login.html");
|
||||||
|
return toReturn;
|
||||||
|
});
|
||||||
|
var token = "";
|
||||||
|
server.HandleEndpoint("token", (HttpListenerRequest request) =>
|
||||||
|
{
|
||||||
|
byte[] rawIncomingBytes = new byte[request.ContentLength64];
|
||||||
|
request.InputStream.Read(rawIncomingBytes, 0, (int)request.ContentLength64);
|
||||||
|
token = request.ContentEncoding.GetString(rawIncomingBytes);
|
||||||
|
_signal.Set();
|
||||||
|
return new Httpd.ResponseSet() {Text = "k" };
|
||||||
|
});
|
||||||
|
var sendTo = $"https://id.twitch.tv/oauth2/authorize?client_id={clientId}&redirect_uri={redirectUri}&response_type=token&state=constant_agitation&scope=channel.ban";
|
||||||
|
Console.WriteLine($"go to {sendTo} plz, I'll wait here");
|
||||||
|
_signal.WaitOne(new TimeSpan(1, 0, 0));
|
||||||
|
return token;
|
||||||
}
|
}
|
||||||
var postURI = $"https://id.twitch.tv/oauth2/token?client_id={clientId}&client_secret={clientSecret}&grant_type=client_credentials{scopeString}";
|
public static OAuthToken GetApplication(HttpClient client, string clientId, string clientSecret, string[] scopes = null)
|
||||||
//Console.WriteLine(postURI);
|
{
|
||||||
var r = client.PostAsync(postURI, null).Result;
|
var scopeString = "";
|
||||||
|
if (scopes != null && scopes.Length > 0)
|
||||||
|
{
|
||||||
|
scopeString = "&scope=" + string.Join(' ', scopes);
|
||||||
|
}
|
||||||
|
var postURI = $"https://id.twitch.tv/oauth2/token?client_id={clientId}&client_secret={clientSecret}&grant_type=client_credentials{scopeString}";
|
||||||
|
//Console.WriteLine(postURI);
|
||||||
|
var r = client.PostAsync(postURI, null).Result;
|
||||||
|
|
||||||
var response = "";
|
var response = "";
|
||||||
using (var streamReader = new StreamReader(r.Content.ReadAsStream()))
|
using (var streamReader = new StreamReader(r.Content.ReadAsStream()))
|
||||||
{
|
{
|
||||||
response = streamReader.ReadToEnd();
|
response = streamReader.ReadToEnd();
|
||||||
|
}
|
||||||
|
if (!r.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Console.Error.WriteLine(response);
|
||||||
|
throw new Exception(response);
|
||||||
|
}
|
||||||
|
Console.WriteLine(response);
|
||||||
|
return JsonConvert.DeserializeObject<OAuthToken>(response);
|
||||||
}
|
}
|
||||||
if(!r.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine(response);
|
|
||||||
throw new Exception(response);
|
|
||||||
}
|
|
||||||
//Console.WriteLine(response);
|
|
||||||
return JsonConvert.DeserializeObject<OAuthToken>(response);
|
|
||||||
}
|
}
|
||||||
}
|
public class OAuthToken
|
||||||
public class OAuthToken
|
{
|
||||||
{
|
public string access_token { get; set; }
|
||||||
public string access_token { get; set; }
|
public string refresh_token { get; set; }
|
||||||
public string refresh_token { get; set; }
|
public int expires_in { get; set; }
|
||||||
public int expires_in { get; set; }
|
public string[] scope { get; set; }
|
||||||
public string[] scope { get; set; }
|
public string token_type { get; set; }
|
||||||
public string token_type { get; set; }
|
}
|
||||||
}
|
}
|
33
Program.cs
33
Program.cs
@ -5,17 +5,20 @@ using System.IO;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using TwitchEventSub.Types.EventSubSubscription;
|
using TwitchEventSub.Types.EventSubSubscription;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using System.Net;
|
||||||
|
|
||||||
namespace twitcher
|
namespace twitcher
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
public static TwitchEventSub.Receiver httpd;
|
static TwitchEventSub.Receiver httpd;
|
||||||
public static Config twitcherConf;
|
static Config twitcherConf;
|
||||||
//public static Telefranz tf;
|
static Telefranz tf;
|
||||||
|
static HttpListener server;
|
||||||
static void Main(string[] args)
|
static void Main(string[] args)
|
||||||
{
|
{
|
||||||
JsonConvert.DefaultSettings = () => {
|
JsonConvert.DefaultSettings = () =>
|
||||||
|
{
|
||||||
var s = new JsonSerializerSettings();
|
var s = new JsonSerializerSettings();
|
||||||
s.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
s.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
|
||||||
return s;
|
return s;
|
||||||
@ -28,23 +31,23 @@ namespace twitcher
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
twitcherConf = JsonConvert.DeserializeObject<Config>(File.ReadAllText("appsettings.json"));
|
twitcherConf = JsonConvert.DeserializeObject<Config>(File.ReadAllText("appsettings.json"));
|
||||||
|
|
||||||
|
var httpd = new Httpd(twitcherConf.port);
|
||||||
|
var theRunTask = httpd.go();
|
||||||
|
var token = OAuthTokenGetter.GetUser(httpd, twitcherConf.clientId, "localhost:8420/login");
|
||||||
|
|
||||||
|
//var token = OAuthTokenGetter.DoIt(client, twitcherConf.clientId, twitcherConf.clientSecret, new string[]{"channel:moderate"});
|
||||||
|
|
||||||
// Telefranz.Configure(name: twitcherConf.kafka_name, bootstrap_servers: twitcherConf.kafka_bootstrap);
|
// Telefranz.Configure(name: twitcherConf.kafka_name, bootstrap_servers: twitcherConf.kafka_bootstrap);
|
||||||
// Task.WaitAll(Task.Delay(1000));
|
// Task.WaitAll(Task.Delay(1000));
|
||||||
// tf = Telefranz.Instance;
|
// tf = Telefranz.Instance;
|
||||||
|
|
||||||
//TODO: throw a request out somewhere asking for public url
|
//TODO: throw a request out somewhere asking for public url
|
||||||
//tf.ProduceMessage(new silver_messages.directorial.execute_command(){command = "ssl_expose", args = {twitcherConf.port.ToString()}});
|
//tf.ProduceMessage(new silver_messages.directorial.execute_command(){command = "ssl_expose", args = {twitcherConf.port.ToString()}});
|
||||||
|
|
||||||
httpd = new TwitchEventSub.Receiver(twitcherConf.port, twitcherConf.clientId, twitcherConf.clientSecret, twitcherConf.public_uri);
|
var rec = new TwitchEventSub.Receiver(server, twitcherConf.clientId, twitcherConf.clientSecret, twitcherConf.public_uri);
|
||||||
var theRunTask = httpd.go();
|
|
||||||
httpd.Subscribe(SubscribableTypes.channel_follow,
|
var sm = new SilverMeddlistsSpecific(httpd, tf, twitcherConf.clientId);
|
||||||
new TwitchEventSub.Types.Conditions.ChannelFollow() { broadcaster_user_id = "12826" },
|
|
||||||
(tg) => {
|
|
||||||
Console.WriteLine("I'm the handler for a twitchogram!");
|
|
||||||
Console.WriteLine(JsonConvert.SerializeObject(tg));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
Task.WaitAll(theRunTask);
|
Task.WaitAll(theRunTask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
66
SilverMeddlistsSpecific.cs
Normal file
66
SilverMeddlistsSpecific.cs
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using franz;
|
||||||
|
using TwitchEventSub;
|
||||||
|
using TwitchEventSub.Types;
|
||||||
|
using Conditions = TwitchEventSub.Types.Conditions;
|
||||||
|
using TwitchEventSub.Types.EventSubSubscription;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
public class SilverMeddlistsSpecific
|
||||||
|
{
|
||||||
|
public Receiver Httpd { get; }
|
||||||
|
public Telefranz Tf { get; }
|
||||||
|
private const string silverMeddlistsBroadcasterID = "598251923";
|
||||||
|
public SilverMeddlistsSpecific(Receiver httpd, Telefranz tf, string clientId)
|
||||||
|
{
|
||||||
|
Httpd = httpd;
|
||||||
|
Tf = tf;
|
||||||
|
|
||||||
|
var targetSilverMeddlistsChannel = new Conditions.TargetChannel(){broadcaster_user_id = silverMeddlistsBroadcasterID};
|
||||||
|
var targetCustomChannelPointsReward = new Conditions.TargetCustomChannelPointsReward(){};
|
||||||
|
var targetSelf = new Conditions.TargetSelf(){client_id = clientId};
|
||||||
|
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_ban, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_channel_points_custom_reward_add, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_channel_points_custom_reward_redemption_add, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_channel_points_custom_reward_redemption_update, targetCustomChannelPointsReward, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_channel_points_custom_reward_remove, targetCustomChannelPointsReward, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_channel_points_custom_reward_update, targetCustomChannelPointsReward, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_cheer, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_follow, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_goal_begin, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_goal_end, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_goal_progress, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_hype_train_begin, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_hype_train_end, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_hype_train_progress, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_moderator_add, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_moderator_remove, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_poll_begin, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_poll_end, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_poll_progress, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_prediction_begin, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_prediction_end, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_prediction_lock, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_prediction_progress, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_raid, new Conditions.ChannelRaid() { to_broadcaster_user_id = silverMeddlistsBroadcasterID}, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_subscribe, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_subscription_end, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_subscription_gift, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_subscription_message, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_unban, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.channel_update, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.drop_entitlement_grant, new Conditions.DropEntitlementGrant(), defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.extension_bits_transaction_create, new Conditions.TargetExtension(), defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.stream_offline, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.stream_online, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.user_authorization_grant, targetSelf, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.user_authorization_revoke, targetSelf, defaultEvent);
|
||||||
|
Httpd.Subscribe(SubscribableTypes.user_update, targetSilverMeddlistsChannel, defaultEvent);
|
||||||
|
}
|
||||||
|
private void defaultEvent(Twitchogram twitchogram)
|
||||||
|
{
|
||||||
|
Console.WriteLine(JsonConvert.SerializeObject(twitchogram));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -26,13 +26,12 @@ namespace TwitchEventSub
|
|||||||
private string clientId;
|
private string clientId;
|
||||||
private HMACSHA256 hmacsha256 = null;
|
private HMACSHA256 hmacsha256 = null;
|
||||||
private List<Task> tasksToNotActuallyAwait = new List<Task>();
|
private List<Task> tasksToNotActuallyAwait = new List<Task>();
|
||||||
public Receiver(int port, string clientId, string clientSecret, string publicUrl)
|
public Receiver(HttpListener server, string clientId, string clientSecret, string publicUrl)
|
||||||
{
|
{
|
||||||
this.clientId = clientId;
|
this.clientId = clientId;
|
||||||
this.publicUrl = new Uri(publicUrl + "/twitcherize");
|
this.publicUrl = new Uri(publicUrl + "/twitcherize");
|
||||||
twitchogrambuffer = new Queue<string>();
|
twitchogrambuffer = new Queue<string>();
|
||||||
server = new HttpListener();
|
this.server = server;
|
||||||
server.Prefixes.Add($"http://*:{port}/");
|
|
||||||
|
|
||||||
authorizeClient(clientId, clientSecret);
|
authorizeClient(clientId, clientSecret);
|
||||||
|
|
||||||
@ -55,7 +54,6 @@ namespace TwitchEventSub
|
|||||||
|
|
||||||
private void authorizeClient(string clientId, string clientSecret)
|
private void authorizeClient(string clientId, string clientSecret)
|
||||||
{
|
{
|
||||||
this.token = OAuthTokenGetter.DoIt(client, clientId, clientSecret);
|
|
||||||
Console.WriteLine($"got a token");
|
Console.WriteLine($"got a token");
|
||||||
client.DefaultRequestHeaders.Add("Client-ID", $"{this.clientId }");
|
client.DefaultRequestHeaders.Add("Client-ID", $"{this.clientId }");
|
||||||
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.token.access_token}");
|
client.DefaultRequestHeaders.Add("Authorization", $"Bearer {this.token.access_token}");
|
||||||
@ -124,104 +122,9 @@ namespace TwitchEventSub
|
|||||||
public async Task go()
|
public async Task go()
|
||||||
{
|
{
|
||||||
going = true;
|
going = true;
|
||||||
server.Start();
|
|
||||||
await Task.Run(() =>
|
await Task.Run(() =>
|
||||||
{
|
{
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
HttpListenerContext context = server.GetContext();
|
|
||||||
HttpListenerResponse response = context.Response;
|
|
||||||
|
|
||||||
string page = context.Request.Url.LocalPath.Substring(1);
|
|
||||||
var resp = "no resource";
|
|
||||||
response.StatusCode = (int)HttpStatusCode.NotFound;
|
|
||||||
lock (psuedoResources)
|
|
||||||
{
|
|
||||||
if (page == "twitcherize")
|
|
||||||
{
|
|
||||||
byte[] rawIncomingBytes = new byte[context.Request.ContentLength64];
|
|
||||||
var readBytes = context.Request.InputStream.Read(rawIncomingBytes, 0, (int)context.Request.ContentLength64);
|
|
||||||
|
|
||||||
|
|
||||||
if (VerifySignature(context.Request.Headers["Twitch-Eventsub-Message-Signature"],
|
|
||||||
context.Request.ContentEncoding,
|
|
||||||
context.Request.Headers["Twitch-Eventsub-Message-Id"],
|
|
||||||
context.Request.Headers["Twitch-Eventsub-Message-Timestamp"],
|
|
||||||
rawIncomingBytes))
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (twitchogrambuffer.Contains(context.Request.Headers["Twitch-Eventsub-Message-Id"]))
|
|
||||||
{
|
|
||||||
Console.WriteLine("duplicate message received. Ignoring.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var incomingText = context.Request.ContentEncoding.GetString(rawIncomingBytes);
|
|
||||||
//Console.WriteLine($"{context.Request.Headers["Twitch-Eventsub-Message-Id"]} looks new to me.");
|
|
||||||
lock (twitchogrambuffer)
|
|
||||||
{
|
|
||||||
var fromTwitch = SubscribableTypesTranslation.RefineTwitchogram(incomingText);
|
|
||||||
if (fromTwitch.challenge != null)
|
|
||||||
{
|
|
||||||
resp = fromTwitch.challenge;
|
|
||||||
Console.WriteLine("challenge responded to, should be subscribed");
|
|
||||||
}
|
|
||||||
else if (fromTwitch.subscription.status == "authorization_revoked")
|
|
||||||
{
|
|
||||||
resp = "ok... :(";
|
|
||||||
Console.WriteLine($"auth revoked for {fromTwitch.subscription.type} ({fromTwitch.subscription.id})");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var foundAHandler = false;
|
|
||||||
foreach (var kvp in psuedoResources)
|
|
||||||
{
|
|
||||||
if (kvp.Key.id == fromTwitch.subscription.id)
|
|
||||||
{
|
|
||||||
kvp.Value(fromTwitch);
|
|
||||||
resp = ":)";
|
|
||||||
foundAHandler = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!foundAHandler)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"I don't have a handler for {fromTwitch.subscription.type} ({fromTwitch.subscription.id})? o_O");
|
|
||||||
resp = ":S";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tasksToNotActuallyAwait.Add(logMessageId(context.Request.Headers["Twitch-Eventsub-Message-Id"]));
|
|
||||||
response.StatusCode = (int)HttpStatusCode.OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.Error.WriteLine("something went wrong calling resource.");
|
|
||||||
Console.Error.WriteLine(JsonConvert.SerializeObject(e));
|
|
||||||
response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
|
||||||
resp = "error :(";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Console.WriteLine("couldn't verify signature.");
|
|
||||||
response.StatusCode = (int)HttpStatusCode.Forbidden;
|
|
||||||
resp = "VoteNay";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(response.StatusCode != (int)HttpStatusCode.OK)
|
|
||||||
{
|
|
||||||
Console.WriteLine($"returning status code {response.StatusCode}");
|
|
||||||
}
|
|
||||||
byte[] buffer = Encoding.UTF8.GetBytes(resp);
|
|
||||||
response.ContentLength64 = buffer.Length;
|
|
||||||
Stream st = response.OutputStream;
|
|
||||||
st.Write(buffer, 0, buffer.Length);
|
|
||||||
response.Close();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
going = false;
|
going = false;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace TwitchEventSub.Types.Conditions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class TargetChannel : Condition
|
public class TargetChannel : Condition
|
||||||
{
|
{
|
||||||
public string broadcaster_user_id { get; set; }
|
public string broadcaster_user_id { get; set; }
|
||||||
}
|
}
|
||||||
@ -28,7 +28,7 @@ namespace TwitchEventSub.Types.Conditions
|
|||||||
{
|
{
|
||||||
public string user_id { get; set; }
|
public string user_id { get; set; }
|
||||||
}
|
}
|
||||||
public abstract class TargetCustomChannelPointsReward : Condition
|
public class TargetCustomChannelPointsReward : Condition
|
||||||
{
|
{
|
||||||
public string broadcaster_user_id { get; set; }
|
public string broadcaster_user_id { get; set; }
|
||||||
public string reward_id { get; set; }
|
public string reward_id { get; set; }
|
||||||
|
27
www/login.html
Normal file
27
www/login.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script type="text/javascript">
|
||||||
|
window.addEventListener('load', (event) => {
|
||||||
|
document.querySelector("body").appendChild(document.createTextNode(document.location.hash));
|
||||||
|
|
||||||
|
const myInit = {
|
||||||
|
method: 'POST',
|
||||||
|
mode: 'cors',
|
||||||
|
body: document.location.hash
|
||||||
|
};
|
||||||
|
|
||||||
|
let myRequest = new Request('token');
|
||||||
|
|
||||||
|
fetch(myRequest, myInit).then(function (response) {
|
||||||
|
document.querySelector("body").appendChild(document.createTextNode(response));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
hi
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Reference in New Issue
Block a user