Skip to content

Commit f104421

Browse files
committed
Add ASP.NET Core project and enhance bot functionality
- Updated solution to include `TelegramBot.AspNetCoreTest`. - Improved bot controller registration in `ServiceCollectionExtensions.cs`. - Enhanced method validation in `InlineQueryHandler.cs`. - Added logging configuration in `appsettings.Development.json` and `appsettings.json`. - Created `Program.cs` for ASP.NET Core application setup. - Defined project structure in `TelegramBot.AspNetCoreTest.csproj`. - Added HTTP request file for API testing. - Introduced `WeatherForecast.cs` model for weather data. - Implemented `CounterController.cs` and `PhoneController.cs` for bot commands. - Added `WeatherForecastController.cs` for weather forecast API endpoint.
1 parent 4b52e3a commit f104421

12 files changed

Lines changed: 387 additions & 42 deletions
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
using Telegram.Bot.Types;
2+
using TelegramBot.Builders;
3+
using TelegramBot.Attributes;
4+
using TelegramBot.Controllers;
5+
using TelegramBot.Abstractions;
6+
using Telegram.Bot.Types.ReplyMarkups;
7+
8+
namespace TelegramBot.AspNetCoreTest.Controllers
9+
{
10+
public class CounterController(ILogger<CounterController> _logger) : BotControllerBase
11+
{
12+
private const string CounterKeyPrefix = "Counter:";
13+
private const string IncrementCommand = "/counter/increment";
14+
private const string DecrementCommand = "/counter/decrement";
15+
16+
[TextCommand("/counter")]
17+
public IActionResult GetCounter()
18+
{
19+
int value = GetCounterValue();
20+
_logger.LogInformation("Counter value requested: {Value}", value);
21+
return CreateCounterResponse(value, edit: false);
22+
}
23+
24+
[InlineCommand("/counter/increment")]
25+
public IActionResult IncrementCounter()
26+
{
27+
int value = GetCounterValue();
28+
value++;
29+
SetCounterValue(value);
30+
_logger.LogInformation("Counter incremented: {Value}", value);
31+
return CreateCounterResponse(value);
32+
}
33+
34+
[InlineCommand("/counter/decrement")]
35+
public IActionResult DecrementCounter()
36+
{
37+
int value = GetCounterValue();
38+
value--;
39+
SetCounterValue(value);
40+
_logger.LogInformation("Counter decremented: {Value}", value);
41+
return CreateCounterResponse(value);
42+
}
43+
44+
private string GetCounterKey() => $"{CounterKeyPrefix}{User.Id}";
45+
46+
private int GetCounterValue() => GetValue<int>(GetCounterKey());
47+
48+
private void SetCounterValue(int value) => SetValue(GetCounterKey(), value);
49+
50+
private static InlineKeyboardMarkup CreateCounterKeyboard()
51+
{
52+
return new KeyboardBuilder()
53+
.WithColumns(2)
54+
.AddButton("➖", DecrementCommand)
55+
.AddButton("➕", IncrementCommand)
56+
.Build();
57+
}
58+
59+
private IActionResult CreateCounterResponse(int value, bool edit = true)
60+
{
61+
string message = $"{CounterKeyPrefix} {value}";
62+
return edit ? TextEdit(message, CreateCounterKeyboard()) : Inline(message, CreateCounterKeyboard());
63+
}
64+
}
65+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
using TelegramBot.Builders;
2+
using TelegramBot.Attributes;
3+
using TelegramBot.Controllers;
4+
using TelegramBot.Abstractions;
5+
using Telegram.Bot.Types.ReplyMarkups;
6+
7+
namespace TelegramBot.AspNetCoreTest.Controllers
8+
{
9+
public class PhoneController(ILogger<PhoneController> _logger) : BotControllerBase
10+
{
11+
private const string PhoneKeyPrefix = "Phone:";
12+
13+
[TextCommand("/phone")]
14+
public IActionResult GetPhone()
15+
{
16+
long value = GetPhoneValue();
17+
_logger.LogInformation("Counter value requested: {Value}", value);
18+
return CreateCounterResponse(value, edit: false);
19+
}
20+
21+
[InlineCommand("/phone/{digit}")]
22+
public IActionResult AddDigit(int digit)
23+
{
24+
if (digit < 0 || digit > 9)
25+
{
26+
_logger.LogWarning("Invalid digit: {Digit}", digit);
27+
return Text("Please enter a valid digit (0-9).");
28+
}
29+
long value = GetPhoneValue();
30+
if (value > 999_999_9999)
31+
{
32+
_logger.LogWarning("Phone number exceeds 11 digits.");
33+
return Void();
34+
}
35+
value = value * 10 + digit;
36+
SetPhoneValue(value);
37+
_logger.LogInformation("Phone changed: {Value}", value);
38+
return CreateCounterResponse(value);
39+
}
40+
41+
[InlineCommand("/phone/delete")]
42+
public IActionResult DeleteLastDigit()
43+
{
44+
long value = GetPhoneValue();
45+
if (value == 0)
46+
{
47+
_logger.LogWarning("No digits to delete.");
48+
return Void();
49+
}
50+
value /= 10; // Remove the last digit
51+
SetPhoneValue(value);
52+
_logger.LogInformation("Last digit deleted, new value: {Value}", value);
53+
return CreateCounterResponse(value);
54+
}
55+
56+
[InlineCommand("/phone/confirm")]
57+
public IActionResult ConfirmPhone()
58+
{
59+
long value = GetPhoneValue();
60+
if (value == 0)
61+
{
62+
_logger.LogWarning("No phone number entered.");
63+
return Text("Please enter a valid phone number.");
64+
}
65+
_logger.LogInformation("Phone number confirmed: {Value}", value);
66+
return Text($"Phone number confirmed: {FormatPhoneNumber(value)}");
67+
}
68+
69+
private static string FormatPhoneNumber(long value)
70+
{
71+
if (value <= 0)
72+
{
73+
return "+_ (___) ___-____";
74+
}
75+
string phoneNumber = value.ToString().PadRight(11, '_');
76+
return $"+{phoneNumber[0]} ({phoneNumber[1..4]}) {phoneNumber.Substring(4, 3)}-{phoneNumber.Substring(7, 4)}";
77+
}
78+
79+
private string GetPhoneKey() => $"{PhoneKeyPrefix}{User.Id}";
80+
81+
private long GetPhoneValue() => GetValue<long>(GetPhoneKey());
82+
83+
private void SetPhoneValue(long value) => SetValue(GetPhoneKey(), value);
84+
85+
private static InlineKeyboardMarkup CreatePhoneKeyboard(bool showNumbers = true)
86+
{
87+
var builder = new KeyboardBuilder()
88+
.WithColumns(3);
89+
for (int i = 1; i <= 9 && showNumbers; i++)
90+
{
91+
builder.AddButton(i.ToString(), $"/phone/{i}");
92+
}
93+
builder.AddButton("⬅️", "/phone/delete");
94+
if (showNumbers)
95+
{
96+
builder.AddButton("0", "/phone/0");
97+
}
98+
builder.AddButton("📞", "/phone/confirm");
99+
return builder.Build();
100+
}
101+
102+
private IActionResult CreateCounterResponse(long value, bool edit = true)
103+
{
104+
// Fix for CS8076, CS8361, CS8088, CS1002, CS0103, and CS0201
105+
// Parenthesize the conditional expression and ensure proper syntax
106+
string message = FormatPhoneNumber(value);
107+
return edit
108+
? TextEdit(message, CreatePhoneKeyboard(value < 999_999_9999))
109+
: Inline(message, CreatePhoneKeyboard(value < 999_999_9999));
110+
}
111+
}
112+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using Microsoft.AspNetCore.Mvc;
2+
3+
namespace TelegramBot.AspNetCoreTest.Controllers
4+
{
5+
[ApiController]
6+
[Route("[controller]")]
7+
public class WeatherForecastController : ControllerBase
8+
{
9+
private static readonly string[] Summaries = new[]
10+
{
11+
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
12+
};
13+
14+
private readonly ILogger<WeatherForecastController> _logger;
15+
16+
public WeatherForecastController(ILogger<WeatherForecastController> logger)
17+
{
18+
_logger = logger;
19+
}
20+
21+
[HttpGet]
22+
public IEnumerable<WeatherForecast> Get()
23+
{
24+
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
25+
{
26+
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
27+
TemperatureC = Random.Shared.Next(-20, 55),
28+
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
29+
})
30+
.ToArray();
31+
}
32+
}
33+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
using TelegramBot.Builders;
2+
using TelegramBot.Extensions;
3+
4+
namespace TelegramBot.AspNetCoreTest
5+
{
6+
public class Program
7+
{
8+
public static void Main(string[] args)
9+
{
10+
var builder = WebApplication.CreateBuilder(args);
11+
builder.Services.AddControllers();
12+
builder.Services.AddBotControllers();
13+
14+
new BotBuilder(builder)
15+
.UseApiKey(x => x.FromConfiguration())
16+
.Build();
17+
18+
var app = builder.Build();
19+
app.UseAuthorization();
20+
app.MapControllers();
21+
app.Run();
22+
}
23+
}
24+
}
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>net9.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<ProjectReference Include="..\TelegramBot\TelegramBot.csproj" />
11+
</ItemGroup>
12+
13+
</Project>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@TelegramBot.AspNetCoreTest_HostAddress = http://localhost:5196
2+
3+
GET {{TelegramBot.AspNetCoreTest_HostAddress}}/weatherforecast/
4+
Accept: application/json
5+
6+
###
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
namespace TelegramBot.AspNetCoreTest
2+
{
3+
public class WeatherForecast
4+
{
5+
public DateOnly Date { get; set; }
6+
7+
public int TemperatureC { get; set; }
8+
9+
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
10+
11+
public string? Summary { get; set; }
12+
}
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"Logging": {
3+
"LogLevel": {
4+
"Default": "Information",
5+
"Microsoft.AspNetCore": "Warning"
6+
}
7+
}
8+
}
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+
}

Sources/TelegramBot.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBot.ConsoleTest", "
77
EndProject
88
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TelegramBot", "TelegramBot\TelegramBot.csproj", "{B58FAC8E-492D-45E2-8D24-4FE1B65E10AB}"
99
EndProject
10+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TelegramBot.AspNetCoreTest", "TelegramBot.AspNetCoreTest\TelegramBot.AspNetCoreTest.csproj", "{FC403FDA-EF7B-4565-A0E0-C668D18BA3A0}"
11+
EndProject
1012
Global
1113
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1214
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
2123
{B58FAC8E-492D-45E2-8D24-4FE1B65E10AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
2224
{B58FAC8E-492D-45E2-8D24-4FE1B65E10AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
2325
{B58FAC8E-492D-45E2-8D24-4FE1B65E10AB}.Release|Any CPU.Build.0 = Release|Any CPU
26+
{FC403FDA-EF7B-4565-A0E0-C668D18BA3A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27+
{FC403FDA-EF7B-4565-A0E0-C668D18BA3A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
28+
{FC403FDA-EF7B-4565-A0E0-C668D18BA3A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
29+
{FC403FDA-EF7B-4565-A0E0-C668D18BA3A0}.Release|Any CPU.Build.0 = Release|Any CPU
2430
EndGlobalSection
2531
GlobalSection(SolutionProperties) = preSolution
2632
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)