Compare commits
2 Commits
9ce31c4dd8
...
1075177511
Author | SHA1 | Date | |
---|---|---|---|
1075177511
|
|||
78f8a9e638
|
@@ -2,8 +2,8 @@ using System.ComponentModel.DataAnnotations;
|
|||||||
using DysonNetwork.Pass.Auth;
|
using DysonNetwork.Pass.Auth;
|
||||||
using DysonNetwork.Pass.Credit;
|
using DysonNetwork.Pass.Credit;
|
||||||
using DysonNetwork.Pass.Wallet;
|
using DysonNetwork.Pass.Wallet;
|
||||||
using DysonNetwork.Shared.Error;
|
|
||||||
using DysonNetwork.Shared.GeoIp;
|
using DysonNetwork.Shared.GeoIp;
|
||||||
|
using DysonNetwork.Shared.Http;
|
||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using DysonNetwork.Pass.Permission;
|
using DysonNetwork.Pass.Permission;
|
||||||
using DysonNetwork.Pass.Wallet;
|
using DysonNetwork.Pass.Wallet;
|
||||||
using DysonNetwork.Shared.Error;
|
using DysonNetwork.Shared.Http;
|
||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System.Text;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
namespace DysonNetwork.Shared.Content;
|
namespace DysonNetwork.Shared.Data;
|
||||||
|
|
||||||
public abstract partial class TextSanitizer
|
public abstract partial class TextSanitizer
|
||||||
{
|
{
|
@@ -39,10 +39,6 @@
|
|||||||
<Protobuf Include="Proto\*.proto" ProtoRoot="Proto" GrpcServices="Both" AdditionalFileExtensions="Proto\" />
|
<Protobuf Include="Proto\*.proto" ProtoRoot="Proto" GrpcServices="Both" AdditionalFileExtensions="Proto\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Error\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\DysonNetwork.ServiceDefaults\DysonNetwork.ServiceDefaults.csproj" />
|
<ProjectReference Include="..\DysonNetwork.ServiceDefaults\DysonNetwork.ServiceDefaults.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
namespace DysonNetwork.Shared.Error;
|
namespace DysonNetwork.Shared.Http;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Standardized error payload to return to clients.
|
/// Standardized error payload to return to clients.
|
@@ -2,7 +2,6 @@ using System.ComponentModel.DataAnnotations;
|
|||||||
using System.ComponentModel.DataAnnotations.Schema;
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
|
||||||
using NodaTime;
|
using NodaTime;
|
||||||
using NodaTime.Serialization.Protobuf;
|
using NodaTime.Serialization.Protobuf;
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using DysonNetwork.Shared.Auth;
|
using DysonNetwork.Shared.Auth;
|
||||||
using DysonNetwork.Shared.Content;
|
using DysonNetwork.Shared.Data;
|
||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
@@ -162,4 +162,25 @@ public class ChatRoomService(
|
|||||||
return m;
|
return m;
|
||||||
})];
|
})];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private const string ChatRoomSubscribeKeyPrefix = "chatroom:subscribe:";
|
||||||
|
|
||||||
|
public async Task SubscribeChatRoom(SnChatMember member)
|
||||||
|
{
|
||||||
|
var cacheKey = ChatRoomSubscribeKeyPrefix + member.Id;
|
||||||
|
await cache.SetAsync(cacheKey, true, TimeSpan.FromHours(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task UnsubscribeChatRoom(SnChatMember member)
|
||||||
|
{
|
||||||
|
var cacheKey = ChatRoomSubscribeKeyPrefix + member.Id;
|
||||||
|
await cache.RemoveAsync(cacheKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> IsSubscribedChatRoom(Guid memberId)
|
||||||
|
{
|
||||||
|
var cacheKey = ChatRoomSubscribeKeyPrefix + memberId;
|
||||||
|
var result = await cache.GetAsync<bool?>(cacheKey);
|
||||||
|
return result ?? false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -280,7 +280,16 @@ public partial class ChatService(
|
|||||||
|
|
||||||
var accountsToNotify = FilterAccountsForNotification(members, message, sender);
|
var accountsToNotify = FilterAccountsForNotification(members, message, sender);
|
||||||
|
|
||||||
logger.LogInformation($"Trying to deliver message to {accountsToNotify.Count} accounts...");
|
// Filter out subscribed users from push notifications
|
||||||
|
var subscribedMemberIds = new List<Guid>();
|
||||||
|
foreach (var member in members)
|
||||||
|
{
|
||||||
|
if (await scopedCrs.IsSubscribedChatRoom(member.Id))
|
||||||
|
subscribedMemberIds.Add(member.AccountId);
|
||||||
|
}
|
||||||
|
accountsToNotify = accountsToNotify.Where(a => !subscribedMemberIds.Contains(Guid.Parse(a.Id))).ToList();
|
||||||
|
|
||||||
|
logger.LogInformation("Trying to deliver message to {count} accounts...", accountsToNotify.Count);
|
||||||
|
|
||||||
if (accountsToNotify.Count > 0)
|
if (accountsToNotify.Count > 0)
|
||||||
{
|
{
|
||||||
@@ -289,7 +298,7 @@ public partial class ChatService(
|
|||||||
await scopedNty.SendPushNotificationToUsersAsync(ntyRequest);
|
await scopedNty.SendPushNotificationToUsersAsync(ntyRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.LogInformation($"Delivered message to {accountsToNotify.Count} accounts.");
|
logger.LogInformation("Delivered message to {count} accounts.", accountsToNotify.Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private PushNotification BuildNotification(SnChatMessage message, SnChatMember sender, SnChatRoom room, string roomSubject,
|
private PushNotification BuildNotification(SnChatMessage message, SnChatMember sender, SnChatRoom room, string roomSubject,
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
using System.ComponentModel.DataAnnotations;
|
using System.ComponentModel.DataAnnotations;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using DysonNetwork.Shared.Auth;
|
using DysonNetwork.Shared.Auth;
|
||||||
using DysonNetwork.Shared.Content;
|
using DysonNetwork.Shared.Data;
|
||||||
using DysonNetwork.Shared.Models;
|
using DysonNetwork.Shared.Models;
|
||||||
using DysonNetwork.Shared.Proto;
|
using DysonNetwork.Shared.Proto;
|
||||||
using DysonNetwork.Sphere.Poll;
|
using DysonNetwork.Sphere.Poll;
|
||||||
|
@@ -192,6 +192,12 @@ public class BroadcastEventHandler(
|
|||||||
case "messages.typing":
|
case "messages.typing":
|
||||||
await HandleMessageTyping(evt, packet);
|
await HandleMessageTyping(evt, packet);
|
||||||
break;
|
break;
|
||||||
|
case "messages.subscribe":
|
||||||
|
await HandleMessageSubscribe(evt, packet);
|
||||||
|
break;
|
||||||
|
case "messages.unsubscribe":
|
||||||
|
await HandleMessageUnsubscribe(evt, packet);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -278,6 +284,62 @@ public class BroadcastEventHandler(
|
|||||||
await pusher.PushWebSocketPacketToUsersAsync(respRequest);
|
await pusher.PushWebSocketPacketToUsersAsync(respRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task HandleMessageSubscribe(WebSocketPacketEvent evt, WebSocketPacket packet)
|
||||||
|
{
|
||||||
|
using var scope = serviceProvider.CreateScope();
|
||||||
|
var crs = scope.ServiceProvider.GetRequiredService<ChatRoomService>();
|
||||||
|
|
||||||
|
if (packet.Data == null)
|
||||||
|
{
|
||||||
|
await SendErrorResponse(evt, "messages.subscribe requires you to provide the ChatRoomId");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var requestData = packet.GetData<ChatController.ChatRoomWsUniversalRequest>();
|
||||||
|
if (requestData == null)
|
||||||
|
{
|
||||||
|
await SendErrorResponse(evt, "Invalid request data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sender = await crs.GetRoomMember(evt.AccountId, requestData.ChatRoomId);
|
||||||
|
if (sender == null)
|
||||||
|
{
|
||||||
|
await SendErrorResponse(evt, "User is not a member of the chat room.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await crs.SubscribeChatRoom(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task HandleMessageUnsubscribe(WebSocketPacketEvent evt, WebSocketPacket packet)
|
||||||
|
{
|
||||||
|
using var scope = serviceProvider.CreateScope();
|
||||||
|
var crs = scope.ServiceProvider.GetRequiredService<ChatRoomService>();
|
||||||
|
|
||||||
|
if (packet.Data == null)
|
||||||
|
{
|
||||||
|
await SendErrorResponse(evt, "messages.unsubscribe requires you to provide the ChatRoomId");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var requestData = packet.GetData<ChatController.ChatRoomWsUniversalRequest>();
|
||||||
|
if (requestData == null)
|
||||||
|
{
|
||||||
|
await SendErrorResponse(evt, "Invalid request data");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sender = await crs.GetRoomMember(evt.AccountId, requestData.ChatRoomId);
|
||||||
|
if (sender == null)
|
||||||
|
{
|
||||||
|
await SendErrorResponse(evt, "User is not a member of the chat room.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await crs.UnsubscribeChatRoom(sender);
|
||||||
|
}
|
||||||
|
|
||||||
private async Task SendErrorResponse(WebSocketPacketEvent evt, string message)
|
private async Task SendErrorResponse(WebSocketPacketEvent evt, string message)
|
||||||
{
|
{
|
||||||
await pusher.PushWebSocketPacketToDeviceAsync(new PushWebSocketPacketToDeviceRequest
|
await pusher.PushWebSocketPacketToDeviceAsync(new PushWebSocketPacketToDeviceRequest
|
||||||
|
Reference in New Issue
Block a user