Skip to content

Commit 8ee0274

Browse files
committed
Any type of argument is available now
1 parent be61e5c commit 8ee0274

File tree

10 files changed

+179
-4
lines changed

10 files changed

+179
-4
lines changed

Deployf.Botf.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deployf.Botf.WebAppExample"
3636
EndProject
3737
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deployf.Botf.UnknownHandlingExample", "Examples\Deployf.Botf.UnknownHandlingExample\Deployf.Botf.UnknownHandlingExample.csproj", "{26897D3D-FDA0-4CA0-89AE-1B5EC777593B}"
3838
EndProject
39+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deployf.Botf.ActionsAndQueryExample", "Examples\Deployf.Botf.ActionsAndQueryExample\Deployf.Botf.ActionsAndQueryExample.csproj", "{171EAF49-EE72-4499-A841-A7E4EDC7D4FF}"
40+
EndProject
3941
Global
4042
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4143
Debug|Any CPU = Debug|Any CPU
@@ -90,6 +92,10 @@ Global
9092
{26897D3D-FDA0-4CA0-89AE-1B5EC777593B}.Debug|Any CPU.Build.0 = Debug|Any CPU
9193
{26897D3D-FDA0-4CA0-89AE-1B5EC777593B}.Release|Any CPU.ActiveCfg = Release|Any CPU
9294
{26897D3D-FDA0-4CA0-89AE-1B5EC777593B}.Release|Any CPU.Build.0 = Release|Any CPU
95+
{171EAF49-EE72-4499-A841-A7E4EDC7D4FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
96+
{171EAF49-EE72-4499-A841-A7E4EDC7D4FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
97+
{171EAF49-EE72-4499-A841-A7E4EDC7D4FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
98+
{171EAF49-EE72-4499-A841-A7E4EDC7D4FF}.Release|Any CPU.Build.0 = Release|Any CPU
9399
EndGlobalSection
94100
GlobalSection(SolutionProperties) = preSolution
95101
HideSolutionNode = FALSE
@@ -106,6 +112,7 @@ Global
106112
{F3B7EFA5-02B0-4970-9FAA-E4DD7D44C45E} = {90A07D9F-B417-4D28-BC58-5D987CB90430}
107113
{3C21F035-1A68-4782-B985-7BEB3600B501} = {90A07D9F-B417-4D28-BC58-5D987CB90430}
108114
{26897D3D-FDA0-4CA0-89AE-1B5EC777593B} = {90A07D9F-B417-4D28-BC58-5D987CB90430}
115+
{171EAF49-EE72-4499-A841-A7E4EDC7D4FF} = {90A07D9F-B417-4D28-BC58-5D987CB90430}
109116
EndGlobalSection
110117
GlobalSection(ExtensibilityGlobals) = postSolution
111118
SolutionGuid = {558E8FF9-5AE8-4471-BF84-D79F5B0E91FB}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
using System.Reflection;
2+
using Telegram.Bot.Framework.Abstractions;
3+
4+
namespace Deployf.Botf;
5+
6+
public class ArgumentBindBridge : IArgumentBind
7+
{
8+
readonly IKeyValueStorage _store;
9+
readonly IKeyGenerator _keyGenerator;
10+
11+
public ArgumentBindBridge(IKeyValueStorage store, IKeyGenerator keyGenerator)
12+
{
13+
_store = store;
14+
_keyGenerator = keyGenerator;
15+
}
16+
17+
public bool CanDecode(ParameterInfo parameter, object argument)
18+
{
19+
return !parameter.ParameterType.IsPrimitive;
20+
}
21+
22+
public bool CanEncode(ParameterInfo parameter, object argument)
23+
{
24+
return !parameter.ParameterType.IsPrimitive;
25+
}
26+
27+
public async ValueTask<object> Decode(ParameterInfo parameter, object argument, IUpdateContext ctx)
28+
{
29+
var userId = ctx.GetSafeUserId()!.Value;
30+
var objectId = "$_bridge_" + argument.ToString()!.Base64();
31+
var state = await _store.Get(userId, objectId, null);
32+
33+
// TODO: Check types
34+
35+
return state!;
36+
}
37+
38+
public string Encode(ParameterInfo parameter, object argument, IUpdateContext ctx)
39+
{
40+
// TODO: check types
41+
42+
var userId = ctx.GetSafeUserId()!.Value;
43+
var id = _keyGenerator.GetLongId();
44+
var objectId = "$_bridge_" + id;
45+
_store.Set(userId, objectId, argument);
46+
return id.Base64();
47+
}
48+
}

Deployf.Botf/ArgumentBinding/ArgumentBinder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public async ValueTask<object[]> Bind(MethodInfo method, object[] args, IUpdateC
2626
{
2727
bindings.Add(await binder.Decode(p, arg, ctx));
2828
found = true;
29-
continue;
29+
break;
3030
}
3131
}
3232

@@ -61,7 +61,7 @@ public object[] Convert(MethodInfo method, object[] args, IUpdateContext ctx)
6161
{
6262
bindings.Add(binder.Encode(p, arg, ctx));
6363
found = true;
64-
continue;
64+
break;
6565
}
6666
}
6767

Deployf.Botf/StartupExtensions.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ public static IServiceCollection AddBotf(this IServiceCollection services, BotfO
118118
services.AddTransient(ctx => ctx.GetRequiredService<BotfBot>().Client);
119119
services.AddTransient<MessageSender>();
120120

121+
services.AddTransient<IKeyGenerator, RandomKeyGenerator>();
122+
121123
services.AddSingleton<IArgumentBind, ArgumentBindInt32>();
122124
services.AddSingleton<IArgumentBind, ArgumentBindInt64>();
123125
services.AddSingleton<IArgumentBind, ArgumentBindBoolean>();
@@ -127,6 +129,7 @@ public static IServiceCollection AddBotf(this IServiceCollection services, BotfO
127129
services.AddSingleton<IArgumentBind, ArgumentBindEnum>();
128130
services.AddSingleton<IArgumentBind, ArgumentBindGuid>();
129131
services.AddSingleton<IArgumentBind, ArgumentAttributeBindState>();
132+
services.AddSingleton<IArgumentBind, ArgumentBindBridge>();
130133
services.AddSingleton<ArgumentBinder>();
131134

132135
return services;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Deployf.Botf;
2+
3+
public interface IKeyGenerator
4+
{
5+
long GetLongId();
6+
Guid GetGuidId();
7+
}
8+
9+
public class RandomKeyGenerator : IKeyGenerator
10+
{
11+
public Guid GetGuidId()
12+
{
13+
return Guid.NewGuid();
14+
}
15+
16+
public long GetLongId()
17+
{
18+
return Random.Shared.NextInt64();
19+
}
20+
}

Deployf.Botf/System/NumberExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ public static long Base64(this string base64)
88
{
99
base64 += "===".Substring(0, 4 - (base64.Length % 4));
1010
}
11-
var bytes = Convert.FromBase64String(base64);
11+
var bytes = Convert.FromBase64String(base64.Replace("-", "/"));
1212
return BitConverter.ToInt64(bytes);
1313
}
1414

1515
public static string Base64(this long value)
1616
{
1717
var bytes = BitConverter.GetBytes(value);
18-
return Convert.ToBase64String(bytes).Replace("=", "");
18+
return Convert.ToBase64String(bytes).Replace("/", "-").Replace("=", "");
1919
}
2020
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk.Web">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net6.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\..\Deployf.Botf\Deployf.Botf.csproj" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using Deployf.Botf;
2+
3+
BotfProgram.StartBot(args);
4+
5+
class ActionAndQueryController : BotController
6+
{
7+
[Action("/start", "start the bot")]
8+
public void Start()
9+
{
10+
PushL($"Hello!");
11+
Push("This an example of how to use Q(...) and action's parameters");
12+
13+
RowButton("Simple action", Q(ActionWithNoArgs));
14+
RowButton("Action with primitive args", Q(ActionWithPrimitiveArgs, 10, "hi"));
15+
16+
var instance = new ExampleClass
17+
{
18+
IntField = 25,
19+
StringProp = "very looooong string with many words"
20+
};
21+
RowButton("Action with class", Q(ActionWithStoredValue, instance));
22+
}
23+
24+
[Action]
25+
void ActionWithNoArgs()
26+
{
27+
Push("Just action :)");
28+
29+
RowButton("Back", Q(Start));
30+
RowButton("Back(manually)", "/start");
31+
}
32+
33+
[Action]
34+
void ActionWithPrimitiveArgs(int arg1, string arg2)
35+
{
36+
PushL("Action with primitive arguments");
37+
PushL($"Arg1: {arg1}");
38+
PushL($"Arg2: {arg2}");
39+
40+
RowButton("Back", Q(Start));
41+
}
42+
43+
[Action]
44+
void ActionWithStoredValue(ExampleClass instance)
45+
{
46+
PushL("Action with class as a parameter");
47+
PushL($"IntField: {instance.IntField}");
48+
PushL($"StringProp: {instance.StringProp}");
49+
50+
instance.IntField += 1;
51+
var action = Q(ActionWithStoredValue, instance);
52+
RowButton("IntField += 1", action);
53+
54+
RowButton("Back", Q(Start));
55+
}
56+
}
57+
58+
class ExampleClass
59+
{
60+
public int IntField;
61+
public string StringProp { get; set; }
62+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"profiles": {
3+
"Deployf.Botf.HelloExample": {
4+
"commandName": "Project",
5+
"dotnetRunMessages": true,
6+
"launchBrowser": false,
7+
"applicationUrl": "http://localhost:5281",
8+
"environmentVariables": {
9+
"ASPNETCORE_ENVIRONMENT": "Development"
10+
}
11+
}
12+
}
13+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
},
8+
"AllowedHosts": "*"
9+
}

0 commit comments

Comments
 (0)