Skip to content

Instantly share code, notes, and snippets.

@MihaZupan
Created May 21, 2018 11:13
Show Gist options
  • Save MihaZupan/e03cf9069b74740323eaa339cec6ea31 to your computer and use it in GitHub Desktop.
Save MihaZupan/e03cf9069b74740323eaa339cec6ea31 to your computer and use it in GitHub Desktop.
using System;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using Telegram.Bot.Types;
namespace StackExBot
{
class WebHook
{
private readonly HttpListener WebHookReceiver = new HttpListener();
private string Token;
private bool Stopped = false;
public string Url { get; private set; }
public WebHook(string fqdn, int port, string token)
{
Token = token;
Url = $"https://{fqdn}:{port}/{token}";
WebHookReceiver.Prefixes.Add($"https://{fqdn}:{port}/");
}
public void Start()
{
if (Stopped) throw new ObjectDisposedException("HttpListener");
WebHookReceiver.Start();
WebHookReceiver.BeginGetContext(WebHookContextReceived, null);
}
public void StopAndClose()
{
if (!Stopped)
{
Stopped = true;
if (WebHookReceiver.IsListening)
WebHookReceiver.Stop();
WebHookReceiver.Close();
}
}
private void WebHookContextReceived(IAsyncResult AR)
{
HttpListenerContext context = WebHookReceiver.EndGetContext(AR);
WebHookReceiver.BeginGetContext(WebHookContextReceived, null);
OnWebHookContext(context);
}
private void OnWebHookContext(HttpListenerContext context)
{
if (context.Request.HttpMethod.ToLower() != "post")
{
RespondWithCode(context, HttpStatusCode.MethodNotAllowed);
return;
}
if (!context.Request.Url.AbsolutePath.TrimEnd('/').EndsWith(Token))
{
RespondWithCode(context, HttpStatusCode.Forbidden);
return;
}
try
{
string json;
using (StreamReader sr = new StreamReader(context.Request.InputStream))
json = sr.ReadToEnd();
Update update = JsonConvert.DeserializeObject<Update>(json);
if (update == null)
{
RespondWithCode(context, HttpStatusCode.BadRequest);
}
else
{
OnUpdate?.BeginInvoke(this, update, OnInvokeEnd, null);
RespondWithCode(context, HttpStatusCode.OK);
}
}
catch
{
RespondWithCode(context, HttpStatusCode.BadRequest);
}
}
private void RespondWithCode(HttpListenerContext context, HttpStatusCode errorCode)
{
context.Response.StatusCode = (int)errorCode;
context.Response.OutputStream.Close();
}
private void OnInvokeEnd(IAsyncResult AR)
{
OnUpdate?.EndInvoke(AR);
}
public event EventHandler<Update> OnUpdate;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment