mirror of
https://github.com/Bubuni-Team/telegram-bot.git
synced 2026-07-31 00:29:24 +03:00
Merge branch 'feature/storage' into dev
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="AleXr64.BotFramework" Version="0.0.17" />
|
<PackageReference Include="AleXr64.BotFramework" Version="0.0.17" />
|
||||||
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.2" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.2" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.2" />
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="3.1.2" />
|
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="3.1.2" />
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Data
|
||||||
|
{
|
||||||
|
public class BotUser
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The unique bot user identifier.
|
||||||
|
/// </summary>
|
||||||
|
[Key]
|
||||||
|
public Guid BotUserId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The chat identifier where this user is related.
|
||||||
|
/// </summary>
|
||||||
|
public long ChatId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The Telegram User identifier.
|
||||||
|
/// </summary>
|
||||||
|
public int UserId { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.Serialization.Formatters.Binary;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Data
|
||||||
|
{
|
||||||
|
public class BotUserValue
|
||||||
|
{
|
||||||
|
[Key]
|
||||||
|
public Guid BotUserValueId { get; set; }
|
||||||
|
|
||||||
|
public BotUser BotUser { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public byte[] Value
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var fmt = new BinaryFormatter();
|
||||||
|
using var memStream = new MemoryStream();
|
||||||
|
fmt.Serialize(memStream, data);
|
||||||
|
|
||||||
|
return memStream.ToArray();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
var fmt = new BinaryFormatter();
|
||||||
|
using var memStream = new MemoryStream();
|
||||||
|
memStream.Write(value);
|
||||||
|
memStream.Position = 0;
|
||||||
|
|
||||||
|
data = fmt.Deserialize(memStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[NonSerialized] public object data;
|
||||||
|
|
||||||
|
public T GetValue<T>() => (T) data;
|
||||||
|
public void SetValue<T>(T value) => data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Data
|
||||||
|
{
|
||||||
|
public class CoreContext : DbContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The all known users.
|
||||||
|
/// </summary>
|
||||||
|
public DbSet<BotUser> Users { get; set; }
|
||||||
|
|
||||||
|
public DbSet<BotUserValue> UserValues { get; set; }
|
||||||
|
|
||||||
|
public override void Dispose()
|
||||||
|
{
|
||||||
|
SaveChanges();
|
||||||
|
base.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
SaveChanges();
|
||||||
|
return base.DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CoreContext(DbContextOptions<CoreContext> ctx) : base(ctx)
|
||||||
|
{
|
||||||
|
Database.Migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using System.Threading.Tasks;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
|
||||||
namespace Kruzya.TelegramBot.Core.Extensions
|
namespace Kruzya.TelegramBot.Core.Extensions
|
||||||
{
|
{
|
||||||
@@ -43,5 +46,85 @@ namespace Kruzya.TelegramBot.Core.Extensions
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Core-context repository extensions
|
||||||
|
|
||||||
|
#region BotUser
|
||||||
|
|
||||||
|
public static async Task<BotUser> FindOrCreate(this DbSet<BotUser> repository, long chatId, int userId)
|
||||||
|
{
|
||||||
|
var user = await repository.SingleOrDefaultAsync(e => e.ChatId == chatId && e.UserId == userId);
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
user = repository.Create();
|
||||||
|
user.ChatId = chatId;
|
||||||
|
user.UserId = userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region BotUserValue
|
||||||
|
|
||||||
|
#region FindOption
|
||||||
|
|
||||||
|
public static async Task<BotUserValue> FindOption(this DbSet<BotUserValue> repository, long chatId,
|
||||||
|
string option) => await repository.FindOption(chatId, 0, option);
|
||||||
|
|
||||||
|
public static async Task<BotUserValue> FindOption(this DbSet<BotUserValue> repository, BotUser user,
|
||||||
|
string option) => await repository.FindOption(user.ChatId, user.UserId, option);
|
||||||
|
|
||||||
|
public static async Task<BotUserValue> FindOption(this DbSet<BotUserValue> repository, long chatId, int userId,
|
||||||
|
string option) => await repository.SingleOrDefaultAsync(e =>
|
||||||
|
e.BotUser.ChatId == chatId && e.BotUser.UserId == userId && e.Name == option);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region FindOrCreateOption
|
||||||
|
|
||||||
|
public static async Task<BotUserValue> FindOrCreateOption(this DbSet<BotUserValue> repository, long chatId,
|
||||||
|
string option) => await repository.FindOrCreateOption(chatId, 0, option);
|
||||||
|
|
||||||
|
public static async Task<BotUserValue> FindOrCreateOption(this DbSet<BotUserValue> repository, BotUser user,
|
||||||
|
string option) => await repository.FindOrCreateOption(user.ChatId, user.UserId, option);
|
||||||
|
|
||||||
|
public static async Task<BotUserValue> FindOrCreateOption(this DbSet<BotUserValue> repository, long chatId,
|
||||||
|
int userId, string option)
|
||||||
|
{
|
||||||
|
var opt = await repository.FindOption(chatId, userId, option);
|
||||||
|
if (opt == null)
|
||||||
|
{
|
||||||
|
opt = repository.Create();
|
||||||
|
opt.BotUser = await repository.GetService<CoreContext>().Users.FindOrCreate(chatId, userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region SetOptionValue
|
||||||
|
|
||||||
|
public static async Task SetOptionValue<T>(this DbSet<BotUserValue> repository, long chatId, string option,
|
||||||
|
T val) => await repository.SetOptionValue(chatId, 0, option, val);
|
||||||
|
|
||||||
|
public static async Task SetOptionValue<T>(this DbSet<BotUserValue> repository, BotUser user, string option,
|
||||||
|
T val) => await repository.SetOptionValue(user.ChatId, user.UserId, option, val);
|
||||||
|
|
||||||
|
public static async Task SetOptionValue<T>(this DbSet<BotUserValue> repository, long chatId, int userId,
|
||||||
|
string option, T val)
|
||||||
|
{
|
||||||
|
var opt = await repository.FindOrCreateOption(chatId, userId, option);
|
||||||
|
opt.SetValue(val);
|
||||||
|
repository.Update(opt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BotFramework;
|
||||||
|
using BotFramework.Attributes;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core
|
||||||
|
{
|
||||||
|
public class GeneralHandler : BotEventHandler
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Method)]
|
||||||
|
public sealed class HandleEverythingAttribute : HandlerAttribute
|
||||||
|
{
|
||||||
|
protected override bool CanHandle(HandlerParams param)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected readonly CoreContext databaseContext;
|
||||||
|
|
||||||
|
public GeneralHandler(CoreContext dbCtx)
|
||||||
|
{
|
||||||
|
databaseContext = dbCtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HandleEverything]
|
||||||
|
public async Task Listener()
|
||||||
|
{
|
||||||
|
foreach (var message in new Message[] {RawUpdate.Message, RawUpdate.EditedMessage, RawUpdate.ChannelPost, RawUpdate.EditedChannelPost})
|
||||||
|
{
|
||||||
|
if (message == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
await VerifyChatPair(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task VerifyChatPair(Message message)
|
||||||
|
{
|
||||||
|
await VerifyChatPair(message.Chat, message.From);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task VerifyChatPair(Chat chat, User user)
|
||||||
|
{
|
||||||
|
await VerifyChatPair(chat.Id, user.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task VerifyChatPair(long chat, int user)
|
||||||
|
{
|
||||||
|
var hasEntry = await databaseContext.Users.AnyAsync(e => e.ChatId == chat && e.UserId == user);
|
||||||
|
if (hasEntry)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await MakeChatPair(chat, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task MakeChatPair(long chat, int user)
|
||||||
|
{
|
||||||
|
await databaseContext.Users.AddAsync(new BotUser()
|
||||||
|
{
|
||||||
|
ChatId = chat,
|
||||||
|
UserId = user,
|
||||||
|
BotUserId = new Guid()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+70
@@ -0,0 +1,70 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(CoreContext))]
|
||||||
|
[Migration("20200307215450_Initial")]
|
||||||
|
partial class Initial
|
||||||
|
{
|
||||||
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.2")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("BotUserId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<long>("ChatId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("BotUserId");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("BotUserValueId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<Guid?>("BotUserId")
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("longtext CHARACTER SET utf8mb4");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Value")
|
||||||
|
.HasColumnType("longblob");
|
||||||
|
|
||||||
|
b.HasKey("BotUserValueId");
|
||||||
|
|
||||||
|
b.HasIndex("BotUserId");
|
||||||
|
|
||||||
|
b.ToTable("UserValues");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Kruzya.TelegramBot.Core.Data.BotUser", "BotUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BotUserId");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Migrations
|
||||||
|
{
|
||||||
|
public partial class Initial : Migration
|
||||||
|
{
|
||||||
|
protected override void Up(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "Users",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
BotUserId = table.Column<Guid>(nullable: false),
|
||||||
|
ChatId = table.Column<long>(nullable: false),
|
||||||
|
UserId = table.Column<int>(nullable: false)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_Users", x => x.BotUserId);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateTable(
|
||||||
|
name: "UserValues",
|
||||||
|
columns: table => new
|
||||||
|
{
|
||||||
|
BotUserValueId = table.Column<Guid>(nullable: false),
|
||||||
|
BotUserId = table.Column<Guid>(nullable: true),
|
||||||
|
Name = table.Column<string>(nullable: true),
|
||||||
|
Value = table.Column<byte[]>(nullable: true)
|
||||||
|
},
|
||||||
|
constraints: table =>
|
||||||
|
{
|
||||||
|
table.PrimaryKey("PK_UserValues", x => x.BotUserValueId);
|
||||||
|
table.ForeignKey(
|
||||||
|
name: "FK_UserValues_Users_BotUserId",
|
||||||
|
column: x => x.BotUserId,
|
||||||
|
principalTable: "Users",
|
||||||
|
principalColumn: "BotUserId",
|
||||||
|
onDelete: ReferentialAction.Restrict);
|
||||||
|
});
|
||||||
|
|
||||||
|
migrationBuilder.CreateIndex(
|
||||||
|
name: "IX_UserValues_BotUserId",
|
||||||
|
table: "UserValues",
|
||||||
|
column: "BotUserId");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Down(MigrationBuilder migrationBuilder)
|
||||||
|
{
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "UserValues");
|
||||||
|
|
||||||
|
migrationBuilder.DropTable(
|
||||||
|
name: "Users");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
// <auto-generated />
|
||||||
|
using System;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.Core.Migrations
|
||||||
|
{
|
||||||
|
[DbContext(typeof(CoreContext))]
|
||||||
|
partial class CoreContextModelSnapshot : ModelSnapshot
|
||||||
|
{
|
||||||
|
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||||
|
{
|
||||||
|
#pragma warning disable 612, 618
|
||||||
|
modelBuilder
|
||||||
|
.HasAnnotation("ProductVersion", "3.1.2")
|
||||||
|
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||||
|
|
||||||
|
modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUser", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("BotUserId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<long>("ChatId")
|
||||||
|
.HasColumnType("bigint");
|
||||||
|
|
||||||
|
b.Property<int>("UserId")
|
||||||
|
.HasColumnType("int");
|
||||||
|
|
||||||
|
b.HasKey("BotUserId");
|
||||||
|
|
||||||
|
b.ToTable("Users");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b =>
|
||||||
|
{
|
||||||
|
b.Property<Guid>("BotUserValueId")
|
||||||
|
.ValueGeneratedOnAdd()
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<Guid?>("BotUserId")
|
||||||
|
.HasColumnType("char(36)");
|
||||||
|
|
||||||
|
b.Property<string>("Name")
|
||||||
|
.HasColumnType("longtext CHARACTER SET utf8mb4");
|
||||||
|
|
||||||
|
b.Property<byte[]>("Value")
|
||||||
|
.HasColumnType("longblob");
|
||||||
|
|
||||||
|
b.HasKey("BotUserValueId");
|
||||||
|
|
||||||
|
b.HasIndex("BotUserId");
|
||||||
|
|
||||||
|
b.ToTable("UserValues");
|
||||||
|
});
|
||||||
|
|
||||||
|
modelBuilder.Entity("Kruzya.TelegramBot.Core.Data.BotUserValue", b =>
|
||||||
|
{
|
||||||
|
b.HasOne("Kruzya.TelegramBot.Core.Data.BotUser", "BotUser")
|
||||||
|
.WithMany()
|
||||||
|
.HasForeignKey("BotUserId");
|
||||||
|
});
|
||||||
|
#pragma warning restore 612, 618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
using BotFramework;
|
using BotFramework;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
using Kruzya.TelegramBot.Core.Extensions;
|
using Kruzya.TelegramBot.Core.Extensions;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
@@ -29,6 +31,10 @@ namespace Kruzya.TelegramBot.Core
|
|||||||
services.AddSingleton<Core>(_core);
|
services.AddSingleton<Core>(_core);
|
||||||
foreach (var module in _core.Modules) services.AddSingleton(module.GetType(), module);
|
foreach (var module in _core.Modules) services.AddSingleton(module.GetType(), module);
|
||||||
|
|
||||||
|
// Add database context to DI.
|
||||||
|
services.AddDbContext<CoreContext>(ctx =>
|
||||||
|
ctx.UseMySql(_core.Configuration.GetConnectionString("DefaultConnection")));
|
||||||
|
|
||||||
// Trigger module handlers.
|
// Trigger module handlers.
|
||||||
_core.Modules.ConfigureServices(services);
|
_core.Modules.ConfigureServices(services);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,9 @@
|
|||||||
"Microsoft": "Warning",
|
"Microsoft": "Warning",
|
||||||
"Microsoft.Hosting.Lifetime": "Information"
|
"Microsoft.Hosting.Lifetime": "Information"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "server=127.0.0.1;UserId=rider;Password=rider;database=rider;port=8889"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
using Telegram.Bot.Types;
|
|
||||||
|
|
||||||
namespace Kruzya.TelegramBot.UrlLimitations
|
|
||||||
{
|
|
||||||
public struct ChatMember
|
|
||||||
{
|
|
||||||
public long Chat;
|
|
||||||
public long User;
|
|
||||||
|
|
||||||
public static ChatMember From(long chatId, long userId)
|
|
||||||
{
|
|
||||||
return new ChatMember()
|
|
||||||
{
|
|
||||||
Chat = chatId,
|
|
||||||
User = userId
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using BotFramework;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
|
||||||
|
namespace Kruzya.TelegramBot.UrlLimitations
|
||||||
|
{
|
||||||
|
public static class MessageExtension
|
||||||
|
{
|
||||||
|
public static async Task<bool> HasUnknownMention(this Message message, ITelegramBotClient bot)
|
||||||
|
{
|
||||||
|
foreach (var mention in message.Entities.Where(e =>
|
||||||
|
e.Type == MessageEntityType.Mention || e.Type == MessageEntityType.TextMention))
|
||||||
|
{
|
||||||
|
var userId = 0;
|
||||||
|
if (mention.Type == MessageEntityType.TextMention)
|
||||||
|
{
|
||||||
|
userId = mention.User.Id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var chat = await bot.GetChatAsync(
|
||||||
|
new ChatId(message.Text.Substring(mention.Offset, mention.Length)));
|
||||||
|
|
||||||
|
if (chat != null)
|
||||||
|
{
|
||||||
|
if (chat.Type != ChatType.Private)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
userId = Convert.ToInt32(chat.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var status = (await bot.GetChatMemberAsync(message.Chat, userId)).Status;
|
||||||
|
|
||||||
|
if ((new ChatMemberStatus[]
|
||||||
|
{
|
||||||
|
ChatMemberStatus.Administrator, ChatMemberStatus.Creator, ChatMemberStatus.Member,
|
||||||
|
ChatMemberStatus.Restricted
|
||||||
|
|
||||||
|
// i'm not sure about "Restricted"
|
||||||
|
// maybe leaved members with some restrictions also can be "Restricted".
|
||||||
|
}).Any(e => e == status) == false)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ using BotFramework;
|
|||||||
using BotFramework.Attributes;
|
using BotFramework.Attributes;
|
||||||
using BotFramework.Setup;
|
using BotFramework.Setup;
|
||||||
using Kruzya.TelegramBot.Core.Cache;
|
using Kruzya.TelegramBot.Core.Cache;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
using Kruzya.TelegramBot.Core.Extensions;
|
using Kruzya.TelegramBot.Core.Extensions;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
@@ -15,35 +16,34 @@ namespace Kruzya.TelegramBot.UrlLimitations
|
|||||||
public class MessageHandler : BotEventHandler
|
public class MessageHandler : BotEventHandler
|
||||||
{
|
{
|
||||||
protected ILogger Logger;
|
protected ILogger Logger;
|
||||||
protected MemoryCache<ChatMember, UInt16> ChatMembersCache;
|
protected readonly CoreContext dbCtx;
|
||||||
|
|
||||||
public MessageHandler(ILogger<MessageHandler> logger, MemoryCache<ChatMember, UInt16> chatMembersCache)
|
public MessageHandler(ILogger<MessageHandler> logger, CoreContext coreContext)
|
||||||
{
|
{
|
||||||
Logger = logger;
|
Logger = logger;
|
||||||
ChatMembersCache = chatMembersCache;
|
dbCtx = coreContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
[TextMessage(InChat.Public)]
|
[TextMessage(InChat.Public)]
|
||||||
public void OnMessageReceived()
|
public async Task OnMessageReceived()
|
||||||
{
|
{
|
||||||
UInt16 messageCount;
|
var option = await dbCtx.UserValues.FindOption(Chat.Id, From.Id, "urlLimitations.messagesAfterJoin");
|
||||||
var chatMember = ChatMember.From(Chat.Id, From.Id);
|
if (option == null)
|
||||||
if (!ChatMembersCache.TryGetValue(chatMember, out messageCount))
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var messageCount = option.GetValue<UInt16>();
|
||||||
if (messageCount > 10)
|
if (messageCount > 10)
|
||||||
{
|
{
|
||||||
ChatMembersCache.SetValue(chatMember, 0, 0);
|
dbCtx.UserValues.Remove(option);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
messageCount++;
|
option.SetValue(messageCount + 1);
|
||||||
ChatMembersCache.SetValue(chatMember, messageCount);
|
|
||||||
var message = RawUpdate.Message;
|
var message = RawUpdate.Message;
|
||||||
if (message.Entities.Count(e => e.Type == MessageEntityType.Url || e.Type == MessageEntityType.TextLink) >
|
if (message.Entities.Count(e => e.Type == MessageEntityType.Url || e.Type == MessageEntityType.TextLink) >
|
||||||
0)
|
0 || await message.HasUnknownMention(Bot))
|
||||||
{
|
{
|
||||||
var targetChat = new ChatId(Chat.Id);
|
var targetChat = new ChatId(Chat.Id);
|
||||||
Task.WaitAll(new Task[] {
|
Task.WaitAll(new Task[] {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Kruzya.TelegramBot.Core;
|
using Kruzya.TelegramBot.Core;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
using Kruzya.TelegramBot.Core.Extensions;
|
using Kruzya.TelegramBot.Core.Extensions;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@@ -10,10 +11,5 @@ namespace Kruzya.TelegramBot.UrlLimitations
|
|||||||
public UrlLimitations(Core.Core core) : base(core)
|
public UrlLimitations(Core.Core core) : base(core)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ConfigureServices(IServiceCollection services)
|
|
||||||
{
|
|
||||||
services.AddMemoryCache<ChatMember, UInt16>();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,25 +1,30 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using BotFramework;
|
using BotFramework;
|
||||||
using BotFramework.Attributes;
|
using BotFramework.Attributes;
|
||||||
using BotFramework.Setup;
|
using BotFramework.Setup;
|
||||||
using Kruzya.TelegramBot.Core.Cache;
|
using Kruzya.TelegramBot.Core.Cache;
|
||||||
|
using Kruzya.TelegramBot.Core.Data;
|
||||||
|
using Kruzya.TelegramBot.Core.Extensions;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
|
|
||||||
namespace Kruzya.TelegramBot.UrlLimitations
|
namespace Kruzya.TelegramBot.UrlLimitations
|
||||||
{
|
{
|
||||||
public class UserJoinHandler : BotEventHandler
|
public class UserJoinHandler : BotEventHandler
|
||||||
{
|
{
|
||||||
protected MemoryCache<ChatMember, UInt16> ChatMembersCache;
|
protected readonly CoreContext dbCtx;
|
||||||
|
|
||||||
public UserJoinHandler(MemoryCache<ChatMember, UInt16> chatMembersCache)
|
public UserJoinHandler(CoreContext coreContext)
|
||||||
{
|
{
|
||||||
ChatMembersCache = chatMembersCache;
|
dbCtx = coreContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Message(MessageType.ChatMembersAdded, InChat.Public)]
|
[Message(MessageType.ChatMembersAdded, InChat.Public)]
|
||||||
public void OnChatMembersAdded()
|
public async Task OnChatMembersAdded()
|
||||||
{
|
{
|
||||||
ChatMembersCache.SetValue(ChatMember.From(Chat.Id, From.Id), 0);
|
foreach (var member in RawUpdate.Message.NewChatMembers)
|
||||||
|
await dbCtx.UserValues.SetOptionValue<UInt16>(Chat.Id, member.Id, "urlLimitations.messagesAfterJoin",
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user