This commit is contained in:
@@ -1,46 +1,157 @@
|
||||
using BotPages.Core;
|
||||
using BotPages.Core.Abstractions;
|
||||
using BotPages.Core.Context;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Types;
|
||||
|
||||
namespace BotPages.Telegram
|
||||
namespace BotPages.Telegram;
|
||||
|
||||
/// <summary>
|
||||
/// Утилита для маппинга Telegram Update → UpdateContext.
|
||||
/// </summary>
|
||||
public static class TelegramUpdateMapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Утилиты для извлечения контекста из Telegram Update.
|
||||
/// Маппинг Telegram Update в UpdateContext BotPages.
|
||||
/// </summary>
|
||||
public static class TelegramUpdateMapper
|
||||
public static UpdateContext Map(Update update, TelegramBotClient client)
|
||||
{
|
||||
/// <summary>
|
||||
/// Преобразует Telegram Update в универсальный UpdateContext.
|
||||
/// </summary>
|
||||
public static UpdateContext Map(ITelegramBotClient bot, INavigationService nav, IStateStore store, Update update)
|
||||
var chat = update.Message?.Chat ?? update.CallbackQuery?.Message?.Chat;
|
||||
var user = update.Message?.From ?? update.CallbackQuery?.From;
|
||||
|
||||
var userContext = new UserContext
|
||||
{
|
||||
var chat = update.Message?.Chat ?? update.CallbackQuery?.Message?.Chat;
|
||||
var user = update.Message?.From ?? update.CallbackQuery?.From;
|
||||
Id = user?.Id.ToString() ?? "unknown",
|
||||
DisplayName = user?.Username,
|
||||
};
|
||||
|
||||
var text = update.Message?.Text ?? update.CallbackQuery?.Data;
|
||||
|
||||
var files = new List<FileDescriptor>();
|
||||
if (update.Message?.Document is { } doc)
|
||||
var chatContext = new ChatContext
|
||||
{
|
||||
Id = chat?.Id.ToString() ?? "unknown",
|
||||
Title = chat?.Title,
|
||||
Capabilities = new Capabilities
|
||||
{
|
||||
files.Add(new FileDescriptor(doc.FileId, doc.FileName ?? "file", doc.MimeType ?? "application/octet-stream"));
|
||||
SupportsInlineButtons = true,
|
||||
SupportsReplyButtons = true,
|
||||
SupportsAlbums = true,
|
||||
SupportsFormattingMarkdown = true,
|
||||
SupportsFormattingHtml = true,
|
||||
MaxMessageLength = 4096,
|
||||
}
|
||||
if (update.Message?.Photo is { } photos && photos.Count() > 0)
|
||||
};
|
||||
|
||||
string? text = null;
|
||||
UpdateKind kind = UpdateKind.None;
|
||||
var files = new List<FileDescriptor>();
|
||||
|
||||
if (update.Message is { } msg)
|
||||
{
|
||||
|
||||
if (msg.Text is not null)
|
||||
{
|
||||
var largest = photos.OrderBy(p => p.FileSize).Last();
|
||||
files.Add(new FileDescriptor(largest.FileId, "photo.jpg", "image/jpeg"));
|
||||
text = msg.Text;
|
||||
kind |= UpdateKind.Text;
|
||||
}
|
||||
|
||||
return new UpdateContext
|
||||
if (msg.Photo is { Length: > 0 })
|
||||
{
|
||||
Client = new TelegramClientAdapter(bot),
|
||||
Chat = new ChatContext { Id = chat!.Id, Title = chat.Title },
|
||||
User = new UserContext { Id = user!.Id, DisplayName = $"{user.FirstName} {user.LastName}" },
|
||||
Text = text,
|
||||
IncomingFiles = files,
|
||||
RawUpdate = update,
|
||||
Nav = nav,
|
||||
State = store
|
||||
};
|
||||
foreach (var p in msg.Photo)
|
||||
{
|
||||
files.Add(new FileDescriptor
|
||||
{
|
||||
Id = p.FileId,
|
||||
Name = "photo",
|
||||
Extension = "jpg",
|
||||
Size = p.FileSize ?? 0,
|
||||
Kind = FileKind.Photo,
|
||||
GetStreamAsync = GetStreamAsync(client, p.FileId),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (msg.Document is not null)
|
||||
{
|
||||
files.Add(new FileDescriptor
|
||||
{
|
||||
Id = msg.Document.FileId,
|
||||
Name = msg.Document.FileName ?? "document",
|
||||
Extension = System.IO.Path.GetExtension(msg.Document.FileName) ?? "bin",
|
||||
Size = msg.Document.FileSize ?? 0,
|
||||
Kind = FileKind.Document,
|
||||
Mime = msg.Document.MimeType,
|
||||
GetStreamAsync = GetStreamAsync(client, msg.Document.FileId),
|
||||
});
|
||||
}
|
||||
|
||||
if (msg.Audio is not null)
|
||||
{
|
||||
files.Add(new FileDescriptor
|
||||
{
|
||||
Id = msg.Audio.FileId,
|
||||
Name = msg.Audio.FileName ?? "audio",
|
||||
Extension = System.IO.Path.GetExtension(msg.Audio.FileName) ?? "mp3",
|
||||
Size = msg.Audio.FileSize ?? 0,
|
||||
Kind = FileKind.Audio,
|
||||
Mime = msg.Audio.MimeType,
|
||||
GetStreamAsync = GetStreamAsync(client, msg.Audio.FileId),
|
||||
});
|
||||
}
|
||||
|
||||
if (msg.Video is not null)
|
||||
{
|
||||
files.Add(new FileDescriptor
|
||||
{
|
||||
Id = msg.Video.FileId,
|
||||
Name = "video",
|
||||
Extension = "mp4",
|
||||
Size = msg.Video.FileSize ?? 0,
|
||||
Kind = FileKind.Video,
|
||||
Mime = msg.Video.MimeType,
|
||||
GetStreamAsync = GetStreamAsync(client, msg.Video.FileId),
|
||||
});
|
||||
}
|
||||
|
||||
if (files.Count > 0)
|
||||
{
|
||||
kind |= UpdateKind.File;
|
||||
}
|
||||
}
|
||||
|
||||
if (update.CallbackQuery is { } cb)
|
||||
{
|
||||
kind |= UpdateKind.Button;
|
||||
text = cb.Data;
|
||||
}
|
||||
|
||||
|
||||
return new UpdateContext
|
||||
{
|
||||
MessengerType = "Telegram",
|
||||
User = userContext,
|
||||
Chat = chatContext,
|
||||
Text = text,
|
||||
Kind = kind,
|
||||
Files = files
|
||||
};
|
||||
}
|
||||
|
||||
private static Func<CancellationToken, Task<Stream>> GetStreamAsync(TelegramBotClient client, string fileId)
|
||||
{
|
||||
|
||||
Func<CancellationToken, Task<Stream>> getStreamAsync = async _ =>
|
||||
{
|
||||
var file = await client.GetFile(fileId);
|
||||
var stream = new MemoryStream();
|
||||
await client.DownloadFile(file, stream);
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
};
|
||||
|
||||
return getStreamAsync;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user