150 lines
4.9 KiB
C#
150 lines
4.9 KiB
C#
using Maki.Structures.Rest;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
|
|
namespace Maki.Rest
|
|
{
|
|
/// <summary>
|
|
/// Handles requests to Discord's REST API
|
|
/// </summary>
|
|
internal class RestClient
|
|
{
|
|
/// <summary>
|
|
/// User agent that is send alongside requests
|
|
/// </summary>
|
|
private const string USER_AGENT = @"DiscordBot (https://github.com/flashwave/nicobot)";
|
|
|
|
/// <summary>
|
|
/// Container for parent DiscordClient instance
|
|
/// </summary>
|
|
private readonly Discord client;
|
|
|
|
/// <summary>
|
|
/// Request types that should be handled as data requests
|
|
/// </summary>
|
|
private readonly RestRequestMethod[] dataRequestTypes = new RestRequestMethod[] {
|
|
RestRequestMethod.POST,
|
|
RestRequestMethod.PUT,
|
|
RestRequestMethod.PATCH,
|
|
};
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
/// <param name="c">Parent DiscordClient instance</param>
|
|
public RestClient(Discord c)
|
|
{
|
|
client = c;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a base HttpWebRequest
|
|
/// </summary>
|
|
/// <param name="method">Request method</param>
|
|
/// <param name="url">Endpoint url</param>
|
|
/// <returns>Prepared HttpWebRequest</returns>
|
|
private HttpWebRequest BaseRequest(RestRequestMethod method, string url)
|
|
{
|
|
Uri uri = new Uri(RestEndpoints.BASE_URL + RestEndpoints.BASE_PATH + url);
|
|
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
|
|
|
|
request.Method = method.ToString();
|
|
request.UserAgent = USER_AGENT;
|
|
|
|
if (!string.IsNullOrEmpty(client.Token))
|
|
request.Headers[HttpRequestHeader.Authorization] = (client.IsBot ? "Bot " : string.Empty) + client.Token;
|
|
|
|
return request;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets a response string from HttpWebRequest
|
|
/// </summary>
|
|
/// <param name="request">HttpWebRequest instance</param>
|
|
/// <returns>string output</returns>
|
|
private RestResponse<T> HandleResponse<T>(HttpWebRequest request)
|
|
{
|
|
HttpWebResponse webResponse;
|
|
RestResponse<T> response = new RestResponse<T>();
|
|
|
|
try
|
|
{
|
|
webResponse = request.GetResponse() as HttpWebResponse;
|
|
}
|
|
catch (WebException ex)
|
|
{
|
|
webResponse = ex.Response as HttpWebResponse;
|
|
}
|
|
|
|
Enum.TryParse(webResponse.Method, out response.Method);
|
|
response.Uri = webResponse.ResponseUri;
|
|
response.Status = (ushort)webResponse.StatusCode;
|
|
|
|
using (Stream httpResponseStream = webResponse.GetResponseStream())
|
|
using (StreamReader streamReader = new StreamReader(httpResponseStream))
|
|
response.RawResponse = streamReader.ReadToEnd();
|
|
|
|
webResponse.Close();
|
|
|
|
Error error = default(Error);
|
|
|
|
try
|
|
{
|
|
error = JsonConvert.DeserializeObject<Error>(response.RawResponse);
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
|
|
if (error.Equals(default(Error)))
|
|
{
|
|
response.ErrorCode = RestErrorCode.Ok;
|
|
response.ErrorMessage = string.Empty;
|
|
}
|
|
else
|
|
{
|
|
response.ErrorCode = (RestErrorCode)error.Code;
|
|
response.ErrorMessage = error.Message;
|
|
}
|
|
|
|
Console.WriteLine(response.RawResponse);
|
|
|
|
if (response.Status == 200)
|
|
response.Response = JsonConvert.DeserializeObject<T>(response.RawResponse);
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Make a json request
|
|
/// </summary>
|
|
/// <typeparam name="T">Type to use when deserialising the JSON object</typeparam>
|
|
/// <param name="method">Request method</param>
|
|
/// <param name="url">Endpoint url</param>
|
|
/// <param name="data">Request data</param>
|
|
/// <returns>Deserialised JSON object</returns>
|
|
public RestResponse<T> Request<T>(RestRequestMethod method, string url, object data = null)
|
|
{
|
|
HttpWebRequest request = BaseRequest(method, url);
|
|
|
|
request.ContentType = "application/json;charset=utf-8";
|
|
request.ContentLength = 0;
|
|
|
|
if (dataRequestTypes.Contains(method) && data != null)
|
|
{
|
|
byte[] bytes = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(data));
|
|
request.ContentLength = bytes.LongLength;
|
|
|
|
using (Stream requestStream = request.GetRequestStream())
|
|
requestStream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
|
|
return HandleResponse<T>(request);
|
|
}
|
|
}
|
|
}
|