diff --git a/.cleanthat/cleanthat.yaml b/.cleanthat/cleanthat.yaml new file mode 100644 index 0000000..e7435cd --- /dev/null +++ b/.cleanthat/cleanthat.yaml @@ -0,0 +1,23 @@ +syntax_version: "2023-01-09" +meta: + labels: + - "cleanthat" + refs: + protected_patterns: + - "refs/heads/develop" + - "refs/heads/main" + - "refs/heads/master" + full_clean_on_configuration_change: false + can_edit_not_protected_branches: true +source_code: + encoding: "UTF-8" + line_ending: "GIT" +engines: +- engine: "spotless" + skip: false + source_code: {} + steps: + - id: "spotless" + skip: false + parameters: + configuration: "repository:/.cleanthat/spotless.yaml" diff --git a/.cleanthat/spotless.yaml b/.cleanthat/spotless.yaml new file mode 100644 index 0000000..8fa9c0a --- /dev/null +++ b/.cleanthat/spotless.yaml @@ -0,0 +1,26 @@ +syntax_version: "2023-01-09" +encoding: "UTF-8" +git: + core_eol: "native" +line_ending: "GIT_ATTRIBUTES" +formatters: +- format: "json" + steps: + - id: "jackson" + skip: false + parameters: + features: + ORDER_MAP_ENTRIES_BY_KEYS: true + yaml_features: + QUOTE_FIELD_NAMES: false +- format: "markdown" + steps: + - id: "flexmark" + skip: false + parameters: + version: "0.62.2" + - id: "freshmark" + skip: false + parameters: + properties: + k1: "v1" diff --git a/.deepsource.toml b/.deepsource.toml new file mode 100644 index 0000000..08e47dd --- /dev/null +++ b/.deepsource.toml @@ -0,0 +1,4 @@ +version = 1 + +[[analyzers]] +name = "csharp" \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 58d2413..0944ba0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "Telegram.Bot"] - path = Telegram.Bot - url = https://github.com/dgmjr-io/Telegram.Bot.git -[submodule "lib/Telegram.Bot"] path = lib/Telegram.Bot url = https://github.com/dgmjr-io/Telegram.Bot.git diff --git a/README.md b/README.md index 146ec15..a289e7d 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ --- + title: Telegram description: This package contains classes for talking to the Telegram APIs. date: 2023-01-09T18:57:29.297Z lastmod: 2023-04-12T10:49:39.467Z type: readme tags: - - telegram - - Dgmjr +- telegram +- DGMJR-IO slug: telegram ---- +-------------- # Telegram diff --git a/src/Bot.Extensions/README.md b/src/Bot.Extensions/README.md index f1384c0..53b8575 100644 --- a/src/Bot.Extensions/README.md +++ b/src/Bot.Extensions/README.md @@ -1,18 +1,19 @@ ---- -author: David G. Moore, Jr. -author_email: david@dgmjr.io -title: README.md -lastmod: 2023-01-17-12:35:43 -created: 2023-01-17-12:35:43 -license: MIT -keywords: - - Dgmjr -tags: - - Dgmjr -categories: - - Dgmjr ---- - -# Telegram Bot Extensions - -This library provides a set of extensions for the [Telegram.Bot](https://github.com/TelegramBots/Telegram.Bot) library. +--- + +author: David G. Moore, Jr. +author_email: david@dgmjr.io +title: README.md +lastmod: 2023-01-17-12:35:43 +created: 2023-01-17-12:35:43 +license: MIT +keywords: +- DGMJR-IO +tags: +- DGMJR-IO +categories: +- DGMJR-IO +---------- + +# Telegram Bot Extensions + +This library provides a set of extensions for the [Telegram.Bot](https://github.com/TelegramBots/Telegram.Bot) library. diff --git a/src/Constants/DatabaseConstants.cs b/src/Constants/DatabaseConstants.cs index 43529b1..3963fee 100644 --- a/src/Constants/DatabaseConstants.cs +++ b/src/Constants/DatabaseConstants.cs @@ -1,11 +1,11 @@ -/* +/* * DatabaseConstants.cs - * + * * Created: 2023-03-23-08:42:48 * Modified: 2023-03-23-11:04:32 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) */ @@ -20,9 +20,25 @@ public static class SchemaNames public static class TableNames { + /// + /// The prefix for tables, + /// + /// tbl_ private const string tbl_ = nameof(tbl_); + /// + /// The table name for Bots, + /// + /// Bot public const string Bot = tbl_ + nameof(Bot); + /// + /// The table name for Groups, + /// + /// Group public const string Group = tbl_ + nameof(Group); + /// + /// The table name for Channels, + /// + /// Channel public const string Channel = tbl_ + nameof(Channel); } @@ -31,7 +47,7 @@ public static class ColumnNames { public static class Bot { - public const string Id = "TelegramId"; + public const string Id = "Id"; public const string Name = nameof(Name); public const string TelegramUsername = nameof(TelegramUsername); public const string SendPulseId = nameof(SendPulseId); diff --git a/src/Constants/README.md b/src/Constants/README.md index 34b34b9..304fb23 100644 --- a/src/Constants/README.md +++ b/src/Constants/README.md @@ -1,20 +1,21 @@ ---- -title: Telegram Constants -lastmod: 2023-03-23-11:06:58 -created: 2023-03-23-11:06:58 -license: MIT -tags: - - dgmjr - - telegram -categories: - - dgmjr - - readme -type: readme -slug: telegram-constants -project: Telegram -lastMod: 2023-03-24T10:45:25.122Z ---- - -# Telegram Constants - -This package contains constants for the Telegram API and usage of it. +--- + +title: Telegram Constants +lastmod: 2023-03-23-11:06:58 +created: 2023-03-23-11:06:58 +license: MIT +tags: +- DGMJR-IO +- telegram +categories: +- DGMJR-IO +- readme +type: readme +slug: telegram-constants +project: Telegram +lastMod: 2023-03-24T10:45:25.122Z +--------------------------------- + +# Telegram Constants + +This package contains constants for the Telegram API and usage of it. diff --git a/src/Constants/Telegram.Constants.csproj b/src/Constants/Telegram.Constants.csproj index 276ece9..9ff35ae 100644 --- a/src/Constants/Telegram.Constants.csproj +++ b/src/Constants/Telegram.Constants.csproj @@ -1,11 +1,11 @@ diff --git a/src/Constants/Telegram.Constants.targets b/src/Constants/Telegram.Constants.targets new file mode 100644 index 0000000..493ab54 --- /dev/null +++ b/src/Constants/Telegram.Constants.targets @@ -0,0 +1,17 @@ + + + + + + + diff --git a/src/EntityFrameworkCore/Abstractions/README.md b/src/EntityFrameworkCore/Abstractions/README.md index 600960c..f9b1c36 100644 --- a/src/EntityFrameworkCore/Abstractions/README.md +++ b/src/EntityFrameworkCore/Abstractions/README.md @@ -1,17 +1,19 @@ ---- -author: David G. Moore, Jr. -author_email: david@dgmjr.io -title: README.md -lastmod: 2023-03-23-09:48:24 -created: 2023-03-23-09:48:23 -license: MIT -tags: - - dgmjr - - efcore - - abstractions -categories: - - dgmjr - - abstractions ---- - -# # Telegram Abstractions for Entity Framework Core +--- + +author: David G. Moore, Jr. +author_email: david@dgmjr.io +title: README.md +lastmod: 2023-03-23-09:48:24 +created: 2023-03-23-09:48:23 +license: MIT +tags: +- DGMJR-IO +- efcore +- abstractions +categories: +- DGMJR-IO +- abstractions +-------------- + +# # Telegram Abstractions for Entity Framework Core + diff --git a/src/EntityFrameworkCore/Models/Bot.cs b/src/EntityFrameworkCore/Models/Bot.cs index 2eb6bb9..810cbde 100644 --- a/src/EntityFrameworkCore/Models/Bot.cs +++ b/src/EntityFrameworkCore/Models/Bot.cs @@ -1,30 +1,18 @@ -using System.Linq; -using System.Net.Http.Headers; -/* - * Bot.cs - * - * Created: 2023-03-19-03:05:09 - * Modified: 2023-03-25-03:14:09 - * - * Author: David G. Moore, Jr. - * - * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved - * License: MIT (https://opensource.org/licenses/MIT) - */ - /* * Bot.cs * - * Created: 2022-12-03-07:51:18 - * Modified: 2022-12-03-07:51:18 + * Created: 2023-03-19-02:05:09 + * Modified: 2023-05-29-07:03:56 * * Author: David G. Moore, Jr. * - * Copyright © 2022-2023 David G. Moore, Jr., All Rights Reserved + * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) */ namespace Telegram.Models; +using System.Linq; +using System.Net.Http.Headers; using System.Collections.ObjectModel; using global::Telegram.Bot.Types; using Telegram.Abstractions; @@ -41,23 +29,23 @@ public class Bot : Dgmjr.Identity.Models.User public class MyBot : Bot { public virtual BotApiToken ApiToken { get; set; } - public virtual UserClaim BotApiTokenClaim { get => this.Claims.FirstOrDefault(c -> c.Type == BotClaimTypes.BotApiToken); } + public virtual UserClaim BotApiTokenClaim { get => this.Claims.FirstOrDefault(c->c.Type == BotClaimTypes.BotApiToken); } } public class SendPulseBot : MyBot { public virtual ObjectId SendPulseId { get; set; } - public virtual UserClaim SendPulseIdClaim + public virtual UserClaim SendPulseIdClaim { - get => this.Claims.FirstOrDefault(c => c.Type == SendPulse.Identity.ClaimTypeNames.ObjectId); - set - { - if (this.SendPulseIdClaim != null) - { - this.Claims.Remove(this.SendPulseIdClaim); - } - this.Claims.Add(value); - } + get => this.Claims.FirstOrDefault(c => c.Type == SendPulse.Identity.ClaimTypeNames.ObjectId); + set + { + if (this.SendPulseIdClaim != null) + { + this.Claims.Remove(this.SendPulseIdClaim); + } + this.Claims.Add(value); + } } } diff --git a/src/EntityFrameworkCore/Models/README.md b/src/EntityFrameworkCore/Models/README.md index 2ad0946..eef768d 100644 --- a/src/EntityFrameworkCore/Models/README.md +++ b/src/EntityFrameworkCore/Models/README.md @@ -1,16 +1,18 @@ ---- -author: David G. Moore, Jr. -author_email: david@dgmjr.io -title: README.md -lastmod: 2023-03-23-09:46:46 -created: 2023-03-23-09:09:58 -license: MIT -tags: - - dgmjr - - models -categories: - - dgmjr - - models ---- - -# Telegram Models for Entity Framework Core +--- + +author: David G. Moore, Jr. +author_email: david@dgmjr.io +title: README.md +lastmod: 2023-03-23-09:46:46 +created: 2023-03-23-09:09:58 +license: MIT +tags: +- DGMJR-IO +- models +categories: +- DGMJR-IO +- models +-------- + +# Telegram Models for Entity Framework Core + diff --git a/src/EntityFrameworkCore/Models/Telegram.Bots.Models.csproj b/src/EntityFrameworkCore/Models/Telegram.Bots.Models.csproj index c7a047d..5068a81 100644 --- a/src/EntityFrameworkCore/Models/Telegram.Bots.Models.csproj +++ b/src/EntityFrameworkCore/Models/Telegram.Bots.Models.csproj @@ -1,11 +1,11 @@ diff --git a/src/Identity.WidgetLogin/Controllers/WeatherForecastController.cs b/src/Identity.WidgetLogin/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..24f81a9 --- /dev/null +++ b/src/Identity.WidgetLogin/Controllers/WeatherForecastController.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Mvc; + +namespace Telegram.Identity.WidgetLogin.Controllers; + +[ApiController] +[Route("[controller]")] +public class WeatherForecastController : ControllerBase +{ + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } +} diff --git a/src/Identity.WidgetLogin/Program.cs b/src/Identity.WidgetLogin/Program.cs new file mode 100644 index 0000000..15eacee --- /dev/null +++ b/src/Identity.WidgetLogin/Program.cs @@ -0,0 +1,25 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); diff --git a/src/Identity.WidgetLogin/Properties/launchSettings.json b/src/Identity.WidgetLogin/Properties/launchSettings.json new file mode 100644 index 0000000..4b51e39 --- /dev/null +++ b/src/Identity.WidgetLogin/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:3428", + "sslPort": 44383 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5240", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7296;http://localhost:5240", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/Identity.WidgetLogin/Telegram.Identity.WidgetLogin.csproj b/src/Identity.WidgetLogin/Telegram.Identity.WidgetLogin.csproj new file mode 100644 index 0000000..2184ee6 --- /dev/null +++ b/src/Identity.WidgetLogin/Telegram.Identity.WidgetLogin.csproj @@ -0,0 +1,15 @@ + + + + net7.0 + enable + enable + + + + + + + + + diff --git a/src/Identity.WidgetLogin/WeatherForecast.cs b/src/Identity.WidgetLogin/WeatherForecast.cs new file mode 100644 index 0000000..3c27897 --- /dev/null +++ b/src/Identity.WidgetLogin/WeatherForecast.cs @@ -0,0 +1,12 @@ +namespace Telegram.Identity.WidgetLogin; + +public class WeatherForecast +{ + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } +} diff --git a/src/Identity.WidgetLogin/appsettings.Development.json b/src/Identity.WidgetLogin/appsettings.Development.json new file mode 100644 index 0000000..ff66ba6 --- /dev/null +++ b/src/Identity.WidgetLogin/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/Identity.WidgetLogin/appsettings.json b/src/Identity.WidgetLogin/appsettings.json new file mode 100644 index 0000000..4d56694 --- /dev/null +++ b/src/Identity.WidgetLogin/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/Identity/ClaimType.cs b/src/Identity/ClaimType.cs index 83276f4..dc927c1 100644 --- a/src/Identity/ClaimType.cs +++ b/src/Identity/ClaimType.cs @@ -1,20 +1,20 @@ -/* +/* * ClaimType.cs - * + * * Created: 2023-03-30-12:25:07 * Modified: 2023-03-30-12:25:08 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) */ namespace Telegram.Identity; -public partial class ClaimType : Dgmjr.Identity.ClaimType +public partial class StrClaimType : Dgmjr.Identity.ClaimType { - public virtual bool Equals(ClaimType? other) + public virtual bool Equals(StrClaimTypes? other) { return base.Equals(other); } diff --git a/src/Identity/ClaimTypeNames.cs b/src/Identity/ClaimTypeNames.cs index 8cf06fe..0299bef 100644 --- a/src/Identity/ClaimTypeNames.cs +++ b/src/Identity/ClaimTypeNames.cs @@ -1,47 +1,60 @@ -/* +/* * Claims.cs - * + * * Created: 2023-03-19-02:53:23 * Modified: 2023-03-23-11:30:12 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) - */ + */ namespace Telegram.Identity; -public static partial class ClaimTypeUris +public static partial class StrClaimTypes { /// The base URI for Telegram - /// https://telegram.org/ public const string BaseUri = "https://telegram.org/"; - /// The base URI for Telegram identity - - /// - public const string Identity = BaseUri + Namespaces.Identity; + /// The base URI for Telegram identity - + /// + public const string Identity = + BaseUri + global::Telegram.Identity.StrClaimTypes.Namespaces.Identity; + // /// The URI for the Telegram user ID claim type. // /// // public const string UserIdClaim = Identity + UriFragments.UserId; - /// The URI for the Telegram claim type. - /// - public const string Username = Identity + ClaimTypeUris.UriFragments.Username; - /// The URI for the Telegram claim type. - /// - public const string UserId = Identity + ClaimTypeUris.UriFragments.UserId; - /// The URI for the Telegram claim type. - /// - public const string CanJoinGroups = Identity + ClaimTypeUris.UriFragments.CanJoinGroups; - /// The URI for the Telegram claim type. - /// - public const string IsBot = Identity + ClaimTypeUris.UriFragments.IsBot; - /// The URI for the Telegram claim type. - /// - public const string LanguageCode = Identity + ClaimTypeUris.UriFragments.LanguageCode; - /// The URI for the Telegram claim type. - /// - public const string BotApiToken = Identity + ClaimTypeUris.UriFragments.BotApiToken; + /// The URI for the Telegram claim type. + /// + public const string Username = + Identity + global::Telegram.Identity.StrClaimTypes.UriFragments.Username; + + /// The URI for the Telegram claim type. + /// + public const string UserId = + Identity + global::Telegram.Identity.StrClaimTypes.UriFragments.UserId; + + /// The URI for the Telegram claim type. + /// + public const string CanJoinGroups = + Identity + global::Telegram.Identity.StrClaimTypes.UriFragments.CanJoinGroups; + + /// The URI for the Telegram claim type. + /// + public const string IsBot = + Identity + global::Telegram.Identity.StrClaimTypes.StrClaimTypes.UriFragments.IsBot; + + /// The URI for the Telegram claim type. + /// + public const string LanguageCode = + Identity + global::Telegram.Identity.trClaimTypes.UriFragments.LanguageCode; + + /// The URI for the Telegram claim type. + /// + public const string BotApiToken = + Identity + global::Telegram.Identity.StrClaimTypes.UriFragments.BotApiToken; } // [GenerateEnumerationRecordStruct("ClaimType")] diff --git a/src/Identity/ClaimTypeUris.cs b/src/Identity/ClaimTypeUris.cs index ced9528..5eaa307 100644 --- a/src/Identity/ClaimTypeUris.cs +++ b/src/Identity/ClaimTypeUris.cs @@ -11,7 +11,8 @@ */ namespace Telegram.Identity; -public static partial class ClaimTypeUris + +public static partial class StrClaimTypes { // public static class ClaimTypeUris // { diff --git a/src/Identity/ClaimTypeValueNames.cs b/src/Identity/ClaimTypeValueNames.cs index 39800b4..8c3d480 100644 --- a/src/Identity/ClaimTypeValueNames.cs +++ b/src/Identity/ClaimTypeValueNames.cs @@ -1,29 +1,22 @@ -/* +/* * Claims.cs - * + * * Created: 2023-03-19-02:53:23 * Modified: 2023-03-23-11:30:12 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) - */ + */ namespace Telegram.Identity; -public static partial class ClaimTypeValueUris +public static partial class StrClaimTypes { - /// The base URI for Telegram values- - /// value/ - public const string BaseUri = ClaimTypeUris.Identity + ClaimTypeUris.Namespaces.Values; - - /// The URI for the Telegram claim value type. - /// - public const string LanguageCode = BaseUri + ClaimTypeUris.UriFragments.LanguageCode; - /// The URI for the Telegram claim value type. - /// - public const string BotApiToken = BaseUri + ClaimTypeUris.UriFragments.BotApiToken; + /// The URI for the Telegram claim value type. + /// + public const string BotApiToken = Identity + UriFragments.BotApiToken; } // [GenerateEnumerationRecordStruct("ClaimType")] diff --git a/src/Identity/Enums/ClaimType.cs b/src/Identity/Enums/ClaimType.cs index ff0ace6..7c90585 100644 --- a/src/Identity/Enums/ClaimType.cs +++ b/src/Identity/Enums/ClaimType.cs @@ -1,52 +1,64 @@ -/* +/* * ClaimType.cs - * + * * Created: 2023-03-25-01:51:33 * Modified: 2023-03-25-01:51:34 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) */ namespace Telegram.Identity.Enums; using System.ComponentModel.DataAnnotations; +using Telegram.Identity; [GenerateEnumerationClass("ClaimType", "Telegram.Identity")] public enum ClaimType { - /// + /// [Display(Name = "Base URI", Description = "The base URI for Telegram")] - [Uri(ClaimTypeNames.BaseUri)] + [Uri(StrClaimTypes.BaseUri)] BaseUri, - /// + + /// [Display(Name = "Identity", Description = "The base URI for Telegram identity claims")] - [Uri(ClaimTypeNames.Identity)] + [Uri(StrClaimTypes.Identity)] Identity, + // /// // [Display(Name = "Base URI", Description = "The base URI for Telegram")] // [Uri(ClaimTypes.UserIdClaim)] // UserIdClaim, - /// + /// [Display(Name = "Base URI", Description = "The base URI for Telegram")] - [Uri(ClaimTypeNames.Username)] + [Uri(StrClaimTypes.Username)] Username, - /// + + /// [Display(Name = "Base URI", Description = "The base URI for Telegram")] - [Uri(ClaimTypeNames.UserId)] + [Uri(StrClaimTypes.UserId)] UserId, - /// + + /// [Display(Name = "Can join groups", Description = "Whether a bot can join groups")] - [Uri(ClaimTypeNames.CanJoinGroups)] + [Uri(StrClaimTypes.CanJoinGroups)] CanJoinGroups, - /// - [Display(Name = "Language code", Description = "The language code for the user's preferred language")] - [Uri(ClaimTypeNames.LanguageCode)] + + /// + [Display( + Name = "Language code", + Description = "The language code for the user's preferred language" + )] + [Uri(StrClaimTypes.LanguageCode)] LanguageCode, - /// - [Display(Name = "Bot API Token", Description = "The super secret \"key\" that allows this bot to talk to the Telegram API")] - [Uri(ClaimTypeNames.BotApiToken)] + /// + [Display( + Name = "Bot API Token", + Description = "The super secret \"key\" that allows this bot to talk to the Telegram API" + )] + [Uri(StrClaimTypes.BotApiToken)] BotApiToken } diff --git a/src/Identity/Enums/ClaimValueType.cs b/src/Identity/Enums/ClaimValueType.cs index 6da6801..a0c03ae 100644 --- a/src/Identity/Enums/ClaimValueType.cs +++ b/src/Identity/Enums/ClaimValueType.cs @@ -1,30 +1,35 @@ -/* +/* * ClaimType.cs - * + * * Created: 2023-03-25-01:51:33 * Modified: 2023-03-25-01:51:34 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) */ namespace Telegram.Identity.Enums; using System.ComponentModel.DataAnnotations; +using ClaimType = Telegram.Identity.StrClaimTypes; [GenerateEnumerationClass("ClaimValueType", "Telegram.Identity")] public enum ClaimValueType { - /// The base type for the Telegram claim value type - - /// + /// The base type for the Telegram claim value type - + /// [Display(Name = "Base URI", Description = "The base URI for Telegram claim value types")] - [Uri(ClaimTypeNames.Identity)] + [Uri(ClaimType.Identity)] BaseUri, - - /// - [Display(Name = "Bot API Token", ShortName = nameof(BotApiToken), Description = "The super secret \"key\" that allows this bot to talk to the Telegram API")] - [Uri(ClaimTypeNames.BotApiToken)] + /// + /// + [Display( + Name = "Bot API Token", + ShortName = nameof(BotApiToken), + Description = "The super secret \"key\" that allows this bot to talk to the Telegram API" + )] + [Uri(ClaimType.BotApiToken)] BotApiToken } diff --git a/src/Identity/Namespaces.cs b/src/Identity/Namespaces.cs index 40c5a07..caf92df 100644 --- a/src/Identity/Namespaces.cs +++ b/src/Identity/Namespaces.cs @@ -12,14 +12,14 @@ namespace Telegram.Identity; -public static partial class ClaimTypeUris +public static partial class StrClaimTypes { public static class Namespaces { /// The namespace for Telegram identity. /// identity/ public const string Identity = "identity/"; - + /// The namespace for Telegram claim value types. /// values/ public const string Values = "values/"; diff --git a/src/Identity/README.md b/src/Identity/README.md index 336a36e..ec01344 100644 --- a/src/Identity/README.md +++ b/src/Identity/README.md @@ -1,23 +1,25 @@ ---- -authors: - - dgmjr -title: Telegram Identity -lastmod: 2023-04-12T10:47:29.315Z -created: 2023-03-27-08:50:54 -license: MIT -keywords: - - DGMJR - - Identity - - Telegram -categories: - - Telegram - - Identity -type: readme -slug: telegram-identity -draft: true -date: 2023-03-28T01:09:56.305Z -project: Telegram -description: A project containing mostly user claims for Telegram ---- - -# Telegram Identity +--- + +authors: +- DGMJR-IO +title: Telegram Identity +lastmod: 2023-04-12T10:47:29.315Z +created: 2023-03-27-08:50:54 +license: MIT +keywords: +- DGMJR-IO +- Identity +- Telegram +categories: +- Telegram +- Identity +type: readme +slug: telegram-identity +draft: true +date: 2023-03-28T01:09:56.305Z +project: Telegram +description: A project containing mostly user claims for Telegram +----------------------------------------------------------------- + +# Telegram Identity + diff --git a/src/Identity/UriFragments.cs b/src/Identity/UriFragments.cs index 7ff152b..37b993e 100644 --- a/src/Identity/UriFragments.cs +++ b/src/Identity/UriFragments.cs @@ -1,11 +1,11 @@ -/* +/* * UriFragments.cs - * + * * Created: 2023-03-19-02:53:23 * Modified: 2023-03-23-11:31:36 - * + * * Author: David G. Moore, Jr. - * + * * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved * License: MIT (https://opensource.org/licenses/MIT) */ @@ -13,16 +13,18 @@ namespace Telegram.Identity; -public static partial class ClaimTypeUris +public static partial class StrClaimTypes { public static class UriFragments { /// A URI fragment for /// user_id/ public const string UserId = "user_id/"; + /// A URI fragment for /// username/ public const string Username = "username/"; + // / A URI fragment for // / givenname/ // public const string GivenName = "givenname/"; @@ -34,18 +36,23 @@ public static class UriFragments /// A URI fragment for /// language_code/ public const string LanguageCode = "language_code/"; + /// A URI fragment for /// is_bot/ public const string IsBot = "is_bot/"; + /// A URI fragment for /// can_join_groups/ public const string CanJoinGroups = "can_join_groups/"; + /// A URI fragment for /// can_read_all_group_messages/ public const string CanReadAllGroupMessages = "can_read_all_group_messages/"; + /// A URI fragment for /// supports_inline_queries/ public const string SupportsInlineQueries = "supports_inline_queries/"; + /// A URI fragment for /// bot_api_token/ public const string BotApiToken = "bot_api_token/"; diff --git a/src/UserBot/Config/IUSerBotConfig.cs b/src/UserBot/Config/IUSerBotConfig.cs new file mode 100644 index 0000000..4f3a758 --- /dev/null +++ b/src/UserBot/Config/IUSerBotConfig.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Telegram.UserBot.Store.Abstractions; + +namespace Telegram.UserBot.Config +{ + public partial interface IUserBotConfig + { + IUserBotStore? GetSessionStore(); + string? GetConfigVariable(string variable); + string Prompt(string variable); + } +} \ No newline at end of file diff --git a/src/UserBot/Config/PersistTo.cs b/src/UserBot/Config/PersistTo.cs new file mode 100644 index 0000000..4f2a3f5 --- /dev/null +++ b/src/UserBot/Config/PersistTo.cs @@ -0,0 +1,9 @@ +namespace Telegram.UserBot; + +[GenerateEnumerationRecordStruct("PersistToWhere")] +public enum PersistTo +{ + Memory = 0, + File = 1, + Database = 2 +} \ No newline at end of file diff --git a/src/UserBot/Config/Telegram.UserBot.Config.csproj b/src/UserBot/Config/Telegram.UserBot.Config.csproj new file mode 100644 index 0000000..cdec461 --- /dev/null +++ b/src/UserBot/Config/Telegram.UserBot.Config.csproj @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/UserBot/Config/UserBotConfig.cs b/src/UserBot/Config/UserBotConfig.cs new file mode 100644 index 0000000..898982e --- /dev/null +++ b/src/UserBot/Config/UserBotConfig.cs @@ -0,0 +1,81 @@ +using System; + +namespace Telegram.UserBot.Config; +using Telegram.UserBot.Store.Abstractions; +using Telegram.UserBot.Store; +using static Environment; +using Microsoft.EntityFrameworkCore; + +public class UserBotConfig +{ + public const string api_hash = nameof(api_hash); + public const string api_id = nameof(api_id); + public const string verification_code = nameof(verification_code); + public const string first_name = nameof(first_name); + public const string last_name = nameof(last_name); + public const string password = nameof(password); + public const string persist_to = nameof(persist_to); + public const string db_conection_string = nameof(db_conection_string); + public const string session_pathname = nameof(session_pathname); + + public virtual string Prompt(string variable) + { + Write($"Enter {variable}: "); + return ReadLine(); + } + + public string? GetConfigVariable(string variable) => + variable switch + { + api_id => (ApiId = long.Parse(ApiId.ToString() ?? Prompt(api_id))).ToString(), + api_hash => ApiHash ??= Prompt(api_hash), + verification_code => VerificationCode ??= Prompt(verification_code), + first_name => FirstName ??= Prompt(first_name), + last_name => LastName ??= Prompt(last_name), + password => Password ??= Prompt(password), + persist_to => PersistTo.ToString(), + db_conection_string => DbConectionString, + session_pathname => SessionPathname, + _ => Prompt(variable) + }; + + public IUserBotStore? GetSessionStore() + { + return PersistTo switch + { + PersistTo.Memory => new MemoryUserBotStore(), + PersistTo.File => new FileUserBotStore(SessionPathname), + PersistTo.Database => new DbUserBotStore(new UserBotDbContext(new DbContextOptionsBuilder().UseSqlServer(DbConectionString).Options), SessionPathname), + _ => null, + }; + } + + [JProp((persist_to))] + public PersistTo PersistTo { get; set; } = + PersistToWhere.TryParse(GetEnvironmentVariable(persist_to), out var @enum) ? @enum.Value : default; + + [JProp(db_conection_string)] + public string DbConectionString { get; set; } = GetEnvironmentVariable(db_conection_string); + + [JProp(api_id)] + public long ApiId { get; set; } = + long.TryParse(GetEnvironmentVariable(api_id), out var @long) ? @long : default; + + [JProp(api_hash)] + public string ApiHash { get; set; } = GetEnvironmentVariable(api_hash); + + [JProp(verification_code)] + public string VerificationCode { get; set; } = GetEnvironmentVariable(verification_code); + + [JProp(first_name)] + public string FirstName { get; set; } = GetEnvironmentVariable(first_name); + + [JProp(last_name)] + public string LastName { get; set; } = GetEnvironmentVariable(last_name); + + [JProp(password)] + public string Password { get; set; } = GetEnvironmentVariable(password); + + [JProp(session_pathname)] + public string SessionPathname { get; set; } = GetEnvironmentVariable(session_pathname); +} diff --git a/src/UserBot/Models/Telegram.UserBot.Models.csproj b/src/UserBot/Models/Telegram.UserBot.Models.csproj new file mode 100644 index 0000000..c86f99e --- /dev/null +++ b/src/UserBot/Models/Telegram.UserBot.Models.csproj @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/src/UserBot/Models/Telegram.UserBot.Models.sln b/src/UserBot/Models/Telegram.UserBot.Models.sln new file mode 100644 index 0000000..baf0520 --- /dev/null +++ b/src/UserBot/Models/Telegram.UserBot.Models.sln @@ -0,0 +1,62 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" + ProjectSection(SolutionItems) = preProject + ..\..\..\..\..\Packages\Versions.props = ..\..\..\..\..\Packages\Versions.props + ..\..\..\..\..\Packages\Versions.Local.json = ..\..\..\..\..\Packages\Versions.Local.json + ..\..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\..\Packages\Versions.Local.props + ..\..\..\..\..\Packages\Packages.pkgs = ..\..\..\..\..\Packages\Packages.pkgs + ..\..\..\..\..\Packages\Packages\AnyOf.pkgs = ..\..\..\..\..\Packages\Packages\AnyOf.pkgs + ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs = ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs + ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs = ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs + ..\..\..\..\..\Packages\Packages\Azure.pkgs = ..\..\..\..\..\Packages\Packages\Azure.pkgs + ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs = ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs + ..\..\..\..\..\Packages\Packages\DDD.pkgs = ..\..\..\..\..\Packages\Packages\DDD.pkgs + ..\..\..\..\..\Packages\Packages\EFCore.pkgs = ..\..\..\..\..\Packages\Packages\EFCore.pkgs + ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs = ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs + ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs = ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs + ..\..\..\..\..\Packages\Packages\Images.pkgs = ..\..\..\..\..\Packages\Packages\Images.pkgs + ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs = ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs + ..\..\..\..\..\Packages\Packages\MediatR.pkgs = ..\..\..\..\..\Packages\Packages\MediatR.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs + ..\..\..\..\..\Packages\Packages\Miscellany.pkgs = ..\..\..\..\..\Packages\Packages\Miscellany.pkgs + ..\..\..\..\..\Packages\Packages\MSBuild.pkgs = ..\..\..\..\..\Packages\Packages\MSBuild.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs + ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs = ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs + ..\..\..\..\..\Packages\Packages\NuGet.pkgs = ..\..\..\..\..\Packages\Packages\NuGet.pkgs + ..\..\..\..\..\Packages\Packages\Powershell.pkgs = ..\..\..\..\..\Packages\Packages\Powershell.pkgs + ..\..\..\..\..\Packages\Packages\Roslyn.pkgs = ..\..\..\..\..\Packages\Packages\Roslyn.pkgs + ..\..\..\..\..\Packages\Packages\Serilog.pkgs = ..\..\..\..\..\Packages\Packages\Serilog.pkgs + ..\..\..\..\..\Packages\Packages\SlnGen.pkgs = ..\..\..\..\..\Packages\Packages\SlnGen.pkgs + ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs = ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs + ..\..\..\..\..\Packages\Packages\System.pkgs = ..\..\..\..\..\Packages\Packages\System.pkgs + ..\..\..\..\..\Packages\Packages\Telegram.pkgs = ..\..\..\..\..\Packages\Packages\Telegram.pkgs + ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs = ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs + ..\..\..\..\..\Packages\Packages\Testing.pkgs = ..\..\..\..\..\Packages\Packages\Testing.pkgs + ..\..\..\..\..\Packages\Packages\Validation.pkgs = ..\..\..\..\..\Packages\Packages\Validation.pkgs + ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs = ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs + ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props = ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props + ..\..\..\..\..\Packages\Versions\AutoMapper.props = ..\..\..\..\..\Packages\Versions\AutoMapper.props + ..\..\..\..\..\Packages\Versions\EFCore.props = ..\..\..\..\..\Packages\Versions\EFCore.props + ..\..\..\..\..\Packages\Versions\JsonPatch.props = ..\..\..\..\..\Packages\Versions\JsonPatch.props + ..\..\..\..\..\Packages\Versions\MediatR.props = ..\..\..\..\..\Packages\Versions\MediatR.props + ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props = ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props + ..\..\..\..\..\Packages\Versions\MSBuild.props = ..\..\..\..\..\Packages\Versions\MSBuild.props + ..\..\..\..\..\Packages\Versions\PowerShell.props = ..\..\..\..\..\Packages\Versions\PowerShell.props + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {34AEC6E0-26BA-4EC9-BC2B-324A902A941D} + EndGlobalSection +EndGlobal diff --git a/src/UserBot/Models/UserTelegramSession.cs b/src/UserBot/Models/UserTelegramSession.cs new file mode 100644 index 0000000..ea36062 --- /dev/null +++ b/src/UserBot/Models/UserTelegramSession.cs @@ -0,0 +1,12 @@ +namespace Telegram.UserBot.Models; + +public class UserTelegramSession +{ + public long Id { get; set; } + + public string SessionName { get; set; } + + public byte[] Session { get; set; } + + public bool IsActive { get; set; } +} diff --git a/src/UserBot/Store/DbUserBotStore.cs b/src/UserBot/Store/DbUserBotStore.cs new file mode 100644 index 0000000..afa92aa --- /dev/null +++ b/src/UserBot/Store/DbUserBotStore.cs @@ -0,0 +1,115 @@ +namespace Telegram.UserBot.Store; +using Telegram.UserBot.Store.Abstractions; +using Telegram.UserBot.Models; + + +internal class DbUserBotStore : Stream, IUserBotStore +{ + private readonly UserBotDbContext _dbContext; + private readonly string _sessionName; + private byte[] _data; + private int _dataLen; + private DateTime _lastWrite; + private Task _delayedWrite; + + public Stream GetStream() => this; + + public DbUserBotStore(UserBotDbContext dbContext, string sessionName = null) + { + _dbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + _sessionName = sessionName ?? "DefaultSession"; + + var session = _dbContext.UserTelegramSessions.FirstOrDefault( + s => s.SessionName == _sessionName + ); + + if (session != null) + { + _dataLen = (_data = session.Session).Length; + } + else + { + // Create a new session with empty data + var newSession = new UserTelegramSession() + { + SessionName = _sessionName, + Session = Array.Empty(), + IsActive = true + }; + + _dbContext.UserTelegramSessions.Add(newSession); + _dbContext.SaveChanges(); + } + } + + protected override void Dispose(bool disposing) + { + // Wait for any delayed write to complete before disposing the context + _delayedWrite?.Wait(); + + base.Dispose(disposing); + } + + public override int Read(byte[] buffer, int offset, int count) + { + Array.Copy(_data, 0, buffer, offset, count); + + return count; + } + + public override void Write(byte[] buffer, int offset, int count) // Write call and buffer modifications are done within a lock() + { + _data = buffer; + _dataLen = count; + + if (_delayedWrite != null) + return; + + var left = 1000 - (int)(DateTime.UtcNow - _lastWrite).TotalMilliseconds; + + if (left < 0) + { + var sessionToUpdate = _dbContext.UserTelegramSessions.FirstOrDefault( + s => s.SessionName == _sessionName + ); + + sessionToUpdate.Session = + count == buffer.Length ? buffer : buffer[offset..(offset + count)]; + + _dbContext.SaveChanges(); + + _lastWrite = DateTime.UtcNow; + } + else // delay writings for a full second + _delayedWrite = Task.Delay(left) + .ContinueWith(t => + { + lock (this) + { + _delayedWrite = null; + Write(_data, 0, _dataLen); + } + }); + } + + public override long Length => _dataLen; + + public override long Position + { + get => 0; + set { } + } + + + public override bool CanSeek => false; + + public override bool CanRead => true; + + public override bool CanWrite => true; + + public override long Seek(long offset, SeekOrigin origin) => 0; + + public override void SetLength(long value) { } + + public override void Flush() { } +} \ No newline at end of file diff --git a/src/UserBot/Store/FileUserBotStore.cs b/src/UserBot/Store/FileUserBotStore.cs new file mode 100644 index 0000000..acc6c68 --- /dev/null +++ b/src/UserBot/Store/FileUserBotStore.cs @@ -0,0 +1,22 @@ +namespace Telegram.UserBot.Store; +using Telegram.UserBot.Store.Abstractions; + +internal class FileUserBotStore : IUserBotStore +{ + private readonly string _filePath; + + public FileUserBotStore(string? filePath = null) + { + _filePath = filePath ?? Path.Join(Environment.CurrentDirectory, "session.dat"); + + if (!File.Exists(_filePath)) + { + File.Create(_filePath).Close(); + } + } + + public Stream GetStream() + { + return new FileStream(_filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite); + } +} diff --git a/src/UserBot/Store/IUserBotDbContext.cs b/src/UserBot/Store/IUserBotDbContext.cs new file mode 100644 index 0000000..0bf16cf --- /dev/null +++ b/src/UserBot/Store/IUserBotDbContext.cs @@ -0,0 +1,7 @@ +namespace Telegram.UserBot.Store.Abstractions; +using Microsoft.EntityFrameworkCore.Abstractions; + +[GenerateInterfaceAttribute(typeof(UserBotDbContext))] +public partial interface IUserBotDbContext : IDbContext +{ +} diff --git a/src/UserBot/Store/IUserBotStore.cs b/src/UserBot/Store/IUserBotStore.cs new file mode 100644 index 0000000..8dab945 --- /dev/null +++ b/src/UserBot/Store/IUserBotStore.cs @@ -0,0 +1,6 @@ +namespace Telegram.UserBot.Store.Abstractions; + +public partial interface IUserBotStore +{ + Stream GetStream(); +} diff --git a/src/UserBot/Store/MemoryUserBotStore.cs b/src/UserBot/Store/MemoryUserBotStore.cs new file mode 100644 index 0000000..8d6b8e6 --- /dev/null +++ b/src/UserBot/Store/MemoryUserBotStore.cs @@ -0,0 +1,17 @@ +namespace Telegram.UserBot.Store; +using Telegram.UserBot.Store.Abstractions; + +internal class MemoryUserBotStore : IUserBotStore +{ + private readonly MemoryStream _stream; + + public MemoryUserBotStore() + { + _stream = new MemoryStream(); + } + + public Stream GetStream() + { + return _stream; + } +} diff --git a/src/UserBot/Store/Telegram.UserBot.Store.csproj b/src/UserBot/Store/Telegram.UserBot.Store.csproj new file mode 100644 index 0000000..b9a37b7 --- /dev/null +++ b/src/UserBot/Store/Telegram.UserBot.Store.csproj @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/UserBot/Store/Telegram.UserBot.Store.sln b/src/UserBot/Store/Telegram.UserBot.Store.sln new file mode 100644 index 0000000..aeafe89 --- /dev/null +++ b/src/UserBot/Store/Telegram.UserBot.Store.sln @@ -0,0 +1,62 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" + ProjectSection(SolutionItems) = preProject + ..\..\..\..\..\Packages\Versions.props = ..\..\..\..\..\Packages\Versions.props + ..\..\..\..\..\Packages\Versions.Local.json = ..\..\..\..\..\Packages\Versions.Local.json + ..\..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\..\Packages\Versions.Local.props + ..\..\..\..\..\Packages\Packages.pkgs = ..\..\..\..\..\Packages\Packages.pkgs + ..\..\..\..\..\Packages\Packages\AnyOf.pkgs = ..\..\..\..\..\Packages\Packages\AnyOf.pkgs + ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs = ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs + ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs = ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs + ..\..\..\..\..\Packages\Packages\Azure.pkgs = ..\..\..\..\..\Packages\Packages\Azure.pkgs + ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs = ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs + ..\..\..\..\..\Packages\Packages\DDD.pkgs = ..\..\..\..\..\Packages\Packages\DDD.pkgs + ..\..\..\..\..\Packages\Packages\EFCore.pkgs = ..\..\..\..\..\Packages\Packages\EFCore.pkgs + ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs = ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs + ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs = ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs + ..\..\..\..\..\Packages\Packages\Images.pkgs = ..\..\..\..\..\Packages\Packages\Images.pkgs + ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs = ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs + ..\..\..\..\..\Packages\Packages\MediatR.pkgs = ..\..\..\..\..\Packages\Packages\MediatR.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs + ..\..\..\..\..\Packages\Packages\Miscellany.pkgs = ..\..\..\..\..\Packages\Packages\Miscellany.pkgs + ..\..\..\..\..\Packages\Packages\MSBuild.pkgs = ..\..\..\..\..\Packages\Packages\MSBuild.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs + ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs = ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs + ..\..\..\..\..\Packages\Packages\NuGet.pkgs = ..\..\..\..\..\Packages\Packages\NuGet.pkgs + ..\..\..\..\..\Packages\Packages\Powershell.pkgs = ..\..\..\..\..\Packages\Packages\Powershell.pkgs + ..\..\..\..\..\Packages\Packages\Roslyn.pkgs = ..\..\..\..\..\Packages\Packages\Roslyn.pkgs + ..\..\..\..\..\Packages\Packages\Serilog.pkgs = ..\..\..\..\..\Packages\Packages\Serilog.pkgs + ..\..\..\..\..\Packages\Packages\SlnGen.pkgs = ..\..\..\..\..\Packages\Packages\SlnGen.pkgs + ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs = ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs + ..\..\..\..\..\Packages\Packages\System.pkgs = ..\..\..\..\..\Packages\Packages\System.pkgs + ..\..\..\..\..\Packages\Packages\Telegram.pkgs = ..\..\..\..\..\Packages\Packages\Telegram.pkgs + ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs = ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs + ..\..\..\..\..\Packages\Packages\Testing.pkgs = ..\..\..\..\..\Packages\Packages\Testing.pkgs + ..\..\..\..\..\Packages\Packages\Validation.pkgs = ..\..\..\..\..\Packages\Packages\Validation.pkgs + ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs = ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs + ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props = ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props + ..\..\..\..\..\Packages\Versions\AutoMapper.props = ..\..\..\..\..\Packages\Versions\AutoMapper.props + ..\..\..\..\..\Packages\Versions\EFCore.props = ..\..\..\..\..\Packages\Versions\EFCore.props + ..\..\..\..\..\Packages\Versions\JsonPatch.props = ..\..\..\..\..\Packages\Versions\JsonPatch.props + ..\..\..\..\..\Packages\Versions\MediatR.props = ..\..\..\..\..\Packages\Versions\MediatR.props + ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props = ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props + ..\..\..\..\..\Packages\Versions\MSBuild.props = ..\..\..\..\..\Packages\Versions\MSBuild.props + ..\..\..\..\..\Packages\Versions\PowerShell.props = ..\..\..\..\..\Packages\Versions\PowerShell.props + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {2E24D899-12EE-4CF0-A743-07786B8796BC} + EndGlobalSection +EndGlobal diff --git a/src/UserBot/Store/UserBotDbContext.cs b/src/UserBot/Store/UserBotDbContext.cs new file mode 100644 index 0000000..bf3fd52 --- /dev/null +++ b/src/UserBot/Store/UserBotDbContext.cs @@ -0,0 +1,31 @@ +namespace Telegram.UserBot.Store; +using Telegram.UserBot.Store.Abstractions; +using Telegram.UserBot.Models; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Abstractions; + +public class UserBotDbContext : DbContext, IUserBotDbContext +{ + public const string Schema = "userbots"; + public const string TableName = "tbl_TelegramSession"; + public const string VarBinaryMax = "varbinary(max)"; + + public UserBotDbContext(DbContextOptions options) : base(options) + { + } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(entity => + { + entity.ToTable(TableName, Schema); + entity.Property(e => e.Id); + entity.HasKey(e => e.SessionName); + entity.Property(e => e.SessionName).IsRequired(); + entity.Property(e => e.Session).HasColumnType(VarBinaryMax).IsRequired(); + entity.Property(e => e.IsActive).HasDefaultValue(true).IsRequired(); + }); + } + + public virtual DbSet UserTelegramSessions { get; set; } +} diff --git a/src/UserBot/UserBot.Api/Controllers/UserBotController.cs b/src/UserBot/UserBot.Api/Controllers/UserBotController.cs new file mode 100644 index 0000000..d47b788 --- /dev/null +++ b/src/UserBot/UserBot.Api/Controllers/UserBotController.cs @@ -0,0 +1,32 @@ +namespace Telegram.UserBot.Api; +using Microsoft.AspNetCore.Mvc; +using System.ComponentModel.DataAnnotations; +using TL; + +[Route("api/users")] +public class UserBotUsersController : Dgmjr.AspNetCore.Controllers.ApiControllerBase +{ + private readonly UserBot _bot; + + public UserBotUsersController(ILogger logger, UserBot bot) : base(logger) + { + _bot = bot; + } + + [HttpGet("{userId:long}")] + public virtual ResponsePayload GetById([FromRoute] long userId) + { + return _bot.Users.TryGetValue(userId, out var user) ? new ResponsePayload(user) : ResponsePayload.NotFound(); + } + + [HttpGet("@{username}")] + public virtual ResponsePayload GetUserByUsername([FromRoute] string username) + { + var user = _bot.Users.FirstOrDefault(u => u.Value.username?.Equals(username, OrdinalIgnoreCase) ?? false).Value; + if(user != null) + { + return new ResponsePayload(user); + } + return ResponsePayload.NotFound(); + } +} diff --git a/src/UserBot/UserBot.Api/Program.cs b/src/UserBot/UserBot.Api/Program.cs new file mode 100644 index 0000000..71682c8 --- /dev/null +++ b/src/UserBot/UserBot.Api/Program.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Azure.Identity; +using Telegram.UserBot; + +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.AddTheWorks(new StartupParametersBuilder() + .WithAddAzureAppConfig(true) + .WithAzureKeyVaultConfigurator(kv => kv.SetCredential(new DefaultCredential()))//(kv => kv.) + .Build()); +builder.AddUserBot(); + +var app = builder.Build(); + +app.UseTheWorks(); + +app.Run(); diff --git a/src/UserBot/UserBot.Api/Properties/launchSettings.json b/src/UserBot/UserBot.Api/Properties/launchSettings.json new file mode 100644 index 0000000..8fabffe --- /dev/null +++ b/src/UserBot/UserBot.Api/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:37542", + "sslPort": 44311 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5166", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7137;http://localhost:5166", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/UserBot/UserBot.Api/Telegram.UserBot.Api.csproj b/src/UserBot/UserBot.Api/Telegram.UserBot.Api.csproj new file mode 100644 index 0000000..0df54e0 --- /dev/null +++ b/src/UserBot/UserBot.Api/Telegram.UserBot.Api.csproj @@ -0,0 +1,18 @@ + + + + net7.0 + enable + enable + true + e6b186e0-e9c0-45e1-a0e0-caaf78d8b2d5 + + + + + + + + + + diff --git a/src/UserBot/UserBot.Api/Telegram.UserBot.Api.sln b/src/UserBot/UserBot.Api/Telegram.UserBot.Api.sln new file mode 100644 index 0000000..3fd3c84 --- /dev/null +++ b/src/UserBot/UserBot.Api/Telegram.UserBot.Api.sln @@ -0,0 +1,62 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" + ProjectSection(SolutionItems) = preProject + ..\..\..\..\..\Packages\Versions.props = ..\..\..\..\..\Packages\Versions.props + ..\..\..\..\..\Packages\Versions.Local.json = ..\..\..\..\..\Packages\Versions.Local.json + ..\..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\..\Packages\Versions.Local.props + ..\..\..\..\..\Packages\Packages.pkgs = ..\..\..\..\..\Packages\Packages.pkgs + ..\..\..\..\..\Packages\Packages\AnyOf.pkgs = ..\..\..\..\..\Packages\Packages\AnyOf.pkgs + ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs = ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs + ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs = ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs + ..\..\..\..\..\Packages\Packages\Azure.pkgs = ..\..\..\..\..\Packages\Packages\Azure.pkgs + ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs = ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs + ..\..\..\..\..\Packages\Packages\DDD.pkgs = ..\..\..\..\..\Packages\Packages\DDD.pkgs + ..\..\..\..\..\Packages\Packages\EFCore.pkgs = ..\..\..\..\..\Packages\Packages\EFCore.pkgs + ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs = ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs + ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs = ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs + ..\..\..\..\..\Packages\Packages\Images.pkgs = ..\..\..\..\..\Packages\Packages\Images.pkgs + ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs = ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs + ..\..\..\..\..\Packages\Packages\MediatR.pkgs = ..\..\..\..\..\Packages\Packages\MediatR.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs + ..\..\..\..\..\Packages\Packages\Miscellany.pkgs = ..\..\..\..\..\Packages\Packages\Miscellany.pkgs + ..\..\..\..\..\Packages\Packages\MSBuild.pkgs = ..\..\..\..\..\Packages\Packages\MSBuild.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs + ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs = ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs + ..\..\..\..\..\Packages\Packages\NuGet.pkgs = ..\..\..\..\..\Packages\Packages\NuGet.pkgs + ..\..\..\..\..\Packages\Packages\Powershell.pkgs = ..\..\..\..\..\Packages\Packages\Powershell.pkgs + ..\..\..\..\..\Packages\Packages\Roslyn.pkgs = ..\..\..\..\..\Packages\Packages\Roslyn.pkgs + ..\..\..\..\..\Packages\Packages\Serilog.pkgs = ..\..\..\..\..\Packages\Packages\Serilog.pkgs + ..\..\..\..\..\Packages\Packages\SlnGen.pkgs = ..\..\..\..\..\Packages\Packages\SlnGen.pkgs + ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs = ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs + ..\..\..\..\..\Packages\Packages\System.pkgs = ..\..\..\..\..\Packages\Packages\System.pkgs + ..\..\..\..\..\Packages\Packages\Telegram.pkgs = ..\..\..\..\..\Packages\Packages\Telegram.pkgs + ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs = ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs + ..\..\..\..\..\Packages\Packages\Testing.pkgs = ..\..\..\..\..\Packages\Packages\Testing.pkgs + ..\..\..\..\..\Packages\Packages\Validation.pkgs = ..\..\..\..\..\Packages\Packages\Validation.pkgs + ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs = ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs + ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props = ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props + ..\..\..\..\..\Packages\Versions\AutoMapper.props = ..\..\..\..\..\Packages\Versions\AutoMapper.props + ..\..\..\..\..\Packages\Versions\EFCore.props = ..\..\..\..\..\Packages\Versions\EFCore.props + ..\..\..\..\..\Packages\Versions\JsonPatch.props = ..\..\..\..\..\Packages\Versions\JsonPatch.props + ..\..\..\..\..\Packages\Versions\MediatR.props = ..\..\..\..\..\Packages\Versions\MediatR.props + ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props = ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props + ..\..\..\..\..\Packages\Versions\MSBuild.props = ..\..\..\..\..\Packages\Versions\MSBuild.props + ..\..\..\..\..\Packages\Versions\PowerShell.props = ..\..\..\..\..\Packages\Versions\PowerShell.props + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {28E7587A-EA25-428B-8684-F5E47F07CC66} + EndGlobalSection +EndGlobal diff --git a/src/UserBot/UserBot.Api/UserBotWebBuilderExtensions.cs b/src/UserBot/UserBot.Api/UserBotWebBuilderExtensions.cs new file mode 100644 index 0000000..21ec846 --- /dev/null +++ b/src/UserBot/UserBot.Api/UserBotWebBuilderExtensions.cs @@ -0,0 +1,20 @@ +namespace Telegram.UserBot; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Telegram.UserBot.Config; + +public static class UserBotWebBuilderExtensions +{ + public static WebApplicationBuilder AddUserBot(this WebApplicationBuilder builder) + { + builder.Services.AddUserBot(builder.Configuration); + return builder; + } + + public static IServiceCollection AddUserBot(this IServiceCollection services, IConfiguration config) + { + services.Configure(config.GetSection("Telegram:UserBot")); + services.AddSingleton(); + return services; + } +} diff --git a/src/UserBot/UserBot.Api/WeatherForecast.cs b/src/UserBot/UserBot.Api/WeatherForecast.cs new file mode 100644 index 0000000..18e21ec --- /dev/null +++ b/src/UserBot/UserBot.Api/WeatherForecast.cs @@ -0,0 +1,12 @@ +namespace Telegram.UserBot.Api; + +public class WeatherForecast +{ + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } +} diff --git a/src/UserBot/UserBot.Api/appsettings.Development.json b/src/UserBot/UserBot.Api/appsettings.Development.json new file mode 100644 index 0000000..ff66ba6 --- /dev/null +++ b/src/UserBot/UserBot.Api/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/src/UserBot/UserBot.Api/appsettings.json b/src/UserBot/UserBot.Api/appsettings.json new file mode 100644 index 0000000..4d56694 --- /dev/null +++ b/src/UserBot/UserBot.Api/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/UserBot/UserBot/IUserBot.cs b/src/UserBot/UserBot/IUserBot.cs new file mode 100644 index 0000000..afdfb83 --- /dev/null +++ b/src/UserBot/UserBot/IUserBot.cs @@ -0,0 +1,19 @@ +/* + * IUserBot.cs + * + * Created: 2023-04-30-07:39:48 + * Modified: 2023-04-30-07:39:48 + * + * Author: David G. Moore, Jr. + * + * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved + * License: MIT (https://opensource.org/licenses/MIT) + */ + +namespace Telegram.UserBot; + +[GenerateInterface(typeof(UserBot))] +public partial interface IUserBot +{ + +} diff --git a/src/UserBot/UserBot/Telegram.UserBot.csproj b/src/UserBot/UserBot/Telegram.UserBot.csproj new file mode 100644 index 0000000..fb6628d --- /dev/null +++ b/src/UserBot/UserBot/Telegram.UserBot.csproj @@ -0,0 +1,29 @@ + + + + + net7.0 + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/UserBot/UserBot/Telegram.UserBot.sln b/src/UserBot/UserBot/Telegram.UserBot.sln new file mode 100644 index 0000000..6fd0fab --- /dev/null +++ b/src/UserBot/UserBot/Telegram.UserBot.sln @@ -0,0 +1,62 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B283EBC2-E01F-412D-9339-FD56EF114549}" + ProjectSection(SolutionItems) = preProject + ..\..\..\..\..\Packages\Versions.props = ..\..\..\..\..\Packages\Versions.props + ..\..\..\..\..\Packages\Versions.Local.json = ..\..\..\..\..\Packages\Versions.Local.json + ..\..\..\..\..\Packages\Versions.Local.props = ..\..\..\..\..\Packages\Versions.Local.props + ..\..\..\..\..\Packages\Packages.pkgs = ..\..\..\..\..\Packages\Packages.pkgs + ..\..\..\..\..\Packages\Packages\AnyOf.pkgs = ..\..\..\..\..\Packages\Packages\AnyOf.pkgs + ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs = ..\..\..\..\..\Packages\Packages\APIVersioning.pkgs + ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs = ..\..\..\..\..\Packages\Packages\AutoMapper.pkgs + ..\..\..\..\..\Packages\Packages\Azure.pkgs = ..\..\..\..\..\Packages\Packages\Azure.pkgs + ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs = ..\..\..\..\..\Packages\Packages\AzureFunctions.pkgs + ..\..\..\..\..\Packages\Packages\DDD.pkgs = ..\..\..\..\..\Packages\Packages\DDD.pkgs + ..\..\..\..\..\Packages\Packages\EFCore.pkgs = ..\..\..\..\..\Packages\Packages\EFCore.pkgs + ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs = ..\..\..\..\..\Packages\Packages\GlobalBuild.pkgs + ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs = ..\..\..\..\..\Packages\Packages\GlobalCodeGenerators.pkgs + ..\..\..\..\..\Packages\Packages\Images.pkgs = ..\..\..\..\..\Packages\Packages\Images.pkgs + ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs = ..\..\..\..\..\Packages\Packages\McMaster.CommandLineUtils.pkgs + ..\..\..\..\..\Packages\Packages\MediatR.pkgs = ..\..\..\..\..\Packages\Packages\MediatR.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.AspNetCore.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Extensions.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.Identity.pkgs + ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs = ..\..\..\..\..\Packages\Packages\Microsoft.VisualStudio.Shell.Interop.pkgs + ..\..\..\..\..\Packages\Packages\Miscellany.pkgs = ..\..\..\..\..\Packages\Packages\Miscellany.pkgs + ..\..\..\..\..\Packages\Packages\MSBuild.pkgs = ..\..\..\..\..\Packages\Packages\MSBuild.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildProjectCreator.pkgs + ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs = ..\..\..\..\..\Packages\Packages\MSBuildSdks.pkgs + ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs = ..\..\..\..\..\Packages\Packages\Newtonsoft.Json.pkgs + ..\..\..\..\..\Packages\Packages\NuGet.pkgs = ..\..\..\..\..\Packages\Packages\NuGet.pkgs + ..\..\..\..\..\Packages\Packages\Powershell.pkgs = ..\..\..\..\..\Packages\Packages\Powershell.pkgs + ..\..\..\..\..\Packages\Packages\Roslyn.pkgs = ..\..\..\..\..\Packages\Packages\Roslyn.pkgs + ..\..\..\..\..\Packages\Packages\Serilog.pkgs = ..\..\..\..\..\Packages\Packages\Serilog.pkgs + ..\..\..\..\..\Packages\Packages\SlnGen.pkgs = ..\..\..\..\..\Packages\Packages\SlnGen.pkgs + ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs = ..\..\..\..\..\Packages\Packages\Swashbuckle.pkgs + ..\..\..\..\..\Packages\Packages\System.pkgs = ..\..\..\..\..\Packages\Packages\System.pkgs + ..\..\..\..\..\Packages\Packages\Telegram.pkgs = ..\..\..\..\..\Packages\Packages\Telegram.pkgs + ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs = ..\..\..\..\..\Packages\Packages\Testing.EfCore.pkgs + ..\..\..\..\..\Packages\Packages\Testing.pkgs = ..\..\..\..\..\Packages\Packages\Testing.pkgs + ..\..\..\..\..\Packages\Packages\Validation.pkgs = ..\..\..\..\..\Packages\Packages\Validation.pkgs + ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs = ..\..\..\..\..\Packages\Packages\XmlDocMd.pkgs + ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props = ..\..\..\..\..\Packages\Versions\AspNetCoreIdentity.props + ..\..\..\..\..\Packages\Versions\AutoMapper.props = ..\..\..\..\..\Packages\Versions\AutoMapper.props + ..\..\..\..\..\Packages\Versions\EFCore.props = ..\..\..\..\..\Packages\Versions\EFCore.props + ..\..\..\..\..\Packages\Versions\JsonPatch.props = ..\..\..\..\..\Packages\Versions\JsonPatch.props + ..\..\..\..\..\Packages\Versions\MediatR.props = ..\..\..\..\..\Packages\Versions\MediatR.props + ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props = ..\..\..\..\..\Packages\Versions\Microsoft.Extensions.Logging.props + ..\..\..\..\..\Packages\Versions\MSBuild.props = ..\..\..\..\..\Packages\Versions\MSBuild.props + ..\..\..\..\..\Packages\Versions\PowerShell.props = ..\..\..\..\..\Packages\Versions\PowerShell.props + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5F2486BA-F461-4743-B512-4B1AA3183CE9} + EndGlobalSection +EndGlobal diff --git a/src/UserBot/UserBot/Telegram.UserBot.targets b/src/UserBot/UserBot/Telegram.UserBot.targets new file mode 100644 index 0000000..8bb15d9 --- /dev/null +++ b/src/UserBot/UserBot/Telegram.UserBot.targets @@ -0,0 +1,17 @@ + + + + + + + \ No newline at end of file diff --git a/src/UserBot/UserBot/UserBot.cs b/src/UserBot/UserBot/UserBot.cs new file mode 100644 index 0000000..1199e24 --- /dev/null +++ b/src/UserBot/UserBot/UserBot.cs @@ -0,0 +1,61 @@ +/* + * UserBot.cs + * + * Created: 2023-04-25-06:59:03 + * Modified: 2023-04-25-06:59:03 + * + * Author: David G. Moore, Jr. + * + * Copyright © 2022 - 2023 David G. Moore, Jr., All Rights Reserved + * License: MIT (https://opensource.org/licenses/MIT) + */ + +namespace Telegram.UserBot; + +using Dgmjr.Abstractions; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Telegram.UserBot.Config; +using Telegram.UserBot.Store.Abstractions; +using TL; + +public class UserBot : WT.Client, ILog, IUserBot +{ + public virtual ILogger Logger { get; protected set; } + public virtual User Me { get; protected set; } + public IDictionary Users { get; } = new Dictionary(); + static IDictionary Chats { get; } = new Dictionary(); + + public UserBot(IOptions cfg, ILogger logger) : this(cfg.Value, logger) + { + + } + public UserBot(IUserBotConfig cfg, ILogger logger) : this(cfg.GetConfigVariable, cfg.GetSessionStore().GetStream(), logger) + { + + } + + public UserBot(Func config, Stream store, ILogger logger) : base(config, store) + { + Logger = logger; + OnUpdate += Client_OnUpdate; + } + + protected virtual async Task Client_OnUpdate(IObject arg) + { + if (arg is not UpdatesBase updates) return; + updates.CollectUsersChats(Users, Chats); + foreach (var update in updates.UpdateList) + { + WriteLine(update.GetType().Name); + if (update is UpdateNewMessage { message: Message { peer_id: PeerUser { user_id: var user_id } } msg }) // private message + if (!msg.flags.HasFlag(Message.Flags.out_)) // ignore our own outgoing messages + if (Users.TryGetValue(user_id, out var user)) + { + WriteLine($"New message from {user}: {msg.message}"); + if (msg.message.Equals("Ping", OrdinalIgnoreCase)) + await SendMessageAsync(user, "Pong"); + } + } + } +} diff --git a/src/UserBot/UserBot/UserBotLogger.cs b/src/UserBot/UserBot/UserBotLogger.cs new file mode 100644 index 0000000..ced5d69 --- /dev/null +++ b/src/UserBot/UserBot/UserBotLogger.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.Logging; +using TL; + +namespace Telegram.UserBot; + +public static partial class UserBotLoggerExtensions +{ + [LoggerMessage(EventId = 0, Level = LogLevel.Information, Message = "New message from {user}: {message}")] + public static partial void LogNewMessageFromUser(this ILogger logger, User user, string message); + + [LoggerMessage(EventId = 1, Level = LogLevel.Information, Message = "{me} logged in with phone number {phoneNumber}")] + public static partial void LogLoggedIn(this ILogger logger, string phoneNumber, User me); +}