Add ChatUsername

This commit is contained in:
Sergey Nazarov 2024-03-22 00:38:37 +04:00
parent 94600fa953
commit 38abbae070
11 changed files with 65 additions and 47 deletions

View File

@ -9,7 +9,7 @@
<PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" /> <PackageVersion Include="Swashbuckle.AspNetCore" Version="6.5.0" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Serilog"> <ItemGroup Label="Serilog">
<PackageVersion Include="Nocr.TelegramListener.Async.Api.Contracts" Version="[0.2.0,1.0.0)" /> <PackageVersion Include="Nocr.TelegramListener.Async.Api.Contracts" Version="0.3.0" />
<PackageVersion Include="RestEase" Version="1.6.4" /> <PackageVersion Include="RestEase" Version="1.6.4" />
<PackageVersion Include="Serilog" Version="3.1.1" /> <PackageVersion Include="Serilog" Version="3.1.1" />
<PackageVersion Include="Serilog.AspNetCore" Version="8.0.1" /> <PackageVersion Include="Serilog.AspNetCore" Version="8.0.1" />
@ -26,9 +26,9 @@
<PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="$(MicrosoftVersion)" /> <PackageVersion Include="Microsoft.AspNetCore.OpenApi" Version="$(MicrosoftVersion)" />
</ItemGroup> </ItemGroup>
<ItemGroup Label="Tests"> <ItemGroup Label="Tests">
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.0"/> <PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageVersion Include="xunit" Version="2.4.2"/> <PackageVersion Include="xunit" Version="2.4.2" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5"/> <PackageVersion Include="xunit.runner.visualstudio" Version="2.4.5" />
<PackageVersion Include="coverlet.collector" Version="6.0.0"/> <PackageVersion Include="coverlet.collector" Version="6.0.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,21 +1,16 @@
using Nocr.TextMatcher.AppServices.Contracts.TextMatches; using Nocr.TextMatcher.AppServices.Contracts.TextMatches;
using RestEase;
namespace Nocr.TextMatcher.Api.Contracts.TextMatches.Dto; namespace Nocr.TextMatcher.Api.Contracts.TextMatches.Dto;
public class CreateTextMatchRequest public class CreateTextMatchRequest
{ {
public long UserId { get; set; } public long UserId { get; set; }
public long ChatId { get; set; } public long ChatId { get; set; }
public string ChatUsername { get; set; }
public string Template { get; set; } public string Template { get; set; }
public TextMatchRule Rule { get; set; }
}
[BasePath(WebRoutes.TextMatches.Path)] public TextMatchRule Rule { get; set; }
public interface ITextMatcherController
{
Task<long> Create([Body] CreateTextMatchRequest request, CancellationToken cancellationToken = default);
} }

View File

@ -0,0 +1,10 @@
using Nocr.TextMatcher.Api.Contracts.TextMatches.Dto;
using RestEase;
namespace Nocr.TextMatcher.Api.Contracts.TextMatches;
[BasePath(WebRoutes.TextMatches.Path)]
public interface ITextMatchesController
{
Task<long> Create([Body] CreateTextMatchRequest request, CancellationToken cancellationToken = default);
}

View File

@ -5,16 +5,16 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions"/> <PackageReference Include="Microsoft.Extensions.Logging.Abstractions" />
<PackageReference Include="Nocr.TelegramListener.Async.Api.Contracts"/> <PackageReference Include="Nocr.TelegramListener.Async.Api.Contracts" />
<PackageReference Include="Rebus"/> <PackageReference Include="Rebus" />
<PackageReference Include="Rebus.ServiceProvider"/> <PackageReference Include="Rebus.ServiceProvider" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Nocr.TextMatcher.AppServices.Contracts\Nocr.TextMatcher.AppServices.Contracts.csproj"/> <ProjectReference Include="..\Nocr.TextMatcher.AppServices.Contracts\Nocr.TextMatcher.AppServices.Contracts.csproj" />
<ProjectReference Include="..\Nocr.TextMatcher.Async.Api.Contracts\Nocr.TextMatcher.Async.Api.Contracts.csproj"/> <ProjectReference Include="..\Nocr.TextMatcher.Async.Api.Contracts\Nocr.TextMatcher.Async.Api.Contracts.csproj" />
<ProjectReference Include="..\Nocr.TextMatcher.Core\Nocr.TextMatcher.Core.csproj"/> <ProjectReference Include="..\Nocr.TextMatcher.Core\Nocr.TextMatcher.Core.csproj" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -34,7 +34,7 @@ public sealed class MessageReceivedHandler : IHandleMessages<MessageReceived>
foreach (var match in matches) foreach (var match in matches)
{ {
if (match.IsMatches(message.ChatId, message.Text)) if (match.IsMatches(message.ChatId, message.ChatUserName, message.Text))
{ {
_logger.LogInformation("Message {@Message} matched {@Match}", message, match); _logger.LogInformation("Message {@Message} matched {@Match}", message, match);
var @event = new TextMatchMatched var @event = new TextMatchMatched

View File

@ -4,7 +4,7 @@ namespace Nocr.TextMatcher.AppServices.TextMatches.Services;
public interface ITextMatchService public interface ITextMatchService
{ {
Task<long> Create(long userId, long chatId, string template, TextMatchRule rule, CancellationToken cancellationToken = default); Task<long> Create(long userId, long chatId, string chatUsername, string template, TextMatchRule rule, CancellationToken cancellationToken = default);
Task Delete(long id, CancellationToken cancellationToken = default); Task Delete(long id, CancellationToken cancellationToken = default);

View File

@ -20,19 +20,20 @@ public sealed class TextMatchService : ITextMatchService
_dateProvider = dateProvider ?? throw new ArgumentNullException(nameof(dateProvider)); _dateProvider = dateProvider ?? throw new ArgumentNullException(nameof(dateProvider));
} }
public async Task<long> Create(long userId, long chatId, string template, TextMatchRule rule, public async Task<long> Create(long userId, long chatId, string chatUsername, string template, TextMatchRule rule,
CancellationToken cancellationToken = default) CancellationToken cancellationToken = default)
{ {
var textMatch = TextMatch.Initialize(userId, chatId, template, rule, _dateProvider.UtcNow); var textMatch = TextMatch.Initialize(userId, chatId, chatUsername, template, rule, _dateProvider.UtcNow);
await _repository.Create(textMatch, cancellationToken); await _repository.Create(textMatch, cancellationToken);
var @event = new TextMatchCreated var @event = new TextMatchCreated
{ {
ChatId = chatId ChatId = chatId,
ChatUsername = textMatch.ChatUsername
}; };
await _bus.Advanced.Topics.Publish("nocr.text.matcher", @event); await _bus.Advanced.Topics.Publish("nocr.text.matcher", @event);
return textMatch.Id; return textMatch.Id;
} }

View File

@ -11,6 +11,8 @@ public sealed class TextMatch
public long ChatId { get; private set; } public long ChatId { get; private set; }
public string ChatUsername { get; private set; }
public string Template { get; private set; } public string Template { get; private set; }
public TextMatchRule Rule { get; private set; } public TextMatchRule Rule { get; private set; }
@ -19,12 +21,14 @@ public sealed class TextMatch
private TextMatch(long userId, private TextMatch(long userId,
long chatId, long chatId,
string chatUsername,
string template, string template,
TextMatchRule rule, TextMatchRule rule,
DateTimeOffset createdDateTime) DateTimeOffset createdDateTime)
{ {
UserId = userId; UserId = userId;
ChatId = chatId; ChatId = chatId;
ChatUsername = chatUsername;
Template = template; Template = template;
Rule = rule; Rule = rule;
CreatedDateTime = createdDateTime; CreatedDateTime = createdDateTime;
@ -32,6 +36,7 @@ public sealed class TextMatch
public static TextMatch Initialize(long userId, public static TextMatch Initialize(long userId,
long chatId, long chatId,
string chatUsername,
string template, string template,
TextMatchRule rule, TextMatchRule rule,
DateTimeOffset createdDateTime) DateTimeOffset createdDateTime)
@ -45,12 +50,15 @@ public sealed class TextMatch
if (string.IsNullOrWhiteSpace(template)) if (string.IsNullOrWhiteSpace(template))
throw new ArgumentException("Template should not be empty", nameof(template)); throw new ArgumentException("Template should not be empty", nameof(template));
return new TextMatch(userId, chatId, template, rule, createdDateTime); if (string.IsNullOrWhiteSpace(chatUsername))
throw new ArgumentException("Chat username should not be empty", nameof(chatUsername));
return new TextMatch(userId, chatId, chatUsername, template, rule, createdDateTime);
} }
public bool IsMatches(long chatId, string text) public bool IsMatches(long chatId, string chatUsername, string text)
{ {
if (ChatId != chatId) if (ChatId != chatId && !string.Equals(ChatUsername, chatUsername, StringComparison.OrdinalIgnoreCase))
return false; return false;
switch (Rule) switch (Rule)

View File

@ -5,4 +5,6 @@ public class TextMatchCreated : IEvent
public Guid Id => Guid.NewGuid(); public Guid Id => Guid.NewGuid();
public long ChatId { get; set; } public long ChatId { get; set; }
public string ChatUsername { get; set; } = null!;
} }

View File

@ -21,7 +21,7 @@ public class TextMatchController : ControllerBase
[HttpPost] [HttpPost]
public Task<long> Create([FromBody] CreateTextMatchRequest request, CancellationToken cancellationToken = default) public Task<long> Create([FromBody] CreateTextMatchRequest request, CancellationToken cancellationToken = default)
{ {
return _textMatchService.Create(request.UserId, request.ChatId, request.Template, request.Rule, return _textMatchService.Create(request.UserId, request.ChatId, request.ChatUsername, request.Template, request.Rule,
cancellationToken); cancellationToken);
} }
} }

View File

@ -15,52 +15,54 @@ public class TextMatchTests
public void IsMatches_SameChatId_FullRule_MatchesText() public void IsMatches_SameChatId_FullRule_MatchesText()
{ {
// Arrange // Arrange
var match = TextMatch.Initialize(UserId, ChatId, "велосипед", TextMatchRule.Full, CreatedDateTime); var match = TextMatch.Initialize(UserId, ChatId, "Барахолка", "велосипед", TextMatchRule.Full, CreatedDateTime);
var text = "Продам снежный велосипед 100 лари. Гудаури."; var text = "Продам снежный велосипед 100 лари. Гудаури.";
// Act // Act
var result = match.IsMatches(ChatId, text); var result = match.IsMatches(ChatId, "Барахолка", text);
// Assert // Assert
Assert.True(result); Assert.True(result);
} }
[Fact] [Fact]
public void IsMatches_SameChatId_AnyWord_MatchesText() public void IsMatches_SameChatId_AnyWord_MatchesText()
{ {
// Arrange // Arrange
var match = TextMatch.Initialize(UserId, ChatId, "iphone айфон", TextMatchRule.AnyWord, CreatedDateTime); var match = TextMatch.Initialize(UserId, ChatId, "Барахолка", "iphone айфон", TextMatchRule.AnyWord,
CreatedDateTime);
var text = "Продам айфон велосипед 100 лари. Гудаури."; var text = "Продам айфон велосипед 100 лари. Гудаури.";
// Act // Act
var result = match.IsMatches(ChatId, text); var result = match.IsMatches(ChatId, "Барахолка", text);
// Assert // Assert
Assert.True(result); Assert.True(result);
} }
[Fact] [Fact]
public void IsMatches_SameChatId_AllWords_MatchesText() public void IsMatches_SameChatId_AllWords_MatchesText()
{ {
// Arrange // Arrange
var match = TextMatch.Initialize(UserId, ChatId, "iphone айфон", TextMatchRule.AnyWord, CreatedDateTime); var match = TextMatch.Initialize(UserId, ChatId, "Барахолка", "iphone айфон", TextMatchRule.AnyWord,
CreatedDateTime);
var text = "Гомарджоба. Продам iphone (айфон) 1000 лари. Гудаури."; var text = "Гомарджоба. Продам iphone (айфон) 1000 лари. Гудаури.";
// Act // Act
var result = match.IsMatches(ChatId, text); var result = match.IsMatches(ChatId, "Барахолка", text);
// Assert // Assert
Assert.True(result); Assert.True(result);
} }
[Fact] [Fact]
public void IsMatches_DifferentChatId_NotMatchesText() public void IsMatches_DifferentChatIdAndUserName_NotMatchesText()
{ {
// Arrange // Arrange
var match = TextMatch.Initialize(UserId, ChatId, "iphone", TextMatchRule.Full, CreatedDateTime); var match = TextMatch.Initialize(UserId, ChatId, "Барахолка", "iphone", TextMatchRule.Full, CreatedDateTime);
// Act // Act
var result = match.IsMatches(ChatId, string.Empty); var result = match.IsMatches(0, string.Empty, "iphone");
// Assert // Assert
Assert.False(result); Assert.False(result);