Releases: deploy-f/botf
[v0.17.3] Registered filters
[v0.17.2] Fixed UpdateContextExtensions methods
- The
IUpdateContext
extension methodsGetSafeChatId()
andGetSafeUserId
now checking values from more types of Updates - Added new
IUpdateContext
extensions methods:GetSafeChat()
andGetSafeUser()
- Added filters:
FilterSuccessfulPayment
andFilterPreCheckoutQuery
[v0.17] Fixed updates of messages containing photos
Explanation of a fix
Now your messages containing photos are updating correctly while handling CallbackQuery
from Telegram.
Here is 4 scenarios:
1st
First message with photo, second - without.
What should happen: the 1st will be deleted and the second will be sent.
2st
No photo in the 1st message, but there is in the 2nd.
What should happen: the 1st will be deleted and the second will be sent
3st
No photo in the 1st message, neither in the 2nd.
What should happen: 1st message would be updated without deletion
4st
There is a photo in the 1st and in the 2nd message.
What should happen: by default Botf will just update 1st message with a new photo. But if you specify UpdateMessagePolicy
via Context.SetUpdateMsgPolicy()
to UpdateMessagePolicy.DeleteAndSend
so the 1st message would be deleted and Botf will send a new one with a new photo and text.
You can find code examples here
[v0.15] New era of handler's filters
New pre-built filters
Regex filter
Now you can use regex template to select a specific message and handle it. Pass the template to named parameter Param
in filter's constuctor for Filters.Regex
filter.
[Filter(Filters.Regex, Param: "Hello .*!")]
[On(Handle.Unknown)]
public void UnknownTextHello()
{
PushL("Hey!");
}
Filters have their own attribute
Use the Filter()
attribute to specify filters rather than passing it in the On()
attribute
[On(Handle.Unknown)]
[Filter(Filters.Text)]
public void UnknownNewTextHandler()
{
Reply();
PushL("Unknown text message");
Context.StopHandling();
}
Combination of filters for single handler
Now you can specify many filters and use boolean operators for it.
[On(Handle.Unknown)]
[Filter(Filters.Text)]
[Filter(And: Filters.Regex, Param: "Hello .*!")]
public void UnknownTextHello()
{
Reply();
PushL("Hey!");
Context.StopHandling();
}
Added new filters:
Filters.NotGlobalState
Filters.CurrentGlobalState
Filters.Regex
Filters.PrivateChat
Filters.GroupChat
Filters.Type
👉 Full example you can see HERE
[0.14.2] Send now returns Message object
Send
andUpdate
methods returnsMessage
object- Controller has new property
MessageId
. Set MessageId to update needed message withUpdate
method.
👉 Example is here
[v0.14] New era of controller's state and improvements in Unknown handlers
Q() supports classes !
That time has come! Now you can do this:
var foo = new ExampleClass
{
IntField = 25,
StringProp = "very looooong string with many words"
};
Button("Click me", Q(HandleIt, foo));
....
[Action]
void HandleIt(ExampleClass foo)
{
PushL($"StringProp: {foo.StringProp}");
}
Looks like magic but it works!
Example is here
Controller state saving and restoring
Now you can save controller's state acros the updates. "State" means controller's fields and properties.
To save the state you have to mark it with [State]
attribute.
It looks like that:
class Example : BotController
{
[State]
int intField;
...
}
intField
will be saved between user's updates.
Fully featured example is located here
improved Unknown handlers
Beginning from v0.14 you have ability to make many of Unknown
handlers in your code.
Second thing is that you can use filters to decide when botf has to call your handler.
See the complete example of the new feature here
[v0.13] Web Apps support
🕸Telegram bot WebApps is now supporting in BotF
See the code example here
[0.12] Sending photos, Url buttons
Sending photos
Now you can send photo via calling Photo("http://path.to/photo.png")
Url buttons
If you pass valid url into payload in the button, the button will be a link.
Example:
[Action("/start")]
void Start()
{
// Add the photo to message
Photo("https://avatars.githubusercontent.com/u/59260433");
Push("Hello from deploy-f");
Button("Got to botf repo", "https://github.com/deploy-f/botf");
}
[v0.11] Argument binding for Guid type
Now you can pass Guid argument into callback/action methods:
[Action("/start", "start")]
void Start()
{
var guid = Guid.NewGuid();
Push("Click the button");
Button($"guid: {guid}", Q(GuidArgumentButtonHandler, guid));
}
[Action]
async Task GuidArgumentButtonHandler(Guid guid)
{
Push($"value: {guid}");
}
[v0.10] Timeout for chain flow
There were an issue the chain was hanging in memory if user does not answer the chain request (calls like AwaitText()
, AwaitUpdate()
and AwaitQuery()
) and that cause memory leaks.
We've added a mechanism to break this dangling chains by the timeout.
How to configure this option
Add a key into connection string with name chain_timeout
and set the value in TimeSpan format (value 0:0:5
- means 5 seconds, 0:5
- 5 minutes, etc).
ℹ️ Default value is 1 hour
Example:
"botf": "123456:MAHHFJSMFNJASKFNSALVDMD?chain_timeout=0:2"
How to handle timeout
We've added new type to handle these events - Handle.ChainTimeout
Example of a code:
[On(Handle.ChainTimeout)]
void ChainTimeout()
{
PushL("timeout");
}
Or you can specify custom handle for any of calls AwaitText()
, AwaitUpdate()
and AwaitQuery()
by passing a delegate with your custom implementation
Example:
var name = await AwaitText(() => Send("Use /start to try again"));