Added API to DiscordBotCore
This commit is contained in:
67
DiscordBotCore/API/ApiManager.cs
Normal file
67
DiscordBotCore/API/ApiManager.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using DiscordBotCore.API.Endpoints;
|
||||
using DiscordBotCore.API.Endpoints.PluginManagement;
|
||||
using DiscordBotCore.Interfaces.API;
|
||||
using DiscordBotCore.Others;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
||||
namespace DiscordBotCore.API;
|
||||
|
||||
public class ApiManager
|
||||
{
|
||||
private bool IsRunning { get; set; }
|
||||
private List<IEndpoint> ApiEndpoints { get; }
|
||||
|
||||
public ApiManager()
|
||||
{
|
||||
ApiEndpoints = new List<IEndpoint>();
|
||||
}
|
||||
|
||||
public Result AddEndpoint(IEndpoint endpoint)
|
||||
{
|
||||
if (ApiEndpoints.Contains(endpoint) || ApiEndpoints.Exists(x => x.Path == endpoint.Path))
|
||||
{
|
||||
return Result.Failure("Endpoint already exists");
|
||||
}
|
||||
|
||||
ApiEndpoints.Add(endpoint);
|
||||
return Result.Success();
|
||||
}
|
||||
|
||||
public void RemoveEndpoint(string endpointPath)
|
||||
{
|
||||
this.ApiEndpoints.RemoveAll(endpoint => endpoint.Path == endpointPath);
|
||||
}
|
||||
|
||||
public bool EndpointExists(string endpointPath)
|
||||
{
|
||||
return this.ApiEndpoints.Exists(endpoint => endpoint.Path == endpointPath);
|
||||
}
|
||||
|
||||
internal void AddBaseEndpoints()
|
||||
{
|
||||
AddEndpoint(new HomeEndpoint());
|
||||
AddEndpoint(new PluginListEndpoint());
|
||||
}
|
||||
|
||||
public async Task InitializeApi()
|
||||
{
|
||||
if (IsRunning)
|
||||
return;
|
||||
|
||||
IsRunning = true;
|
||||
|
||||
var builder = WebApplication.CreateBuilder();
|
||||
var app = builder.Build();
|
||||
app.UseRouting();
|
||||
|
||||
EndpointManager manager = new EndpointManager(app);
|
||||
foreach(IEndpoint endpoint in this.ApiEndpoints)
|
||||
{
|
||||
manager.MapEndpoint(endpoint);
|
||||
}
|
||||
|
||||
await app.RunAsync();
|
||||
}
|
||||
}
|
||||
34
DiscordBotCore/API/ApiResponse.cs
Normal file
34
DiscordBotCore/API/ApiResponse.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Threading.Tasks;
|
||||
using DiscordBotCore.Others;
|
||||
|
||||
namespace DiscordBotCore.API;
|
||||
|
||||
public class ApiResponse
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public bool Success { get; set; }
|
||||
|
||||
private ApiResponse(string message, bool success)
|
||||
{
|
||||
Message = message;
|
||||
Success = success;
|
||||
}
|
||||
|
||||
public static ApiResponse From(string message, bool success)
|
||||
{
|
||||
return new ApiResponse(message, success);
|
||||
}
|
||||
|
||||
public static ApiResponse Fail(string message)
|
||||
{
|
||||
return new ApiResponse(message, false);
|
||||
}
|
||||
|
||||
public static ApiResponse Ok()
|
||||
{
|
||||
return new ApiResponse(string.Empty, true);
|
||||
}
|
||||
|
||||
public async Task<string> ToJson() => await JsonManager.ConvertToJsonString(this);
|
||||
|
||||
}
|
||||
80
DiscordBotCore/API/EndpointManager.cs
Normal file
80
DiscordBotCore/API/EndpointManager.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using DiscordBotCore.Interfaces.API;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace DiscordBotCore.API;
|
||||
|
||||
internal sealed class EndpointManager
|
||||
{
|
||||
private WebApplication _appBuilder;
|
||||
internal EndpointManager(WebApplication appBuilder)
|
||||
{
|
||||
_appBuilder = appBuilder;
|
||||
}
|
||||
|
||||
internal void MapEndpoint(IEndpoint endpoint)
|
||||
{
|
||||
switch (endpoint.HttpMethod)
|
||||
{
|
||||
case EndpointType.Get:
|
||||
_appBuilder.MapGet(endpoint.Path, async context =>
|
||||
{
|
||||
//convert the context to a string
|
||||
string jsonRequest = string.Empty;
|
||||
if (context.Request.Body.CanRead)
|
||||
{
|
||||
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
|
||||
jsonRequest = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
var response = await endpoint.HandleRequest(jsonRequest);
|
||||
await context.Response.WriteAsync(await response.ToJson());
|
||||
});
|
||||
break;
|
||||
case EndpointType.Put:
|
||||
_appBuilder.MapPut(endpoint.Path, async context =>
|
||||
{
|
||||
string jsonRequest = string.Empty;
|
||||
if (context.Request.Body.CanRead)
|
||||
{
|
||||
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
|
||||
jsonRequest = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
var response = await endpoint.HandleRequest(jsonRequest);
|
||||
await context.Response.WriteAsync(await response.ToJson());
|
||||
});
|
||||
break;
|
||||
case EndpointType.Post:
|
||||
_appBuilder.MapPost(endpoint.Path, async context =>
|
||||
{
|
||||
string jsonRequest = string.Empty;
|
||||
if (context.Request.Body.CanRead)
|
||||
{
|
||||
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
|
||||
jsonRequest = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
var response = await endpoint.HandleRequest(jsonRequest);
|
||||
await context.Response.WriteAsync(await response.ToJson());
|
||||
});
|
||||
break;
|
||||
case EndpointType.Delete:
|
||||
_appBuilder.MapDelete(endpoint.Path, async context =>
|
||||
{
|
||||
string jsonRequest = string.Empty;
|
||||
if (context.Request.Body.CanRead)
|
||||
{
|
||||
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
|
||||
jsonRequest = await reader.ReadToEndAsync();
|
||||
}
|
||||
|
||||
var response = await endpoint.HandleRequest(jsonRequest);
|
||||
await context.Response.WriteAsync(await response.ToJson());
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
26
DiscordBotCore/API/Endpoints/HomeEndpoint.cs
Normal file
26
DiscordBotCore/API/Endpoints/HomeEndpoint.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using DiscordBotCore.Interfaces.API;
|
||||
using DiscordBotCore.Others;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace DiscordBotCore.API.Endpoints;
|
||||
|
||||
internal class HomeEndpoint : IEndpoint
|
||||
{
|
||||
private static readonly string _HomeMessage = "Welcome to the DiscordBot API.";
|
||||
public string Path => "/";
|
||||
EndpointType IEndpoint.HttpMethod => EndpointType.Get;
|
||||
public async Task<ApiResponse> HandleRequest(string? jsonText)
|
||||
{
|
||||
string response = _HomeMessage;
|
||||
if (jsonText != string.Empty)
|
||||
{
|
||||
var json = await JsonManager.ConvertFromJson<Dictionary<string,string>>(jsonText!);
|
||||
response += $"\n\nYou sent the following JSON:\n{string.Join("\n", json.Select(x => $"{x.Key}: {x.Value}"))}";
|
||||
}
|
||||
|
||||
return ApiResponse.From(response, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using DiscordBotCore.Interfaces.API;
|
||||
using DiscordBotCore.Others;
|
||||
using DiscordBotCore.Plugin;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
|
||||
namespace DiscordBotCore.API.Endpoints.PluginManagement;
|
||||
|
||||
public class InstallPluginEndpoint : IEndpoint
|
||||
{
|
||||
public string Path => "/api/plugin/install";
|
||||
public EndpointType HttpMethod => EndpointType.Put;
|
||||
public async Task<ApiResponse> HandleRequest(string? jsonRequest)
|
||||
{
|
||||
Dictionary<string, string> jsonDict = await JsonManager.ConvertFromJson<Dictionary<string, string>>(jsonRequest);
|
||||
string pluginName = jsonDict["pluginName"];
|
||||
|
||||
PluginOnlineInfo? pluginInfo = await Application.CurrentApplication.PluginManager.GetPluginDataByName(pluginName);
|
||||
|
||||
if (pluginInfo == null)
|
||||
{
|
||||
return ApiResponse.Fail("Plugin not found.");
|
||||
}
|
||||
|
||||
await Application.CurrentApplication.PluginManager.InstallPlugin(pluginInfo, null);
|
||||
return ApiResponse.Ok();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Threading.Tasks;
|
||||
using DiscordBotCore.Interfaces.API;
|
||||
using DiscordBotCore.Others;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
||||
namespace DiscordBotCore.API.Endpoints.PluginManagement;
|
||||
|
||||
public class PluginListEndpoint : IEndpoint
|
||||
{
|
||||
public string Path => "/api/plugin/list/online";
|
||||
public EndpointType HttpMethod => EndpointType.Get;
|
||||
public async Task<ApiResponse> HandleRequest(string? jsonRequest)
|
||||
{
|
||||
var onlineInfos = await Application.CurrentApplication.PluginManager.GetPluginsList();
|
||||
var response = await JsonManager.ConvertToJsonString(onlineInfos);
|
||||
return ApiResponse.From(response, true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Threading.Tasks;
|
||||
using DiscordBotCore.Interfaces.API;
|
||||
using DiscordBotCore.Others;
|
||||
|
||||
namespace DiscordBotCore.API.Endpoints.PluginManagement;
|
||||
|
||||
public class PluginListInstalledEndpoint : IEndpoint
|
||||
{
|
||||
public string Path => "/api/plugin/list/local";
|
||||
public EndpointType HttpMethod => EndpointType.Get;
|
||||
public async Task<ApiResponse> HandleRequest(string? jsonRequest)
|
||||
{
|
||||
var listInstalled = await Application.CurrentApplication.PluginManager.GetInstalledPlugins();
|
||||
var response = await JsonManager.ConvertToJsonString(listInstalled);
|
||||
return ApiResponse.From(response, true);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user