Telegram entegrasyonu

This commit is contained in:
Sedat ÖZTÜRK 2026-08-28 15:03:36 +03:00
parent 91de623a85
commit a670d2e966
31 changed files with 403 additions and 48 deletions

View file

@ -9,5 +9,5 @@ public static class NotificationChannels
public const string UiActivity = "UiActivity"; //UI Activity (ABP UI Activity) public const string UiActivity = "UiActivity"; //UI Activity (ABP UI Activity)
public const string UiToast = "UiToast"; //UI Toast (ABP UI Toast) Ayarlar/Sistem/Bildirimler/Chrome açık olması gerekiyor. public const string UiToast = "UiToast"; //UI Toast (ABP UI Toast) Ayarlar/Sistem/Bildirimler/Chrome açık olması gerekiyor.
public const string WhatsApp = "WhatsApp"; //WhatsApp (HTTP API, template-based) public const string WhatsApp = "WhatsApp"; //WhatsApp (HTTP API, template-based)
// public const string Telegram = "Telegram"; public const string Telegram = "Telegram"; //Telegram (Bot API, chat based)
} }

View file

@ -40,7 +40,7 @@ public class NotificationIdentifierProvider : INotificationIdentifierProvider
NotificationChannels.UiActivity => user.Id.ToString(), NotificationChannels.UiActivity => user.Id.ToString(),
NotificationChannels.UiToast => user.Id.ToString(), NotificationChannels.UiToast => user.Id.ToString(),
NotificationChannels.WhatsApp => user.PhoneNumber, NotificationChannels.WhatsApp => user.PhoneNumber,
// NotificationChannels.Telegram => user.PhoneNumber, NotificationChannels.Telegram => user.GetProperty<string?>("TelegramChatId"),
_ => null, _ => null,
}; };

View file

@ -5,6 +5,7 @@ using Sozsoft.Sender.Mail.AmazonSes;
using Sozsoft.Sender.Rocket; using Sozsoft.Sender.Rocket;
using Sozsoft.Sender.Sms; using Sozsoft.Sender.Sms;
using Sozsoft.Sender.Sms.PostaGuvercini; using Sozsoft.Sender.Sms.PostaGuvercini;
using Sozsoft.Sender.Telegram;
using Sozsoft.Sender.WhatsApp; using Sozsoft.Sender.WhatsApp;
using Volo.Abp.BackgroundJobs; using Volo.Abp.BackgroundJobs;
using Volo.Abp.Emailing; using Volo.Abp.Emailing;
@ -36,6 +37,7 @@ public class ErpSenderModule : AbpModule
context.Services.AddScoped<ISozsoftSmsSender>(sp => sp.GetRequiredService<PostaGuverciniSmsSender>()); context.Services.AddScoped<ISozsoftSmsSender>(sp => sp.GetRequiredService<PostaGuverciniSmsSender>());
context.Services.AddScoped<ISozsoftRocketSender>(sp => sp.GetRequiredService<RocketSender>()); context.Services.AddScoped<ISozsoftRocketSender>(sp => sp.GetRequiredService<RocketSender>());
context.Services.AddScoped<ISozsoftWhatsAppSender>(sp => sp.GetRequiredService<SozsoftWhatsAppSender>()); context.Services.AddScoped<ISozsoftWhatsAppSender>(sp => sp.GetRequiredService<SozsoftWhatsAppSender>());
context.Services.AddScoped<ISozsoftTelegramSender>(sp => sp.GetRequiredService<SozsoftTelegramSender>());
context.Services.AddHttpClient<PostaGuverciniHttpClient>(); context.Services.AddHttpClient<PostaGuverciniHttpClient>();
context.Services.AddScoped<IPostaGuverciniHttpClient>(sp => sp.GetRequiredService<PostaGuverciniHttpClient>()); context.Services.AddScoped<IPostaGuverciniHttpClient>(sp => sp.GetRequiredService<PostaGuverciniHttpClient>());
@ -46,6 +48,9 @@ public class ErpSenderModule : AbpModule
context.Services.AddHttpClient<WhatsAppHttpClient>(); context.Services.AddHttpClient<WhatsAppHttpClient>();
context.Services.AddScoped<IWhatsAppHttpClient>(sp => sp.GetRequiredService<WhatsAppHttpClient>()); context.Services.AddScoped<IWhatsAppHttpClient>(sp => sp.GetRequiredService<WhatsAppHttpClient>());
context.Services.AddHttpClient<TelegramHttpClient>();
context.Services.AddScoped<ITelegramHttpClient>(sp => sp.GetRequiredService<TelegramHttpClient>());
} }
} }

View file

@ -0,0 +1,44 @@
using Microsoft.Extensions.Logging;
using Volo.Abp.DependencyInjection;
namespace Sozsoft.Sender.Telegram;
public interface ISozsoftTelegramSender : ITransientDependency
{
Task<TelegramSendResult> SendAsync(string ChatId, string Message);
}
public class SozsoftTelegramSender : ISozsoftTelegramSender
{
private readonly ITelegramHttpClient httpClient;
private readonly ILogger<SozsoftTelegramSender> logger;
public SozsoftTelegramSender(
ITelegramHttpClient httpClient,
ILogger<SozsoftTelegramSender> logger)
{
this.httpClient = httpClient;
this.logger = logger;
}
public async Task<TelegramSendResult> SendAsync(string ChatId, string Message)
{
logger.LogInformation("Sending Telegram message. {ChatId}, {Message}", ChatId, Message);
var result = await httpClient.SendMessageAsync(ChatId, Message);
var success = result?.ok == true;
if (success)
{
logger.LogInformation("Telegram sent successfully. {ChatId}, {Message}", ChatId, Message);
}
else
{
logger.LogWarning("Failed to send Telegram message. {ChatId}, {Message}, {ErrorCode}, {Description}",
ChatId, Message, result?.error_code, result?.description);
}
return new TelegramSendResult
{
Success = success,
};
}
}

View file

@ -0,0 +1,44 @@
using System.Net.Http.Json;
using Volo.Abp.Settings;
namespace Sozsoft.Sender.Telegram;
public interface ITelegramHttpClient
{
Task<TelegramSendResultDto> SendMessageAsync(string ChatId, string Message);
}
public sealed class TelegramHttpClient : ITelegramHttpClient, IDisposable
{
private readonly HttpClient httpClient;
private readonly ISettingProvider settingProvider;
public TelegramHttpClient(
HttpClient httpClient,
ISettingProvider settingProvider)
{
this.httpClient = httpClient;
this.settingProvider = settingProvider;
}
public async Task<TelegramSendResultDto> SendMessageAsync(string ChatId, string Message)
{
var url = await settingProvider.GetOrNullAsync(TelegramSettingNames.Url);
var botToken = await settingProvider.GetOrNullAsync(TelegramSettingNames.BotToken);
var parseMode = await settingProvider.GetOrNullAsync(TelegramSettingNames.ParseMode);
var response = await httpClient.PostAsJsonAsync($"{url.TrimEnd('/')}/bot{botToken}/sendMessage",
new TelegramPostMessageInput
{
chat_id = ChatId,
text = Message,
parse_mode = parseMode.IsNullOrWhiteSpace() ? null : parseMode,
disable_web_page_preview = true
});
// Bot API hatayı 4xx gövdesinde açıklar; durum kodunu fırlatmak açıklamayı kaybettirir.
return await response.Content.ReadFromJsonAsync<TelegramSendResultDto>();
}
public void Dispose() => httpClient?.Dispose();
}

View file

@ -0,0 +1,9 @@
namespace Sozsoft.Sender.Telegram;
public class TelegramPostMessageInput
{
public string chat_id { get; set; }
public string text { get; set; }
public string parse_mode { get; set; }
public bool disable_web_page_preview { get; set; }
}

View file

@ -0,0 +1,6 @@
namespace Sozsoft.Sender.Telegram;
public class TelegramSendResult
{
public bool Success { get; set; }
}

View file

@ -0,0 +1,23 @@
namespace Sozsoft.Sender.Telegram;
public class TelegramSendResultDto
{
public bool ok { get; set; }
public int? error_code { get; set; }
public string description { get; set; }
public Message result { get; set; }
public class Message
{
public long message_id { get; set; }
public int date { get; set; }
public Chat chat { get; set; }
public class Chat
{
public long id { get; set; }
public string type { get; set; }
public string username { get; set; }
}
}
}

View file

@ -0,0 +1,9 @@
namespace Sozsoft.Sender.Telegram;
public static class TelegramSettingNames
{
public const string Default = "App.Sender.Telegram.";
public const string Url = Default + "Url"; // https://api.telegram.org
public const string BotToken = Default + "BotToken"; // BotFather token: 123456:ABC-DEF...
public const string ParseMode = Default + "ParseMode"; // HTML | Markdown | MarkdownV2 | (bos)
}

View file

@ -38,6 +38,7 @@ public class UserInfoViewModel : ExtensibleObject
public bool ShouldChangePasswordOnNextLogin { get; set; } public bool ShouldChangePasswordOnNextLogin { get; set; }
public string Avatar { get; set; } public string Avatar { get; set; }
public string RocketUsername { get; set; } public string RocketUsername { get; set; }
public string TelegramChatId { get; set; }
public DateTimeOffset? CreationTime { get; set; } public DateTimeOffset? CreationTime { get; set; }
public DateTimeOffset? LastModificationTime { get; set; } public DateTimeOffset? LastModificationTime { get; set; }
public string WorkHour { get; set; } public string WorkHour { get; set; }

View file

@ -260,6 +260,7 @@ public class PlatformIdentityAppService : ApplicationService
user.Surname = UserInfo.Surname; user.Surname = UserInfo.Surname;
user.SetPhoneNumber(UserInfo.PhoneNumber, user.PhoneNumberConfirmed); user.SetPhoneNumber(UserInfo.PhoneNumber, user.PhoneNumberConfirmed);
user.SetRocketUsername(UserInfo.RocketUsername); user.SetRocketUsername(UserInfo.RocketUsername);
user.SetTelegramChatId(UserInfo.TelegramChatId);
user.SetWorkHour(UserInfo.WorkHour); user.SetWorkHour(UserInfo.WorkHour);
user.SetDepartmentId(UserInfo.DepartmentId); user.SetDepartmentId(UserInfo.DepartmentId);
user.SetJobPositionId(UserInfo.JobPositionId); user.SetJobPositionId(UserInfo.JobPositionId);

View file

@ -16,6 +16,7 @@ public static class UserInfoViewModelMappingExtensions
userInfoViewModel.LoginEndDate = user.GetLoginEndDate(); userInfoViewModel.LoginEndDate = user.GetLoginEndDate();
userInfoViewModel.Avatar = user.GetAvatar(); userInfoViewModel.Avatar = user.GetAvatar();
userInfoViewModel.RocketUsername = user.GetRocketUsername(); userInfoViewModel.RocketUsername = user.GetRocketUsername();
userInfoViewModel.TelegramChatId = user.GetTelegramChatId();
userInfoViewModel.WorkHour = user.GetWorkHour(); userInfoViewModel.WorkHour = user.GetWorkHour();
userInfoViewModel.DepartmentId = user.GetDepartmentId(); userInfoViewModel.DepartmentId = user.GetDepartmentId();
userInfoViewModel.JobPositionId = user.GetJobPositionId(); userInfoViewModel.JobPositionId = user.GetJobPositionId();

View file

@ -414,6 +414,58 @@
"selectOptions": {}, "selectOptions": {},
"order": 16 "order": 16
}, },
{
"code": "App.Sender.Telegram.Url",
"nameKey": "App.Sender.Telegram.Url",
"descriptionKey": "App.SenderUrl.UrlDescription",
"defaultValue": "https://api.telegram.org",
"isVisibleToClients": false,
"providers": "T|G|D",
"isInherited": false,
"isEncrypted": false,
"mainGroupKey": "App.Sender",
"subGroupKey": "App.Sender.Telegram",
"requiredPermissionName": "App.Sender.Telegram",
"dataType": "Text",
"selectOptions": {},
"order": 17
},
{
"code": "App.Sender.Telegram.BotToken",
"nameKey": "App.Sender.Telegram.BotToken",
"descriptionKey": "App.TelegramBotToken.BotTokenDescription",
"defaultValue": "8783091157:AAHlTHofhUmQtAd3JwPShkGBbL_JwPJjI7c",
"isVisibleToClients": false,
"providers": "T|G|D",
"isInherited": false,
"isEncrypted": true,
"mainGroupKey": "App.Sender",
"subGroupKey": "App.Sender.Telegram",
"requiredPermissionName": "App.Sender.Telegram",
"dataType": "Text",
"selectOptions": {},
"order": 18
},
{
"code": "App.Sender.Telegram.ParseMode",
"nameKey": "App.Sender.Telegram.ParseMode",
"descriptionKey": "App.TelegramParseMode.ParseModeDescription",
"defaultValue": "HTML",
"isVisibleToClients": false,
"providers": "T|G|D",
"isInherited": false,
"isEncrypted": false,
"mainGroupKey": "App.Sender",
"subGroupKey": "App.Sender.Telegram",
"requiredPermissionName": "App.Sender.Telegram",
"dataType": "List",
"selectOptions": {
"HTML": "HTML",
"Markdown": "Markdown",
"MarkdownV2": "MarkdownV2"
},
"order": 19
},
{ {
"code": "App.Sender.Rocket.Url", "code": "App.Sender.Rocket.Url",
"nameKey": "App.Sender.Rocket.Url", "nameKey": "App.Sender.Rocket.Url",
@ -428,7 +480,7 @@
"requiredPermissionName": "App.Sender.Rocket", "requiredPermissionName": "App.Sender.Rocket",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 17 "order": 20
}, },
{ {
"code": "App.Sender.Rocket.UserId", "code": "App.Sender.Rocket.UserId",
@ -444,7 +496,7 @@
"requiredPermissionName": "App.Sender.Rocket", "requiredPermissionName": "App.Sender.Rocket",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 18 "order": 21
}, },
{ {
"code": "App.Sender.Rocket.Token", "code": "App.Sender.Rocket.Token",
@ -460,7 +512,7 @@
"requiredPermissionName": "App.Sender.Rocket", "requiredPermissionName": "App.Sender.Rocket",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 19 "order": 22
}, },
{ {
"code": "Abp.Mailing.DefaultFromDisplayName", "code": "Abp.Mailing.DefaultFromDisplayName",
@ -476,7 +528,7 @@
"requiredPermissionName": "Abp.Mailing", "requiredPermissionName": "Abp.Mailing",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 20 "order": 23
}, },
{ {
"code": "Abp.Mailing.DefaultFromAddress", "code": "Abp.Mailing.DefaultFromAddress",
@ -492,7 +544,7 @@
"requiredPermissionName": "Abp.Mailing", "requiredPermissionName": "Abp.Mailing",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 21 "order": 24
}, },
{ {
"code": "Abp.Mailing.Smtp.UserName", "code": "Abp.Mailing.Smtp.UserName",
@ -508,7 +560,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 22 "order": 25
}, },
{ {
"code": "Abp.Mailing.Smtp.Password", "code": "Abp.Mailing.Smtp.Password",
@ -524,7 +576,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 23 "order": 26
}, },
{ {
"code": "Abp.Mailing.Smtp.Host", "code": "Abp.Mailing.Smtp.Host",
@ -540,7 +592,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 24 "order": 27
}, },
{ {
"code": "Abp.Mailing.Smtp.Port", "code": "Abp.Mailing.Smtp.Port",
@ -556,7 +608,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 25 "order": 28
}, },
{ {
"code": "Abp.Mailing.Smtp.Domain", "code": "Abp.Mailing.Smtp.Domain",
@ -572,7 +624,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 26 "order": 29
}, },
{ {
"code": "Abp.Mailing.Smtp.EnableSsl", "code": "Abp.Mailing.Smtp.EnableSsl",
@ -588,7 +640,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 27 "order": 30
}, },
{ {
"code": "Abp.Mailing.Smtp.UseDefaultCredentials", "code": "Abp.Mailing.Smtp.UseDefaultCredentials",
@ -604,7 +656,7 @@
"requiredPermissionName": "Abp.Mailing.Smtp", "requiredPermissionName": "Abp.Mailing.Smtp",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 28 "order": 31
}, },
{ {
"code": "Abp.Mailing.AWS.Profile", "code": "Abp.Mailing.AWS.Profile",
@ -620,7 +672,7 @@
"requiredPermissionName": "Abp.Mailing.AWS", "requiredPermissionName": "Abp.Mailing.AWS",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 29 "order": 32
}, },
{ {
"code": "Abp.Mailing.AWS.Region", "code": "Abp.Mailing.AWS.Region",
@ -636,7 +688,7 @@
"requiredPermissionName": "Abp.Mailing.AWS", "requiredPermissionName": "Abp.Mailing.AWS",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 30 "order": 33
}, },
{ {
"code": "Abp.Mailing.AWS.AccessKey", "code": "Abp.Mailing.AWS.AccessKey",
@ -652,7 +704,7 @@
"requiredPermissionName": "Abp.Mailing.AWS", "requiredPermissionName": "Abp.Mailing.AWS",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 31 "order": 34
}, },
{ {
"code": "Abp.Mailing.AWS.AccessKeyId", "code": "Abp.Mailing.AWS.AccessKeyId",
@ -668,7 +720,7 @@
"requiredPermissionName": "Abp.Mailing.AWS", "requiredPermissionName": "Abp.Mailing.AWS",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 32 "order": 35
}, },
{ {
"code": "Abp.Account.IsSelfRegistrationEnabled", "code": "Abp.Account.IsSelfRegistrationEnabled",
@ -684,7 +736,7 @@
"requiredPermissionName": "Abp.Account.General", "requiredPermissionName": "Abp.Account.General",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 40 "order": 43
}, },
{ {
"code": "Abp.Account.EnableLocalLogin", "code": "Abp.Account.EnableLocalLogin",
@ -700,7 +752,7 @@
"requiredPermissionName": "Abp.Account.General", "requiredPermissionName": "Abp.Account.General",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 41 "order": 44
}, },
{ {
"code": "Abp.Account.TwoFactor.Enabled", "code": "Abp.Account.TwoFactor.Enabled",
@ -716,7 +768,7 @@
"requiredPermissionName": "Abp.Account.TwoFactor", "requiredPermissionName": "Abp.Account.TwoFactor",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 42 "order": 45
}, },
{ {
"code": "Abp.Account.Captcha.MaxFailedAccessAttempts", "code": "Abp.Account.Captcha.MaxFailedAccessAttempts",
@ -732,7 +784,7 @@
"requiredPermissionName": "Abp.Account.Captcha", "requiredPermissionName": "Abp.Account.Captcha",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 43 "order": 46
}, },
{ {
"code": "Abp.Account.Captcha.EndPoint", "code": "Abp.Account.Captcha.EndPoint",
@ -748,7 +800,7 @@
"requiredPermissionName": "Abp.Account.Captcha", "requiredPermissionName": "Abp.Account.Captcha",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 44 "order": 47
}, },
{ {
"code": "Abp.Account.Captcha.SiteKey", "code": "Abp.Account.Captcha.SiteKey",
@ -764,7 +816,7 @@
"requiredPermissionName": "Abp.Account.Captcha", "requiredPermissionName": "Abp.Account.Captcha",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 45 "order": 48
}, },
{ {
"code": "Abp.Account.Captcha.SecretKey", "code": "Abp.Account.Captcha.SecretKey",
@ -780,7 +832,7 @@
"requiredPermissionName": "Abp.Account.Captcha", "requiredPermissionName": "Abp.Account.Captcha",
"dataType": "Text", "dataType": "Text",
"selectOptions": {}, "selectOptions": {},
"order": 46 "order": 49
}, },
{ {
"code": "Abp.Identity.Profile.General.RequireVerifiedAccount", "code": "Abp.Identity.Profile.General.RequireVerifiedAccount",
@ -796,7 +848,7 @@
"requiredPermissionName": "Abp.Identity.Profile", "requiredPermissionName": "Abp.Identity.Profile",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 50 "order": 53
}, },
{ {
"code": "Abp.Identity.Profile.General.BlacklistedEmailProviders", "code": "Abp.Identity.Profile.General.BlacklistedEmailProviders",
@ -812,7 +864,7 @@
"requiredPermissionName": "Abp.Identity.Profile", "requiredPermissionName": "Abp.Identity.Profile",
"dataType": "Memo", "dataType": "Memo",
"selectOptions": {}, "selectOptions": {},
"order": 51 "order": 54
}, },
{ {
"code": "Abp.Identity.SignIn.RequireConfirmedEmail", "code": "Abp.Identity.SignIn.RequireConfirmedEmail",
@ -828,7 +880,7 @@
"requiredPermissionName": "Abp.Identity.SignIn", "requiredPermissionName": "Abp.Identity.SignIn",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 60 "order": 63
}, },
{ {
"code": "Abp.Identity.SignIn.RequireEmailVerificationToRegister", "code": "Abp.Identity.SignIn.RequireEmailVerificationToRegister",
@ -844,7 +896,7 @@
"requiredPermissionName": "Abp.Identity.SignIn", "requiredPermissionName": "Abp.Identity.SignIn",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 61 "order": 64
}, },
{ {
"code": "Abp.Identity.SignIn.RequireConfirmedPhoneNumber", "code": "Abp.Identity.SignIn.RequireConfirmedPhoneNumber",
@ -860,7 +912,7 @@
"requiredPermissionName": "Abp.Identity.SignIn", "requiredPermissionName": "Abp.Identity.SignIn",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 62 "order": 65
}, },
{ {
"code": "Abp.Identity.SignIn.EnablePhoneNumberConfirmation", "code": "Abp.Identity.SignIn.EnablePhoneNumberConfirmation",
@ -876,7 +928,7 @@
"requiredPermissionName": "Abp.Identity.SignIn", "requiredPermissionName": "Abp.Identity.SignIn",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 63 "order": 66
}, },
{ {
"code": "Abp.Identity.User.IsUserNameUpdateEnabled", "code": "Abp.Identity.User.IsUserNameUpdateEnabled",
@ -892,7 +944,7 @@
"requiredPermissionName": "Abp.Identity.User", "requiredPermissionName": "Abp.Identity.User",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 64 "order": 67
}, },
{ {
"code": "Abp.Identity.User.IsEmailUpdateEnabled", "code": "Abp.Identity.User.IsEmailUpdateEnabled",
@ -908,7 +960,7 @@
"requiredPermissionName": "Abp.Identity.User", "requiredPermissionName": "Abp.Identity.User",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 65 "order": 68
}, },
@ -926,7 +978,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 70 "order": 73
}, },
{ {
"code": "Abp.Identity.Password.PasswordChangePeriodDays", "code": "Abp.Identity.Password.PasswordChangePeriodDays",
@ -942,7 +994,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 71 "order": 74
}, },
{ {
"code": "Abp.Identity.Password.RequiredLength", "code": "Abp.Identity.Password.RequiredLength",
@ -958,7 +1010,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 72 "order": 75
}, },
{ {
"code": "Abp.Identity.Password.RequiredUniqueChars", "code": "Abp.Identity.Password.RequiredUniqueChars",
@ -974,7 +1026,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 73 "order": 76
}, },
{ {
"code": "Abp.Identity.Password.RequireNonAlphanumeric", "code": "Abp.Identity.Password.RequireNonAlphanumeric",
@ -990,7 +1042,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 74 "order": 77
}, },
{ {
"code": "Abp.Identity.Password.RequireLowercase", "code": "Abp.Identity.Password.RequireLowercase",
@ -1006,7 +1058,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 75 "order": 78
}, },
{ {
"code": "Abp.Identity.Password.RequireUppercase", "code": "Abp.Identity.Password.RequireUppercase",
@ -1022,7 +1074,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 76 "order": 79
}, },
{ {
"code": "Abp.Identity.Password.RequireDigit", "code": "Abp.Identity.Password.RequireDigit",
@ -1038,7 +1090,7 @@
"requiredPermissionName": "Abp.Identity.Password", "requiredPermissionName": "Abp.Identity.Password",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 77 "order": 80
}, },
{ {
"code": "Abp.Identity.Lockout.AllowedForNewUsers", "code": "Abp.Identity.Lockout.AllowedForNewUsers",
@ -1054,7 +1106,7 @@
"requiredPermissionName": "Abp.Identity.Lockout", "requiredPermissionName": "Abp.Identity.Lockout",
"dataType": "Bool", "dataType": "Bool",
"selectOptions": {}, "selectOptions": {},
"order": 78 "order": 81
}, },
{ {
"code": "Abp.Identity.Lockout.LockoutDuration", "code": "Abp.Identity.Lockout.LockoutDuration",
@ -1070,7 +1122,7 @@
"requiredPermissionName": "Abp.Identity.Lockout", "requiredPermissionName": "Abp.Identity.Lockout",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 79 "order": 82
}, },
{ {
"code": "Abp.Identity.Lockout.MaxFailedAccessAttempts", "code": "Abp.Identity.Lockout.MaxFailedAccessAttempts",
@ -1086,7 +1138,7 @@
"requiredPermissionName": "Abp.Identity.Lockout", "requiredPermissionName": "Abp.Identity.Lockout",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 80 "order": 83
}, },
{ {
"code": "Abp.Identity.OrganizationUnit.MaxUserMembershipCount", "code": "Abp.Identity.OrganizationUnit.MaxUserMembershipCount",
@ -1102,7 +1154,7 @@
"requiredPermissionName": "Abp.Identity.OrganizationUnits", "requiredPermissionName": "Abp.Identity.OrganizationUnits",
"dataType": "Number", "dataType": "Number",
"selectOptions": {}, "selectOptions": {},
"order": 90 "order": 93
} }
], ],
"NotificationTypes": [], "NotificationTypes": [],

View file

@ -1986,6 +1986,42 @@
"en": "The token for the WhatsApp service.", "en": "The token for the WhatsApp service.",
"tr": "WhatsApp hizmeti için token." "tr": "WhatsApp hizmeti için token."
}, },
{
"resourceName": "Platform",
"key": "App.Sender.Telegram",
"en": "Telegram",
"tr": "Telegram"
},
{
"resourceName": "Platform",
"key": "App.Sender.Telegram.Url",
"en": "Url",
"tr": "Url"
},
{
"resourceName": "Platform",
"key": "App.Sender.Telegram.BotToken",
"en": "Bot Token",
"tr": "Bot Token"
},
{
"resourceName": "Platform",
"key": "App.TelegramBotToken.BotTokenDescription",
"en": "The BotFather token of the Telegram bot.",
"tr": "Telegram botunun BotFather token bilgisi."
},
{
"resourceName": "Platform",
"key": "App.Sender.Telegram.ParseMode",
"en": "Parse Mode",
"tr": "Biçimlendirme Modu"
},
{
"resourceName": "Platform",
"key": "App.TelegramParseMode.ParseModeDescription",
"en": "The formatting mode used for Telegram messages.",
"tr": "Telegram mesajlarında kullanılan biçimlendirme modu."
},
{ {
"resourceName": "Platform", "resourceName": "Platform",
"key": "App.Sender.Rocket", "key": "App.Sender.Rocket",
@ -3468,6 +3504,12 @@
"en": "Rocket User Name", "en": "Rocket User Name",
"tr": "Rocket Kullanıcı Adı" "tr": "Rocket Kullanıcı Adı"
}, },
{
"resourceName": "Platform",
"key": "App.Platform.TelegramChatId",
"en": "Telegram Chat Id",
"tr": "Telegram Sohbet Kimliği"
},
{ {
"resourceName": "Platform", "resourceName": "Platform",
"key": "Abp.Identity.UserLockedOutMessage", "key": "Abp.Identity.UserLockedOutMessage",

View file

@ -5387,6 +5387,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new () { Key="Sms", Name="App.Sender.Sms" }, new () { Key="Sms", Name="App.Sender.Sms" },
new () { Key="Mail", Name="App.StaticLookup.Mail" }, new () { Key="Mail", Name="App.StaticLookup.Mail" },
new () { Key="WhatsApp", Name="App.Sender.WhatsApp" }, new () { Key="WhatsApp", Name="App.Sender.WhatsApp" },
new () { Key="Telegram", Name="App.Sender.Telegram" },
new () { Key="Rocket", Name="App.StaticLookup.Rocket" }, new () { Key="Rocket", Name="App.StaticLookup.Rocket" },
new () { Key="UiActivity", Name="App.StaticLookup.UiActivity" }, new () { Key="UiActivity", Name="App.StaticLookup.UiActivity" },
new () { Key="UiToast", Name="App.StaticLookup.UiToast" }, new () { Key="UiToast", Name="App.StaticLookup.UiToast" },
@ -5608,6 +5609,7 @@ public class ListFormSeeder_Saas : IDataSeedContributor, ITransientDependency
new () { Key="UiActivity", Name="App.StaticLookup.UiActivity" }, new () { Key="UiActivity", Name="App.StaticLookup.UiActivity" },
new () { Key="UiToast", Name="App.StaticLookup.UiToast" }, new () { Key="UiToast", Name="App.StaticLookup.UiToast" },
new () { Key="WhatsApp", Name="App.Sender.WhatsApp" }, new () { Key="WhatsApp", Name="App.Sender.WhatsApp" },
new () { Key="Telegram", Name="App.Sender.Telegram" },
}), }),
}), }),
ColumnCustomizationJson = DefaultColumnCustomizationJson, ColumnCustomizationJson = DefaultColumnCustomizationJson,

View file

@ -2714,6 +2714,15 @@
"MultiTenancySide": 3, "MultiTenancySide": 3,
"MenuGroup": "Erp|Kurs" "MenuGroup": "Erp|Kurs"
}, },
{
"GroupName": "App.Administration",
"Name": "App.Sender.Telegram",
"ParentName": "App.Sender",
"DisplayName": "App.Sender.Telegram",
"IsEnabled": true,
"MultiTenancySide": 3,
"MenuGroup": "Erp|Kurs"
},
{ {
"GroupName": "App.Administration", "GroupName": "App.Administration",
"Name": "App.Sender.Rocket", "Name": "App.Sender.Rocket",

View file

@ -105,6 +105,7 @@ public static class PlatformConsts
public const string IsVerified = "IsVerified"; public const string IsVerified = "IsVerified";
public const string Avatar = "Avatar"; public const string Avatar = "Avatar";
public const string RocketUsername = "RocketUsername"; public const string RocketUsername = "RocketUsername";
public const string TelegramChatId = "TelegramChatId";
public const string HomeAddress = "HomeAddress"; public const string HomeAddress = "HomeAddress";
public const string EducationLevel = "EducationLevel"; public const string EducationLevel = "EducationLevel";
public const string GraduationSchool = "GraduationSchool"; public const string GraduationSchool = "GraduationSchool";
@ -342,6 +343,15 @@ public static class PlatformConsts
public const string TemplateName = Default + ".TemplateName"; public const string TemplateName = Default + ".TemplateName";
public const string Token = Default + ".Token"; public const string Token = Default + ".Token";
} }
public static class Telegram
{
public const string Default = GroupName + ".Telegram";
public const string Url = Default + ".Url";
public const string BotToken = Default + ".BotToken";
public const string ParseMode = Default + ".ParseMode";
}
} }
} }

View file

@ -84,6 +84,13 @@ public static class PlatformModuleExtensionConfigurator
property.DisplayName = new LocalizableString(typeof(PlatformResource), PlatformConsts.AbpIdentity.User.RocketUsername); property.DisplayName = new LocalizableString(typeof(PlatformResource), PlatformConsts.AbpIdentity.User.RocketUsername);
}); });
user.AddOrUpdateProperty<string>(
PlatformConsts.AbpIdentity.User.TelegramChatId,
property =>
{
property.DisplayName = new LocalizableString(typeof(PlatformResource), PlatformConsts.AbpIdentity.User.TelegramChatId);
});
user.AddOrUpdateProperty<Guid>( user.AddOrUpdateProperty<Guid>(
PlatformConsts.AbpIdentity.User.DepartmentId, PlatformConsts.AbpIdentity.User.DepartmentId,
property => property =>

View file

@ -10,6 +10,7 @@ using Sozsoft.Platform.Data.Seeds;
using Sozsoft.Sender.Mail; using Sozsoft.Sender.Mail;
using Sozsoft.Sender.Rocket; using Sozsoft.Sender.Rocket;
using Sozsoft.Sender.Sms; using Sozsoft.Sender.Sms;
using Sozsoft.Sender.Telegram;
using Sozsoft.Sender.WhatsApp; using Sozsoft.Sender.WhatsApp;
using Volo.Abp.BackgroundWorkers; using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Domain.Repositories; using Volo.Abp.Domain.Repositories;
@ -28,6 +29,7 @@ public class NotificationWorker : BackgroundWorkerBase
protected ISozsoftEmailSender ErpEmailSender { get; } protected ISozsoftEmailSender ErpEmailSender { get; }
protected ISozsoftSmsSender ErpSmsSender { get; } protected ISozsoftSmsSender ErpSmsSender { get; }
protected ISozsoftWhatsAppSender ErpWhatsAppSender { get; } protected ISozsoftWhatsAppSender ErpWhatsAppSender { get; }
protected ISozsoftTelegramSender ErpTelegramSender { get; }
protected ISettingProvider SettingProvider { get; } protected ISettingProvider SettingProvider { get; }
public NotificationWorker( public NotificationWorker(
@ -38,6 +40,7 @@ public class NotificationWorker : BackgroundWorkerBase
ISozsoftRocketSender erpRocketSender, ISozsoftRocketSender erpRocketSender,
ISozsoftEmailSender erpEmailSender, ISozsoftEmailSender erpEmailSender,
ISozsoftWhatsAppSender erpWhatsAppSender, ISozsoftWhatsAppSender erpWhatsAppSender,
ISozsoftTelegramSender erpTelegramSender,
ISettingProvider settingProvider) ISettingProvider settingProvider)
{ {
Repository = repository; Repository = repository;
@ -47,6 +50,7 @@ public class NotificationWorker : BackgroundWorkerBase
ErpRocketSender = erpRocketSender; ErpRocketSender = erpRocketSender;
ErpEmailSender = erpEmailSender; ErpEmailSender = erpEmailSender;
ErpWhatsAppSender = erpWhatsAppSender; ErpWhatsAppSender = erpWhatsAppSender;
ErpTelegramSender = erpTelegramSender;
SettingProvider = settingProvider; SettingProvider = settingProvider;
} }
@ -140,6 +144,25 @@ public class NotificationWorker : BackgroundWorkerBase
} }
} }
var telegram = await Repository.GetListAsync(a => a.NotificationChannel == NotificationChannels.Telegram && !a.IsSent, cancellationToken: cancellationToken);
foreach (var notification in telegram)
{
try
{
var result = await ErpTelegramSender.SendAsync(notification.Identifier, notification.Message);
if (result.Success)
{
notification.IsSent = true;
notification.IsRead = true;
await Repository.UpdateAsync(notification, autoSave: true, cancellationToken: cancellationToken);
}
}
catch (Exception ex)
{
Logger.LogException(ex);
}
}
await uow.SaveChangesAsync(cancellationToken); await uow.SaveChangesAsync(cancellationToken);
} }
} }

View file

@ -305,6 +305,15 @@ public static class SeedConsts
public const string TemplateName = Default + ".TemplateName"; public const string TemplateName = Default + ".TemplateName";
public const string Token = Default + ".Token"; public const string Token = Default + ".Token";
} }
public static class Telegram
{
public const string Default = GroupName + ".Telegram";
public const string Url = Default + ".Url";
public const string BotToken = Default + ".BotToken";
public const string ParseMode = Default + ".ParseMode";
}
} }
} }

View file

@ -61,6 +61,16 @@ public static class AbpIdentityUserExtensions
return user.GetProperty<string>(PlatformConsts.AbpIdentity.User.RocketUsername); return user.GetProperty<string>(PlatformConsts.AbpIdentity.User.RocketUsername);
} }
//Telegram Chat Id
public static void SetTelegramChatId(this IdentityUser user, string telegramChatId)
{
user.SetProperty(PlatformConsts.AbpIdentity.User.TelegramChatId, telegramChatId);
}
public static string GetTelegramChatId(this IdentityUser user)
{
return user.GetProperty<string>(PlatformConsts.AbpIdentity.User.TelegramChatId);
}
//Work Hour //Work Hour
public static void SetWorkHour(this IdentityUser user, string workHour) public static void SetWorkHour(this IdentityUser user, string workHour)
{ {

View file

@ -65,6 +65,15 @@ public static class PlatformEfCoreEntityExtensionMappings
} }
); );
ObjectExtensionManager.Instance
.MapEfCoreProperty<IdentityUser, string>(
PlatformConsts.AbpIdentity.User.TelegramChatId,
(entityBuilder, propertyBuilder) =>
{
propertyBuilder.HasMaxLength(64).HasDefaultValue(null);
}
);
ObjectExtensionManager.Instance ObjectExtensionManager.Instance
.MapEfCoreProperty<IdentityUser, string>( .MapEfCoreProperty<IdentityUser, string>(
PlatformConsts.AbpIdentity.User.WorkHour, PlatformConsts.AbpIdentity.User.WorkHour,

View file

@ -13,7 +13,7 @@ using Volo.Abp.EntityFrameworkCore;
namespace Sozsoft.Platform.Migrations namespace Sozsoft.Platform.Migrations
{ {
[DbContext(typeof(PlatformDbContext))] [DbContext(typeof(PlatformDbContext))]
[Migration("20260826070015_Initial")] [Migration("20260828094327_Initial")]
partial class Initial partial class Initial
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -7854,6 +7854,10 @@ namespace Sozsoft.Platform.Migrations
.HasColumnType("nvarchar(64)") .HasColumnType("nvarchar(64)")
.HasColumnName("Surname"); .HasColumnName("Surname");
b.Property<string>("TelegramChatId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<Guid?>("TenantId") b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier") .HasColumnType("uniqueidentifier")
.HasColumnName("TenantId"); .HasColumnName("TenantId");

View file

@ -461,6 +461,7 @@ namespace Sozsoft.Platform.Migrations
SequenceNo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true), SequenceNo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true),
SerialNo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true), SerialNo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true),
SskNo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true), SskNo = table.Column<string>(type: "nvarchar(32)", maxLength: 32, nullable: true),
TelegramChatId = table.Column<string>(type: "nvarchar(64)", maxLength: 64, nullable: true),
TerminationDate = table.Column<DateTime>(type: "datetime2", nullable: true), TerminationDate = table.Column<DateTime>(type: "datetime2", nullable: true),
UserType = table.Column<int>(type: "int", nullable: false, defaultValue: 0), UserType = table.Column<int>(type: "int", nullable: false, defaultValue: 0),
Village = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true), Village = table.Column<string>(type: "nvarchar(128)", maxLength: 128, nullable: true),

View file

@ -7851,6 +7851,10 @@ namespace Sozsoft.Platform.Migrations
.HasColumnType("nvarchar(64)") .HasColumnType("nvarchar(64)")
.HasColumnName("Surname"); .HasColumnName("Surname");
b.Property<string>("TelegramChatId")
.HasMaxLength(64)
.HasColumnType("nvarchar(64)");
b.Property<Guid?>("TenantId") b.Property<Guid?>("TenantId")
.HasColumnType("uniqueidentifier") .HasColumnType("uniqueidentifier")
.HasColumnName("TenantId"); .HasColumnName("TenantId");

View file

@ -6,7 +6,7 @@ const NotificationChannels = {
UiActivity: 'UiActivity', UiActivity: 'UiActivity',
UiToast: 'UiToast', UiToast: 'UiToast',
WhatsApp: 'WhatsApp', WhatsApp: 'WhatsApp',
// Telegram: 'Telegram', Telegram: 'Telegram',
} }
export const NotificationChannelColors: Record<string, string> = { export const NotificationChannelColors: Record<string, string> = {
@ -17,7 +17,7 @@ export const NotificationChannelColors: Record<string, string> = {
UiActivity: 'bg-lime-600', UiActivity: 'bg-lime-600',
UiToast: 'bg-emerald-800', UiToast: 'bg-emerald-800',
WhatsApp: 'bg-cyan-600', WhatsApp: 'bg-cyan-600',
// Telegram: 'bg-purple-900', Telegram: 'bg-purple-900',
} }
export default NotificationChannels export default NotificationChannels

View file

@ -140,6 +140,7 @@ export interface UserInfoViewModel extends ExtensibleObject {
shouldChangePasswordOnNextLogin: boolean shouldChangePasswordOnNextLogin: boolean
avatar: string avatar: string
rocketUsername?: string rocketUsername?: string
telegramChatId?: string
creationTime: Date | string creationTime: Date | string
lastModificationTime: Date | string lastModificationTime: Date | string
workHour?: string workHour?: string

View file

@ -35,6 +35,7 @@ const ActivityLog = () => {
NotificationChannels.UiActivity, NotificationChannels.UiActivity,
NotificationChannels.UiToast, NotificationChannels.UiToast,
NotificationChannels.WhatsApp, NotificationChannels.WhatsApp,
NotificationChannels.Telegram,
]) ])
const fetchData = useCallback(async (isLoadmore: boolean = false) => { const fetchData = useCallback(async (isLoadmore: boolean = false) => {

View file

@ -15,6 +15,7 @@ const ticketCheckboxes = [
{ label: NotificationChannels.UiActivity, value: NotificationChannels.UiActivity }, { label: NotificationChannels.UiActivity, value: NotificationChannels.UiActivity },
{ label: NotificationChannels.UiToast, value: NotificationChannels.UiToast }, { label: NotificationChannels.UiToast, value: NotificationChannels.UiToast },
{ label: NotificationChannels.WhatsApp, value: NotificationChannels.WhatsApp }, { label: NotificationChannels.WhatsApp, value: NotificationChannels.WhatsApp },
{ label: NotificationChannels.Telegram, value: NotificationChannels.Telegram },
] ]
const CategoryTitle = ({ children, className }: CategoryTitleProps) => { const CategoryTitle = ({ children, className }: CategoryTitleProps) => {

View file

@ -20,6 +20,7 @@ import {
import 'react-advanced-cropper/dist/style.css' import 'react-advanced-cropper/dist/style.css'
import { import {
FaFacebookMessenger, FaFacebookMessenger,
FaTelegramPlane,
FaEnvelope, FaEnvelope,
FaTrashAlt, FaTrashAlt,
FaUserCircle, FaUserCircle,
@ -293,6 +294,16 @@ const General = () => {
value={profileData?.extraProperties?.['RocketUsername'] as string | undefined} value={profileData?.extraProperties?.['RocketUsername'] as string | undefined}
></Input> ></Input>
</FormItem> </FormItem>
<FormItem label={translate('::App.Platform.TelegramChatId')}>
<Input
disabled
type="text"
prefix={<FaTelegramPlane className="text-xl" />}
value={
profileData?.extraProperties?.['TelegramChatId'] as string | undefined
}
></Input>
</FormItem>
</div> </div>
<div> <div>

View file

@ -49,6 +49,7 @@ import {
FaPhone, FaPhone,
FaUserCircle, FaUserCircle,
FaFacebookMessenger, FaFacebookMessenger,
FaTelegramPlane,
FaHome, FaHome,
FaUniversity, FaUniversity,
FaCalendarAlt, FaCalendarAlt,
@ -828,6 +829,21 @@ function UserDetails() {
</FormItem> </FormItem>
</div> </div>
<div>
<FormItem
size="sm"
label={translate('::App.Platform.TelegramChatId')}
>
<Field
type="text"
name="telegramChatId"
placeholder={translate('::App.Platform.TelegramChatId')}
component={Input}
prefix={<FaTelegramPlane className="text-xl" />}
/>
</FormItem>
</div>
<div> <div>
<FormItem <FormItem
label={translate('::Abp.Identity.User.UserInformation.SskNo')} label={translate('::Abp.Identity.User.UserInformation.SskNo')}