Skip to content

Commit

Permalink
Merge pull request #34 from granstel/send-to-admin
Browse files Browse the repository at this point in the history
Send to admin
  • Loading branch information
granstel authored Oct 22, 2023
2 parents 9b9baf0 + 709a1b3 commit a7605bd
Show file tree
Hide file tree
Showing 24 changed files with 226 additions and 38 deletions.
6 changes: 5 additions & 1 deletion Dodo1000Bot.Api.Dialogflow.Tests/DialogflowServiceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal class DialogflowServiceTests
private Mock<IMapper> _mapperMock;
private Mock<IUsersService> _usersServiceMock;
private Mock<ICustomNotificationsRepository> _customNotificationsRepositoryMock;
private Mock<INotificationsService> _notificationsService;

private DialogflowService _target;

Expand All @@ -34,12 +35,15 @@ public void SetUp()
_mapperMock = _mockRepository.Create<IMapper>();
_usersServiceMock = _mockRepository.Create<IUsersService>();
_customNotificationsRepositoryMock = _mockRepository.Create<ICustomNotificationsRepository>();
_notificationsService = _mockRepository.Create<INotificationsService>();

_target = new DialogflowService(
_log,
_conversationServiceMock.Object,
_mapperMock.Object,
_usersServiceMock.Object, _customNotificationsRepositoryMock.Object);
_usersServiceMock.Object,
_customNotificationsRepositoryMock.Object,
_notificationsService.Object);

_fixture = new Fixture { OmitAutoProperties = true };
}
Expand Down
31 changes: 27 additions & 4 deletions Dodo1000Bot.Api.Dialogflow/DialogflowService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ public class DialogflowService : MessengerService<FulfillmentRequest, string>, I

private readonly IUsersService _usersService;
private readonly ICustomNotificationsRepository _customNotificationsRepository;
private readonly INotificationsService _notificationsService;

public DialogflowService(
ILogger<DialogflowService> log,
IConversationService conversationService,
IMapper mapper,
IUsersService usersService,
ICustomNotificationsRepository customNotificationsRepository) : base(log, conversationService, mapper)
IUsersService usersService,
ICustomNotificationsRepository customNotificationsRepository,
INotificationsService notificationsService) : base(log, conversationService, mapper)
{
_usersService = usersService;
_customNotificationsRepository = customNotificationsRepository;
Expand All @@ -35,8 +37,10 @@ public DialogflowService(
{
{ "SaveUser", SaveUser },
{ "DeleteUser", DeleteUser },
{ "SaveCustomNotification", SaveCustomNotification }
{ "SaveCustomNotification", SaveCustomNotification },
{ "SendToAdmin", SendToAdmin }
};
_notificationsService = notificationsService;
}

protected override async Task<Response> ProcessCommand(Request request, CancellationToken cancellationToken)
Expand Down Expand Up @@ -102,7 +106,7 @@ internal async Task DeleteUser(Request request, CancellationToken cancellationTo
/// <returns></returns>
private async Task SaveCustomNotification(Request request, CancellationToken cancellationToken)
{
var notification = new Notification
var notification = new Notification(NotificationType.Custom)
{
Payload = new NotificationPayload
{
Expand All @@ -112,4 +116,23 @@ private async Task SaveCustomNotification(Request request, CancellationToken can

await _customNotificationsRepository.Save(notification, cancellationToken);
}

/// <summary>
/// Action for key "SendToAdmin"
/// </summary>
/// <param name="request"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
private async Task SendToAdmin(Request request, CancellationToken cancellationToken)
{
var notification = new Notification(NotificationType.Admin)
{
Payload = new NotificationPayload
{
Text = request.Text
}
};

await _notificationsService.SendToAdmin(notification, cancellationToken);
}
}
2 changes: 1 addition & 1 deletion Dodo1000Bot.Api/Dodo1000Bot.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Version>1.21.0</Version>
<Version>1.22.0</Version>
<UserSecretsId>f449de95-800a-40ef-8716-6e80b7f0977d</UserSecretsId>
</PropertyGroup>

Expand Down
21 changes: 21 additions & 0 deletions Dodo1000Bot.Api/Migrations/202308292353_AddColumn_users_IsAdmin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using FluentMigrator;

namespace Dodo1000Bot.Api.Migrations;

[Migration(202308292353)]
public class AddColumn_Users_IsAdmin: Migration
{
public override void Up()
{
Execute.Sql
(@"
ALTER TABLE users
ADD COLUMN `IsAdmin` BIT NOT NULL DEFAULT 0;
");
}

public override void Down()
{
throw new System.NotImplementedException();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using FluentMigrator;

namespace Dodo1000Bot.Api.Migrations;

[Migration(202310221801)]
public class AddColumn_notifications_Type: Migration
{
public override void Up()
{
Execute.Sql
(@"
ALTER TABLE notifications
ADD COLUMN `Type` TINYINT(2) NOT NULL DEFAULT 0 AFTER `Id`,
ADD INDEX `Type` (`Type` ASC) VISIBLE;
");
}

public override void Down()
{
throw new System.NotImplementedException();
}
}
27 changes: 23 additions & 4 deletions Dodo1000Bot.Messengers.Telegram/TelegramNotifyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
using Dodo1000Bot.Services;
using Microsoft.Extensions.Logging;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Exceptions;
using Telegram.Bot.Types.Enums;

namespace Dodo1000Bot.Messengers.Telegram;

public class TelegramNotifyService: INotifyService
public class TelegramNotifyService : INotifyService
{
private readonly ILogger<TelegramNotifyService> _log;
private readonly IUsersRepository _usersRepository;
private readonly ITelegramBotClient _client;
private readonly ILogger<TelegramNotifyService> _log;

public TelegramNotifyService(IUsersRepository usersRepository, ITelegramBotClient client,
ILogger<TelegramNotifyService> log)
Expand All @@ -37,7 +38,7 @@ public async Task<IEnumerable<PushedNotification>> NotifyAbout(IList<Notificatio
return pushedNotifications;
}

IEnumerable<User> users = await _usersRepository.GetUsers(Source.Telegram, cancellationToken);
IList<Models.Domain.User> users = await _usersRepository.GetUsers(Source.Telegram, cancellationToken);

if (users?.Any() != true)
{
Expand All @@ -54,7 +55,7 @@ public async Task<IEnumerable<PushedNotification>> NotifyAbout(IList<Notificatio
return pushedNotifications;
}

private async Task<IList<PushedNotification>> PushNotificationsToUser(IList<Notification> notifications, User user, CancellationToken cancellationToken)
private async Task<IList<PushedNotification>> PushNotificationsToUser(IList<Notification> notifications, Models.Domain.User user, CancellationToken cancellationToken)
{
var pushedNotifications = new List<PushedNotification>();

Expand Down Expand Up @@ -96,4 +97,22 @@ await _client.SendTextMessageAsync(messengerUserId, notification.Payload.Text,

return pushedNotifications;
}

public async Task SendToAdmin(Notification notification, CancellationToken cancellationToken)
{
var admins = await _usersRepository.GetAdmins(Source.Telegram, cancellationToken);

foreach (var admin in admins)
{
try
{
await _client.SendTextMessageAsync(admin.MessengerUserId, notification.Payload.Text, parseMode: ParseMode.Html,
cancellationToken: cancellationToken);
}
catch (Exception e)
{
_log.LogError(e, "Error while send notification to {MessengerUserId}", admin.MessengerUserId);
}
}
}
}
9 changes: 7 additions & 2 deletions Dodo1000Bot.Models/Domain/Notification.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@
{
public class Notification
{
public Notification(NotificationType type)
{
Type = type;
}
public int Id { get; set; }

public NotificationType Type { get; }

public NotificationPayload Payload { get; set; }

public string Distinction => Payload.ToString().ToUpper()
.Replace(" ", string.Empty);
public string Distinction => $"{Payload}";
}
}
2 changes: 1 addition & 1 deletion Dodo1000Bot.Models/Domain/NotificationPayload.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class NotificationPayload

public override string ToString()
{
return $"{HappenedAt:d}{Text}";
return $"{HappenedAt:d}{Text}".ToUpper().Replace(" ", string.Empty);
}
}
}
17 changes: 17 additions & 0 deletions Dodo1000Bot.Models/NotificationType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Dodo1000Bot.Models;

public enum NotificationType
{
Custom,
TotalOverall,
TotalAtBrands,
TotalAtCountries,
TotalCountriesAtBrands,
NewCountry,
NewUnit,
OrdersPerMinute,
YearRevenue,
SubscribersCount,
Admin,
Emoji,
}
2 changes: 2 additions & 0 deletions Dodo1000Bot.Services/Interfaces/INotificationsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ public interface INotificationsService
Task PushNotifications(CancellationToken cancellationToken);

Task Delete(int notificationId, CancellationToken cancellationToken);

Task SendToAdmin(Notification notification, CancellationToken cancellationToken);
}
2 changes: 2 additions & 0 deletions Dodo1000Bot.Services/Interfaces/INotifyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ public interface INotifyService
{
Task<IEnumerable<PushedNotification>> NotifyAbout(IList<Notification> notifications,
CancellationToken cancellationToken);

Task SendToAdmin(Notification notification, CancellationToken cancellationToken);
}
2 changes: 2 additions & 0 deletions Dodo1000Bot.Services/Interfaces/IUsersRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ public interface IUsersRepository
Task Delete(User user, CancellationToken cancellationToken);

Task<int> Count(CancellationToken cancellationToken);

Task<IList<User>> GetAdmins(Source messengerType, CancellationToken cancellationToken);
}
}
18 changes: 17 additions & 1 deletion Dodo1000Bot.Services/NotificationsService.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -54,4 +55,19 @@ public async Task Delete(int notificationId, CancellationToken cancellationToken
{
await _notificationsRepository.Delete(notificationId, cancellationToken);
}

public async Task SendToAdmin(Notification notification, CancellationToken cancellationToken)
{
try
{
IEnumerable<Task> tasks =
_notifyServices.Select(s => s.SendToAdmin(notification, cancellationToken));

await Task.WhenAll(tasks);
}
catch (Exception e)
{
_logger.LogError(e, "Can't send to admin");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Threading;
using System.Threading.Tasks;
using Dapper;
using Dodo1000Bot.Models;
using Dodo1000Bot.Models.Domain;
using MySql.Data.MySqlClient;

Expand Down Expand Up @@ -42,7 +43,7 @@ public async Task<Notification> Get(int id, CancellationToken cancellationToken)
return null;
}

var notification = new Notification
var notification = new Notification(NotificationType.Custom)
{
Id = record.Id,
Payload = JsonSerializer.Deserialize<NotificationPayload>(record.Payload)
Expand Down
8 changes: 5 additions & 3 deletions Dodo1000Bot.Services/Repositories/NotificationsRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System.Threading;
using System.Threading.Tasks;
using Dapper;
using Dodo1000Bot.Models;
using Dodo1000Bot.Models.Domain;
using MySql.Data.MySqlClient;

Expand All @@ -25,9 +26,10 @@ public async Task Save(Notification notification, CancellationToken cancellation
var payload = JsonSerializer.Serialize(notification?.Payload);

await _connection.ExecuteAsync(new CommandDefinition(
"INSERT IGNORE INTO notifications (Payload, Distinction) VALUES (@payload, @distinction)",
"INSERT IGNORE INTO notifications (Type, Payload, Distinction) VALUES (@type, @payload, @distinction)",
new
{
notification?.Type,
payload,
notification?.Distinction
}, cancellationToken: cancellationToken));
Expand All @@ -36,12 +38,12 @@ await _connection.ExecuteAsync(new CommandDefinition(
public async Task<IList<Notification>> GetNotPushedNotifications(CancellationToken cancellationToken)
{
var records = await _connection.QueryAsync(new CommandDefinition(
@"SELECT n.Id, n.Payload FROM notifications n
@"SELECT n.Id, n.Type, n.Payload FROM notifications n
LEFT JOIN pushed_notifications pn
ON n.Id = pn.notificationId
WHERE pn.id IS NULL", cancellationToken: cancellationToken));

var notifications = records.Select(r => new Notification
var notifications = records.Select(r => new Notification(r.Type is NotificationType ? (NotificationType)r.Type : NotificationType.Custom)
{
Id = r.Id,
Payload = JsonSerializer.Deserialize<NotificationPayload>(r.Payload)
Expand Down
13 changes: 13 additions & 0 deletions Dodo1000Bot.Services/Repositories/UsersRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,18 @@ public async Task<int> Count(CancellationToken cancellationToken)

return count;
}

public async Task<IList<User>> GetAdmins(Source messengerType, CancellationToken cancellationToken)
{
var users = await _connection.QueryAsync<User>(new CommandDefinition(
@"SELECT Id, MessengerUserId, MessengerType FROM users
WHERE MessengerType = @messengerType AND IsAdmin = 1",
new
{
messengerType
}, cancellationToken: cancellationToken));

return users.ToImmutableArray();
}
}
}
Loading

0 comments on commit a7605bd

Please sign in to comment.