Skip to content

SKitLs AdvancedMessages

SKitLs-dev edited this page Mar 31, 2024 · 11 revisions

Provides methods for organization more complicated messages sending, inc. Messages Editing, Dynamic Messages (depending on update's content), enabling menus and other.

Contents

Setup

Download Package

dotnet add package SKitLs.Bots.Telegram.AdvancedMessages

Download Locals

Get the required localization files from the repository (*.am.json) and install them in the folder /resources/locals.

Integration

See Snippets to get information about integration.

General Model

Back to contents

AdvancedDeliveryService

AdvancedDeliveryService is inherited from Core DeliveryService and overrides some SendMessageToChatAsync() to make delivery more flexible.

At the moment it only extends basics with Edit Extension support. Further versions would support Photos, Videos, Documents and other object.

public override async Task<DeliveryResponse> SendMessageToChatAsync(long chatId, ITelegramMessage message, CancellationTokenSource? cts = null)
{
    cts ??= new();
    if (message is IEditWrapper edit)
        return await HandleEditAsync(chatId, edit, cts);
    else
        return await base.SendMessageToChatAsync(chatId, message, cts);
}

Back to contents

Messages

General message elements are IOutputMessage interface and OutputMessage<TMessage> abstract class. They implements Core IBuildableMessage interface and can be handled properly by IDeliveryService interface.

OutputMessage series extends basic message class with dynamic menu (presented with IBuildableContent<IMessageMenu>) and dynamic content generator (presented with ContentBuilder<TMessage>? ContentBuilder).

public delegate Task<TSender> ContentBuilder<TSender>(TSender sender, ICastedUpdate? update) where TSender : class;

Serves as an abstract base for specific messages, listed below.

Text Messages

OutputMessageText presents an OutputMessage with preset text base, which could be manipulated by ContentBuilder.

MultiblockMessage (kinda Obsolete) presents a specific message with paragraphs. Paragraphs are built automatically.

var multiblock = new MultiblockMessage();
multiblock.Header = "Header";
multiblock.AddBlock("Block 1.");
multiblock.AddBlock("Block 2.");
multiblock.Footer = "Footer";

Results in:

MultiblockMessage Example

Localized Messages

Localized Messages extends Core Localization facilities, providing automatic localization. Implements Localized class and IBuildableMessage interface.

You can pass localization key and formatting parameters to the class and it will be translated to required language before sending. Usage example.

public class LocalizedTextMessage : Localized<OutputMessageText, TelegramTextMessage, ITelegramMessage>, IBuildableMessage

Back to contents

IBuildableContent

IBuildableContent<T> interface provides additional functionality for handling dynamic content.

Declares Task<T> BuildContentAsync(ICastedUpdate? update) method.

Back to contents

Menus

Module's menus are presented with IMessageMenu interface that serves as a wrapper for telegram keyboards (IReplyMarkup raw interface). Implemented in 3 classes.

MenuWrapper

Simple wrapper that should be used if you wanna pass raw IReplyMarkup to any of supported messages.

ReplyBase

Base abstract class for Reply Keyboard Markup. Can be customized according to API requirements. Holds a set of Reply Buttons.

Implemented in 2 classes: ReplyMenu (just a reply menu) and ReplyCleaner (deletes current menu).

InlineBase

Base abstract class for Inline Keyboard Markup. Can be customized according to API requirements. Holds a set of Inline Buttons.

Implemented in 1 class: InlineMenu.

Inline Menu class supports several shortcuts for Callbacks integration (inc. ArgedCallbacks). Add(...) method overloads.

// Basic one
public void Add(IBuildableContent<IInlineButton> button) { }

// Overloads
public void Add(IInlineButton button) => Add(new SelfBuild<IInlineButton>(button));

public void Add(DefaultCallback callback...) { }

public void Add<T>(BotArgedCallback<T> callback, T data...) { }

public void Add(string actionLabel, IBotAction<SignedCallbackUpdate> callback...) { }

public void Add<T>(string customLabel, IArgedAction<T, SignedCallbackUpdate> callback, T data...) { }

public void Add(LabeledData data...) { }

public void Add(string label, string data...) { }

Back to contents

Buttons

Reply Buttons

Based on IReplyButton interface. Implemented in ReplyButton class. Extensions could be found here.

Supports localization via Localize static class.

Inline Buttons

Based on IInlineButton interface. Implemented in InlineButton class. Extended by UrlButton.

Supports localization via Localize static class.

Back to contents

Features

Back to contents

Localized Content

Generic Localized<TContent, TBuildTemp, TBuildResult> class is defined to dynamically localize message's content.

Type Member Description
TContent Value Represents the value of the buildable content object.
string LocalizePropertyName Represents the name of the property that should be localized.
string?[] FormatArgsList Represents the list of format arguments used for formatting the localized text.

Localized is a wrapper for an IBuildableContent object. During building this class would raise its content's Task<TBuildTemp> BuildContentAsync() method and override LocalizePropertyName property.

        public async Task<TBuildResult> BuildContentAsync(ICastedUpdate? update)
        {
            var result = await Value.BuildContentAsync(update);
            var localizedProperty = typeof(TBuildTemp).GetProperty(LocalizePropertyName);
            var propValue = localizedProperty?.GetValue(result)?.ToString();
            if (update is not null && localizedProperty is not null && propValue is not null)
            {
                var localized = update.Owner.ResolveBotString(propValue, FormatArgsList) ?? propValue;
                localizedProperty.SetValue(result, localized);
            }
            return result;
        }

Localize Shortcuts

Localize static class provides some shortcuts for Localized<TContent, TBuildTemp, TBuildResult> content. At the moment used for buttons localization.

        public static Localized<InlineButton, TButton, IInlineButton> Inline<TButton>(TButton button, params string?[] format) where TButton : InlineButton
        {
            return new Localized<InlineButton, TButton, IInlineButton>(button, nameof(InlineButton.Label), format);
        }


        public static Localized<ReplyButton, TButton, IReplyButton> Reply<TButton>(TButton button, params string?[] format) where TButton : ReplyButton
        {
            return new Localized<ReplyButton, TButton, IReplyButton>(button, nameof(InlineButton.Label), format);
        }

Back to Features

Delivery Extensions

Back to Features

Editing Messages

Back to Features