using SocketIOClient; using System.Text.Json; namespace PagerParser.PagerProviders; // Interface class for fetching pager messages from PagerMon // sites such as Jobyyy over HTTP. [PagerProvider] public class PagerMon : IPagerProvider { private record PagerMonMessage { public long Timestamp { get; set; } public string Message { get; set; } public PagerMessage PagerMessage => new PagerMessage() { Timestamp = DateTimeOffset.FromUnixTimeSeconds(Timestamp).UtcDateTime, Message = Message }; } private record PagerMonQueryResponse { public PagerMonMessage[] Messages { get; set; } } public event EventHandler OnConnect; public event EventHandler OnDisconnect; public event PagerMessageHandler OnPagerMessage; private const string QueryBaseUrl = "https://jobyyy.net/api/messages"; private HttpClient httpClient = new(); private SocketIO socketIOClient; public PagerMon() { socketIOClient = new SocketIO("https://jobyyy.net/", new SocketIOOptions() { AutoUpgrade = false, ConnectionTimeout = TimeSpan.FromMinutes(15), EIO = EngineIO.V3, Transport = SocketIOClient.Transport.TransportProtocol.WebSocket }); socketIOClient.OnConnected += (sender, e) => OnConnect?.Invoke(this, e); socketIOClient.OnDisconnected += (sender, e) => OnDisconnect?.Invoke(this, e); socketIOClient.On("messagePost", PagerMessageReceived); } public void Connect() => socketIOClient.ConnectAsync().GetAwaiter().GetResult(); public void Disconnect() => socketIOClient.DisconnectAsync().GetAwaiter().GetResult(); public PagerMessage[] Fetch() { List messages = new(); var result = httpClient .GetFromJsonAsync($"{QueryBaseUrl}?limit=120") .GetAwaiter() .GetResult(); if(result is null) return Array.Empty(); return result.Messages .Select(m => m.PagerMessage) .ToArray(); } public async Task FetchAsync(CancellationToken ct, DateTime until) { List pagerMessages = new(); int page = 1; while(!ct.IsCancellationRequested) { PagerMonQueryResponse? result; try { result = await httpClient .GetFromJsonAsync($"{QueryBaseUrl}?limit=120&page={page}"); } catch { break; } if(result is null || result.Messages.Count() == 0) break; var messages = result.Messages .Select(m => m.PagerMessage) .OrderBy(m => m.Timestamp) .ToArray(); pagerMessages.AddRange(messages); if(messages[0].Timestamp <= until) break; page++; } return pagerMessages.ToArray(); } private void PagerMessageReceived(SocketIOResponse resp) { var message = JsonSerializer.Deserialize( resp.GetValue(), new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); if(message is null) return; OnPagerMessage?.Invoke(this, new() { Message = message.PagerMessage }); } }