From a8485edcf94be975188237e192e6fcc89542f6bf Mon Sep 17 00:00:00 2001 From: jetsparrow Date: Thu, 8 Aug 2019 22:19:31 +0300 Subject: [PATCH] Initial release --- .gitignore | 45 ++++++++ JetHerald.sln | 25 +++++ JetHerald/ChatCommandRouter.cs | 65 ++++++++++++ JetHerald/CommandString.cs | 42 ++++++++ JetHerald/Commands/CreateTopicCommand.cs | 47 +++++++++ JetHerald/Commands/DeleteTopicCommand.cs | 33 ++++++ JetHerald/Commands/ListCommand.cs | 31 ++++++ JetHerald/Commands/SubscribeCommand.cs | 38 +++++++ JetHerald/Commands/UnsubscribeCommand.cs | 30 ++++++ JetHerald/Configs.cs | 17 +++ JetHerald/Controllers/ReportController.cs | 42 ++++++++ JetHerald/Db.cs | 120 ++++++++++++++++++++++ JetHerald/JetHerald.csproj | 27 +++++ JetHerald/JetHeraldBot.cs | 85 +++++++++++++++ JetHerald/NLog.config | 27 +++++ JetHerald/Program.cs | 49 +++++++++ JetHerald/Properties/launchSettings.json | 30 ++++++ JetHerald/Startup.cs | 43 ++++++++ JetHerald/appsettings.Development.json | 9 ++ JetHerald/appsettings.json | 11 ++ 20 files changed, 816 insertions(+) create mode 100644 .gitignore create mode 100644 JetHerald.sln create mode 100644 JetHerald/ChatCommandRouter.cs create mode 100644 JetHerald/CommandString.cs create mode 100644 JetHerald/Commands/CreateTopicCommand.cs create mode 100644 JetHerald/Commands/DeleteTopicCommand.cs create mode 100644 JetHerald/Commands/ListCommand.cs create mode 100644 JetHerald/Commands/SubscribeCommand.cs create mode 100644 JetHerald/Commands/UnsubscribeCommand.cs create mode 100644 JetHerald/Configs.cs create mode 100644 JetHerald/Controllers/ReportController.cs create mode 100644 JetHerald/Db.cs create mode 100644 JetHerald/JetHerald.csproj create mode 100644 JetHerald/JetHeraldBot.cs create mode 100644 JetHerald/NLog.config create mode 100644 JetHerald/Program.cs create mode 100644 JetHerald/Properties/launchSettings.json create mode 100644 JetHerald/Startup.cs create mode 100644 JetHerald/appsettings.Development.json create mode 100644 JetHerald/appsettings.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c81b57d --- /dev/null +++ b/.gitignore @@ -0,0 +1,45 @@ +# Autosave files +*~ + +# build +[Oo]bj/ +[Bb]in/ +packages/ +TestResults/ + +# globs +Makefile.in +*.DS_Store +*.sln.cache +*.suo +*.cache +*.pidb +*.userprefs +*.usertasks +config.log +config.make +config.status +aclocal.m4 +install-sh +autom4te.cache/ +*.user +*.tar.gz +tarballs/ +test-results/ +Thumbs.db +.vs/ + +# Mac bundle stuff +*.dmg +*.app + +# resharper +*_Resharper.* +*.Resharper + +# dotCover +*.dotCover + +#secret config +karma.cfg.json +*secrets.ini diff --git a/JetHerald.sln b/JetHerald.sln new file mode 100644 index 0000000..98b32d0 --- /dev/null +++ b/JetHerald.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.539 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JetHerald", "JetHerald\JetHerald.csproj", "{B48207B2-F0A8-4BD8-AF92-906D128EF152}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {B48207B2-F0A8-4BD8-AF92-906D128EF152}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B48207B2-F0A8-4BD8-AF92-906D128EF152}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B48207B2-F0A8-4BD8-AF92-906D128EF152}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B48207B2-F0A8-4BD8-AF92-906D128EF152}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {A8B3E56D-CF82-4D94-B2CD-396A1AF6718B} + EndGlobalSection +EndGlobal diff --git a/JetHerald/ChatCommandRouter.cs b/JetHerald/ChatCommandRouter.cs new file mode 100644 index 0000000..63afa74 --- /dev/null +++ b/JetHerald/ChatCommandRouter.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Telegram.Bot.Args; + +namespace JetHerald +{ + public interface IChatCommand + { + Task Execute(CommandString cmd, MessageEventArgs messageEventArgs); + } + + public class ChatCommandRouter + { + string Username { get; } + ILogger Log { get; } + + public ChatCommandRouter(string username, ILogger log) + { + Log = log; + Username = username; + } + + public async Task Execute(object sender, MessageEventArgs args) + { + var text = args.Message.Text; + if (CommandString.TryParse(text, out var cmd)) + { + if (cmd.UserName != null && cmd.UserName != Username) + { + Log.LogDebug("Message not directed at us"); + return null; + } + if (commands.ContainsKey(cmd.Command)) + { + try + { + Log.LogDebug($"Handling message via {commands[cmd.Command].GetType().Name}"); + return await commands[cmd.Command].Execute(cmd, args); + } + catch (Exception e) + { + Log.LogError(e, $"Error while executing command {cmd.Command}!"); + } + } + else + Log.LogDebug($"Command {cmd.Command} not found"); + } + return null; + } + + public void Add(IChatCommand c, params string[] cmds) + { + foreach (var cmd in cmds) + { + if (commands.ContainsKey(cmd)) + throw new ArgumentException($"collision for {cmd}, commands {commands[cmd].GetType()} and {c.GetType()}"); + commands[cmd] = c; + } + } + + Dictionary commands = new Dictionary(); + } +} diff --git a/JetHerald/CommandString.cs b/JetHerald/CommandString.cs new file mode 100644 index 0000000..77e5e05 --- /dev/null +++ b/JetHerald/CommandString.cs @@ -0,0 +1,42 @@ +using System; +using System.Linq; +using System.Text.RegularExpressions; + +namespace JetHerald +{ + public class CommandString + { + public CommandString(string command, string username, params string[] parameters) + { + Command = command; + Parameters = parameters; + } + + public string Command { get; } + public string UserName { get; } + public string[] Parameters { get; } + + static readonly char[] WS_CHARS = new[] { ' ', '\r', '\n', '\n' }; + + public static bool TryParse(string s, out CommandString result) + { + result = null; + if (string.IsNullOrWhiteSpace(s) || s[0] != '/') + return false; + + string[] words = s.Split(WS_CHARS, StringSplitOptions.RemoveEmptyEntries); + + var cmdRegex = new Regex(@"/(?\w+)(@(?\w+))?"); + var match = cmdRegex.Match(words.First()); + if (!match.Success) + return false; + + string cmd = match.Groups["cmd"].Captures[0].Value; + string username = match.Groups["name"].Captures.Count > 0 ? match.Groups["name"].Captures[0].Value : null; + string[] parameters = words.Skip(1).ToArray(); + + result = new CommandString(cmd, username, parameters); + return true; + } + } +} diff --git a/JetHerald/Commands/CreateTopicCommand.cs b/JetHerald/Commands/CreateTopicCommand.cs new file mode 100644 index 0000000..cb8d7e3 --- /dev/null +++ b/JetHerald/Commands/CreateTopicCommand.cs @@ -0,0 +1,47 @@ +using System.Linq; +using System.Threading.Tasks; +using MySql.Data.MySqlClient; +using Telegram.Bot.Args; +using Telegram.Bot.Types.Enums; + +namespace JetHerald.Commands +{ + public class CreateTopicCommand : IChatCommand + { + Db db; + + public CreateTopicCommand(Db db) + { + this.db = db; + } + + public async Task Execute(CommandString cmd, MessageEventArgs messageEventArgs) + { + if (cmd.Parameters.Length < 1) + return null; + var msg = messageEventArgs.Message; + var chatid = msg.Chat.Id; + + if (msg.Chat.Type != ChatType.Private) + return null; + + string name = cmd.Parameters[0]; + string descr = name; + if (cmd.Parameters.Length > 1) + descr = string.Join(' ', cmd.Parameters.Skip(1)); + + try + { + var topic = await db.CreateTopic(msg.From.Id, name, descr); + return $"created {topic.Name}\n" + + $"readToken\n{topic.ReadToken}\n" + + $"writeToken\n{topic.WriteToken}\n" + + $"adminToken\n{topic.AdminToken}\n"; + } + catch (MySqlException myDuplicate) when (myDuplicate.Number == 1062) + { + return $"topic {name} already exists"; + } + } + } +} diff --git a/JetHerald/Commands/DeleteTopicCommand.cs b/JetHerald/Commands/DeleteTopicCommand.cs new file mode 100644 index 0000000..dd9275c --- /dev/null +++ b/JetHerald/Commands/DeleteTopicCommand.cs @@ -0,0 +1,33 @@ +using System.Threading.Tasks; +using Telegram.Bot.Args; +using Telegram.Bot.Types.Enums; + +namespace JetHerald.Commands +{ + public class DeleteTopicCommand : IChatCommand + { + Db db; + + public DeleteTopicCommand(Db db) + { + this.db = db; + } + + public async Task Execute(CommandString cmd, MessageEventArgs messageEventArgs) + { + if (cmd.Parameters.Length < 2) + return null; + var msg = messageEventArgs.Message; + var chatid = msg.Chat.Id; + + if (msg.Chat.Type != ChatType.Private) + return null; + + string name = cmd.Parameters[0]; + string adminToken = cmd.Parameters[1]; + + var topic = await db.DeleteTopic(name, adminToken); + return $"deleted {name} and all its subscriptions"; + } + } +} diff --git a/JetHerald/Commands/ListCommand.cs b/JetHerald/Commands/ListCommand.cs new file mode 100644 index 0000000..b2f89dc --- /dev/null +++ b/JetHerald/Commands/ListCommand.cs @@ -0,0 +1,31 @@ +using System.Linq; +using System.Threading.Tasks; +using Telegram.Bot.Args; + +namespace JetHerald +{ + public class ListCommand : IChatCommand + { + Db db; + + public ListCommand(Db db) + { + this.db = db; + } + + public async Task Execute(CommandString cmd, MessageEventArgs messageEventArgs) + { + var msg = messageEventArgs.Message; + var chatid = msg.Chat.Id; + var topics = await db.GetTopicsForChat(chatid); + + return topics.Any() + ? "Topics:\n" + string.Join("\n", topics.Select(GetTopicListing)) + : "No subscriptions active."; + } + + static string GetTopicListing(Db.Topic t) + => t.Name == t.Description ? t.Name : $"{t.Name}: {t.Description}"; + + } +} \ No newline at end of file diff --git a/JetHerald/Commands/SubscribeCommand.cs b/JetHerald/Commands/SubscribeCommand.cs new file mode 100644 index 0000000..46b3dcd --- /dev/null +++ b/JetHerald/Commands/SubscribeCommand.cs @@ -0,0 +1,38 @@ +using System.Threading.Tasks; +using Telegram.Bot.Args; + +namespace JetHerald +{ + public class SubscribeCommand : IChatCommand + { + Db db; + + public SubscribeCommand(Db db) + { + this.db = db; + } + + public async Task Execute(CommandString cmd, MessageEventArgs args) + { + if (cmd.Parameters.Length < 1) + return null; + + var chatid = args.Message.Chat.Id; + var token = cmd.Parameters[0]; + + var topic = await db.GetTopic(token, chatid); + + if (topic == null) + return "topic not found"; + else if (topic.ChatId == chatid) + return $"already subscribed to {topic.Name}"; + else if (topic.ReadToken != token) + return "token mismatch"; + else + { + await db.CreateSubscription(topic.TopicId, chatid); + return $"subscribed to {topic.Name}"; + } + } + } +} \ No newline at end of file diff --git a/JetHerald/Commands/UnsubscribeCommand.cs b/JetHerald/Commands/UnsubscribeCommand.cs new file mode 100644 index 0000000..6ada499 --- /dev/null +++ b/JetHerald/Commands/UnsubscribeCommand.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using Telegram.Bot.Args; + +namespace JetHerald +{ + public class UnsubscribeCommand : IChatCommand + { + Db db; + + public UnsubscribeCommand(Db db) + { + this.db = db; + } + + public async Task Execute(CommandString cmd, MessageEventArgs messageEventArgs) + { + if (cmd.Parameters.Length < 1) + return null; + + var msg = messageEventArgs.Message; + var chatid = msg.Chat.Id; + var topicName = cmd.Parameters[0]; + int affected = await db.RemoveSubscription(topicName, chatid); + if (affected >= 1) + return $"unsubscribed from {topicName}"; + else + return $"could not find subscription for {topicName}"; + } + } +} \ No newline at end of file diff --git a/JetHerald/Configs.cs b/JetHerald/Configs.cs new file mode 100644 index 0000000..758be17 --- /dev/null +++ b/JetHerald/Configs.cs @@ -0,0 +1,17 @@ +namespace JetHerald.Options +{ + public class ConnectionStrings + { + public string DefaultConnection { get; set; } + } + + public class Telegram + { + public string ApiKey { get; set; } + + public bool UseProxy { get; set; } + public string ProxyUrl { get; set; } + public string ProxyPassword { get; set; } + public string ProxyLogin { get; set; } + } +} diff --git a/JetHerald/Controllers/ReportController.cs b/JetHerald/Controllers/ReportController.cs new file mode 100644 index 0000000..c129978 --- /dev/null +++ b/JetHerald/Controllers/ReportController.cs @@ -0,0 +1,42 @@ +using System; +using System.Runtime.Serialization; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; + +namespace JetHerald.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ReportController : ControllerBase + { + Db Db { get; } + JetHeraldBot Herald { get; } + + public ReportController(Db db, JetHeraldBot herald) + { + Herald = herald; + Db = db; + } + + [HttpPost] + public async Task Post([FromBody] ReportArgs args) + { + var t = await Db.GetTopic(args.Topic); + if (t == null) + return new NotFoundResult(); + else if (!t.WriteToken.Equals(args.WriteToken, StringComparison.OrdinalIgnoreCase)) + return StatusCode(403); + + await Herald.PublishMessage(t, args.Message); + return new OkResult(); + } + + [DataContract] + public class ReportArgs + { + [DataMember] public string Topic { get; set; } + [DataMember] public string Message { get; set; } + [DataMember] public string WriteToken { get; set; } + } + } +} diff --git a/JetHerald/Db.cs b/JetHerald/Db.cs new file mode 100644 index 0000000..fb1e206 --- /dev/null +++ b/JetHerald/Db.cs @@ -0,0 +1,120 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using MySql.Data.MySqlClient; +using Dapper; +using Microsoft.Extensions.Options; +using System; +using System.Security.Cryptography; +using System.Transactions; + +namespace JetHerald +{ + public static class TokenHelper + { + static RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider(); + static byte[] buf = new byte[24]; + + public static string GetToken() + { + rng.GetBytes(buf); + return Convert.ToBase64String(buf).Replace('+', '_').Replace('/','_'); + } + } + + public class Db + { + public class Topic + { + public uint TopicId { get; set; } + public long CreatorId { get; set; } + public string Name { get; set; } + public string Description { get; set; } + public string ReadToken { get; set; } + public string WriteToken { get; set; } + public string AdminToken { get; set; } + + public long? ChatId { get; set; } + } + + public async Task DeleteTopic(string name, string adminToken) + { + using (var c = GetConnection()) + { + return await c.ExecuteAsync("DELETE FROM topic WHERE Name = @name AND AdminToken = @adminToken", new { name, adminToken }); + } + } + + public async Task GetTopic(string name) + { + using (var c = GetConnection()) + return await c.QuerySingleOrDefaultAsync("SELECT * FROM topic WHERE Name = @name", new { name }); + } + + public async Task GetTopic(string token, long chatId) + { + using (var c = GetConnection()) + return await c.QuerySingleOrDefaultAsync( + "SELECT t.*, tc.ChatId " + + "FROM topic t LEFT JOIN topic_chat tc ON t.TopicId = tc.TopicId AND tc.ChatId = @chatId " + + "WHERE ReadToken = @token", new { token, chatId}); + } + + public async Task CreateTopic(long userId, string name, string descr) + { + var t = new Topic + { + CreatorId = userId, + Name = name, + Description = descr, + ReadToken = TokenHelper.GetToken(), + WriteToken = TokenHelper.GetToken(), + AdminToken = TokenHelper.GetToken() + }; + using (var c = GetConnection()) + { + return await c.QuerySingleOrDefaultAsync( + " INSERT INTO herald.topic " + + " (TopicId, CreatorId, Name, Description, ReadToken, WriteToken, AdminToken) " + + " VALUES " + + " (NULL, @CreatorId, @Name, @Description, @ReadToken, @WriteToken, @AdminToken); " + + " SELECT * FROM topic WHERE TopicId = LAST_INSERT_ID(); ", + t); + } + } + public async Task> GetChatIdsForTopic(uint topicid) + { + using (var c = GetConnection()) + return await c.QueryAsync("SELECT ChatId FROM topic_chat WHERE TopicId = @topicid", new { topicid }); + } + + public async Task> GetTopicsForChat(long chatid) + { + using (var c = GetConnection()) + return await c.QueryAsync("SELECT t.* FROM topic_chat ct JOIN topic t on t.TopicId = ct.TopicId WHERE ct.ChatId = @chatid", new { chatid }); + } + + public async Task CreateSubscription(uint topicId, long chatId) + { + using (var c = GetConnection()) + await c.ExecuteAsync("INSERT INTO topic_chat (ChatId, TopicId ) VALUES (@chatId, @topicId)", new { topicId, chatId }); + } + + public async Task RemoveSubscription(string topicName, long chatId) + { + using (var c = GetConnection()) + return await c.ExecuteAsync( + "DELETE tc " + + "FROM topic_chat tc JOIN topic t ON tc.TopicId = t.TopicId " + + "WHERE t.Name = @topicName AND tc.ChatId = @chatId;", + new { topicName, chatId }); + } + + public Db(IOptions cfg) + { + Config = cfg; + } + + IOptions Config { get; } + MySqlConnection GetConnection() => new MySqlConnection(Config.Value.DefaultConnection); + } +} diff --git a/JetHerald/JetHerald.csproj b/JetHerald/JetHerald.csproj new file mode 100644 index 0000000..967abd3 --- /dev/null +++ b/JetHerald/JetHerald.csproj @@ -0,0 +1,27 @@ + + + + netcoreapp2.1 + + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/JetHerald/JetHeraldBot.cs b/JetHerald/JetHeraldBot.cs new file mode 100644 index 0000000..25da66f --- /dev/null +++ b/JetHerald/JetHeraldBot.cs @@ -0,0 +1,85 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Telegram.Bot; +using Telegram.Bot.Args; +using Telegram.Bot.Types.Enums; + +using JetHerald.Commands; + +namespace JetHerald +{ + public class JetHeraldBot + { + Db Db { get; set; } + Options.Telegram Config { get; } + ILogger Log { get; } + + public JetHeraldBot(Db db, IOptions cfg, ILogger log) + { + Db = db; + Config = cfg.Value; + Log = log; + } + + TelegramBotClient Client { get; set; } + ChatCommandRouter Commands; + Telegram.Bot.Types.User Me { get; set; } + + public async Task Init() + { + if (Config.UseProxy) + { + Client = new TelegramBotClient(Config.ApiKey); + } + else + { + var httpProxy = new WebProxy(Config.ProxyUrl) + { Credentials = new NetworkCredential(Config.ProxyLogin, Config.ProxyPassword) }; + Client = new TelegramBotClient(Config.ApiKey, httpProxy); + } + Me = await Client.GetMeAsync(); + + Commands = new ChatCommandRouter(Me.Username, Log); + Commands.Add(new CreateTopicCommand(Db), "createtopic"); + Commands.Add(new DeleteTopicCommand(Db), "deletetopic"); + Commands.Add(new SubscribeCommand(Db), "subscribe", "sub"); + Commands.Add(new UnsubscribeCommand(Db), "unsubscribe", "unsub"); + Commands.Add(new ListCommand(Db), "list"); + + Client.OnMessage += BotOnMessageReceived; + Client.StartReceiving(); + } + + public async Task PublishMessage(Db.Topic topic, string message) + { + var chatIds = await Db.GetChatIdsForTopic(topic.TopicId); + var formatted = $"|{topic.Description}|:\n{message}"; + foreach (var c in chatIds) + await Client.SendTextMessageAsync(c, formatted); + } + + async void BotOnMessageReceived(object sender, MessageEventArgs messageEventArgs) + { + var msg = messageEventArgs.Message; + if (msg == null || msg.Type != MessageType.Text) + return; + + try + { + var reply = await Commands.Execute(sender, messageEventArgs); + if (reply != null) + await Client.SendTextMessageAsync( + chatId: msg.Chat.Id, + text: reply, + replyToMessageId: msg.MessageId); + } + catch (Exception e) + { + Log.LogError(e, "Exception occured during handling of command: "+ msg.Text); + } + } + } +} diff --git a/JetHerald/NLog.config b/JetHerald/NLog.config new file mode 100644 index 0000000..dc2088a --- /dev/null +++ b/JetHerald/NLog.config @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/JetHerald/Program.cs b/JetHerald/Program.cs new file mode 100644 index 0000000..0002916 --- /dev/null +++ b/JetHerald/Program.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using NLog.Web; + +namespace JetHerald +{ + public class Program + { + public static void Main(string[] args) + { + var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger(); + try + { + logger.Debug("init main"); + CreateWebHostBuilder(args).Build().Run(); + } + catch (Exception ex) + { + logger.Error(ex, "Stopped program because of exception"); + throw; + } + finally + { + NLog.LogManager.Shutdown(); + } + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup() + .ConfigureAppConfiguration(config => + { + config.AddIniFile("secrets.ini"); + }) + .ConfigureLogging(logging => + { + logging.ClearProviders(); + logging.SetMinimumLevel(LogLevel.Trace); + }) + .UseNLog(); // NLog: setup NLog for Dependency injection + } +} diff --git a/JetHerald/Properties/launchSettings.json b/JetHerald/Properties/launchSettings.json new file mode 100644 index 0000000..c4b1195 --- /dev/null +++ b/JetHerald/Properties/launchSettings.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:57041", + "sslPort": 0 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": false, + "launchUrl": "api/values", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "JetHerald": { + "commandName": "Project", + "launchBrowser": false, + "launchUrl": "api/values", + "applicationUrl": "http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} \ No newline at end of file diff --git a/JetHerald/Startup.cs b/JetHerald/Startup.cs new file mode 100644 index 0000000..a55d832 --- /dev/null +++ b/JetHerald/Startup.cs @@ -0,0 +1,43 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace JetHerald +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.Configure(Configuration.GetSection("ConnectionStrings")); + services.Configure(Configuration.GetSection("Telegram")); + services.AddSingleton(); + services.AddSingleton(); + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1); + + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + var bot = app.ApplicationServices.GetService(); + bot.Init().Wait(); + app.UsePathBase(Configuration.GetValue("PathBase")); + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseMvc(); + } + } +} diff --git a/JetHerald/appsettings.Development.json b/JetHerald/appsettings.Development.json new file mode 100644 index 0000000..e203e94 --- /dev/null +++ b/JetHerald/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/JetHerald/appsettings.json b/JetHerald/appsettings.json new file mode 100644 index 0000000..6b2043d --- /dev/null +++ b/JetHerald/appsettings.json @@ -0,0 +1,11 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "Telegram": { + "UseProxy": "false" + }, + "PathBase": "/" +} \ No newline at end of file