Skip to content

Features ⭐️

immmdreza edited this page Jul 23, 2021 · 5 revisions

Let's See why you should use Flamingo

1- Setup rich update handlers in a minute

using Flamingo.Attributes.Filters.Messages;
using Flamingo.Fishes.Advanced.InComingHandlers;
using Flamingo.Helpers.Types.Enums;
using System.Threading.Tasks;
using Telegram.Bot.Types;

namespace FlamingoProduction.InComings.Messages
{
    [CommandFilter("form")]
    [ChatTypeFilter(FlamingoChatType.Private)]
    public class MyAdvMessageInComing: AdvInComingMessage
    {
        protected override async Task GetEatenWrapper(Message inComing)
        {
            await ReplyText("Hello there!");
        }
    }
}

Or create a quick incoming handler with a single static method

[InComingMessage]
[CommandFilter("start", ArgumentsMode.NoArgs)]
public static async Task<bool> NormalStart(ICondiment<Message> cdmt)
{
    await cdmt.ReplyText($"Just Started!");
    return false;
}

Related docs

Related examples

2- Super Customizable

You create your own handler, filters, filter attributes, combine filters, rate limiters even update receivers and so on.

using Flamingo.Condiments;
using Telegram.Bot.Types;

namespace Flamingo.Filters.MessageFilters
{
    public class RepliedFilter : FilterBase<ICondiment<Message>>
    {
        public RepliedFilter() 
            : base(x=> x.InComing.ReplyToMessage != null)
        { }
    }
}

3- Rich extension methods when handling updates

[InComingMessage]
[CommandFilter("start", ArgumentsMode.NoArgs)]
public static async Task<bool> NormalStart(ICondiment<Message> cdmt)
{
    var msg = await cdmt.ReplyText("Just Started!");

    await msg.EditText("Oh started again!");

    await msg.Pin();

    await msg.Delete();
    return false;
}
            // - Feel extensions ...
            // - Query data args has been made using "callbackDataSpliter" at "InitBot"
            if (cdmt.GetRequireArgs(
                out string mode, out int level, 1))
            /*  ^                ^              ^
                |                |              |
                |_ First arg of callback data as string
                                 |_ Second arg of callback data as int
                                                |_ Start index ( set 1 to skip "data" itself)
             */

Since ICondiment<T> carries a lot of useful data about updates, you can build a large set of custom extension methods

public static async Task<ICondiment<Message>> Forward(this ICondiment<Message> Cdmt,
    Chat toChat,
    bool disableNofication = true,
    CancellationToken cancellationToken = default)
{
    var message = await Cdmt.Flamingo.BotClient.ForwardMessageAsync(
        toChat, Cdmt.Chat.Id, Cdmt.InComing.MessageId,
        disableNofication, cancellationToken);

    return new MessageCondiment(message, Cdmt.Flamingo);
}

Related docs

4- Use any dependencies in handlers

Flamingo will create dependencies in the constructor that carriers [AdvancedHandlerConstructor]

[CommandFilter("mage")]
public class GetDataFromBaseHandler: AdvInComingMessage
{
    private readonly FlamingoContext _flamingoContext;

    [AdvancedHandlerConstructor]
    public GetDataFromBaseHandler(FlamingoContext flamingoContext)
    {
        _flamingoContext = flamingoContext;
    }

    protected override async Task GetEatenWrapper(Message inComing)
    {
        await ReplyText(_flamingoContext.MagicalItem.MagicalWords);
    }
}

See

5- Await-able incoming handlers

You can wait for an specified incoming update in an update handler

var dl = await Cdmt.WaitForCallbackQuery(new RegexFilter("^dl_"));

if(dl.Succeeded)
{
    ...
}

Examples about await ables

Rate limiters

// Limits message sender to 1 message per 3 seconds
// by passing true, the thread will be blocked till limit releases
// An the answer will be sent after ( Nothing ignored )
flamingo.AddAutoMessageSenderLimit(TimeSpan.FromSeconds(3), true);

Or create your own limit and add it!

Useful helpers

Create inline buttons and reply buttons easily

var btns = new InlineBuilder(1,
    ("Happy 10", "data_happy_10"), ("Sad 10", "data_sad_10") );

await cdmt.ReplyText(..., replyMarkup: btns.Markup());

Fill forms easily with FormFiller

// Creates a form filler instance for `UserDataForm` class
var filler = Flamingo.CreateFormFiller<UserDataForm>();

// Asks user for marked properties of `UserDataForm`
// And allows user to fail for 1 time ( Type check failure or value checks )
await filler.Ask(
    Sender.Id,
    triesOnFailure: 1,
    cancellInputPattern: new Regex("^/cancel"));

Customize you form

public class UserDataForm
{
    [FlamingoFormProperty]
    [StringLength(10, FailureMessage = "10 char at most")]
    [StringRegex(@"^[a-zA-Z]+$", FailureMessage = "only letters")]
    public string FirstName { get; set; }

    [FlamingoFormProperty]
    [StringLength(10)]
    [StringRegex(@"^[a-zA-Z]+$", FailureMessage = "only letters")]
    public string LastName { get; set; }

    [FlamingoFormProperty]
    public int Code { get; set; }

    [FlamingoFormProperty(Required = false)]
    public Gender Gender { get; set; } = Gender.None;

    public string FullName => $"{FirstName} {LastName} ({Code}) ({Gender})";
}

Full example

There should be more

There should more that i forgot at the moment :)

Take a look at FlamingoProduction and Examples

What for now?

You can start from here

Flamingo Framework written in pure c#, install from Nuget

Clone this wiki locally