using MessengerApi.Model; using MessengerApi.Model.Messages; using portaloggy; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; namespace MessengerApi { /// /// Exists for mocking reason. This is implemented by . /// public interface IClient { /// /// Receives pending messages from the messenger API. /// /// Credentials to the API. IEnumerable GetMessages(); /// /// Acknowledges message reception to the server. /// void AckMessage(InboxMessage message); /// /// Acknowledges message reception to the server. /// /// void AckMessage(Guid messageId); /// /// Sends a message. /// /// Credentials to the API. Guid SendMessage(OutboxMessage outboxMessage); /// /// Returns user ids for allowed message recipients. /// Contact[] GetYellowPages(); /// /// Returns number of pending messages, waiting for delivery. /// int Peek(); /// /// Gets delivery state of a message. /// State Verify(Guid messageId); } public class Client : IClient { protected readonly Credentials _credentials; protected readonly HttpClient _httpClient; protected readonly ILogger _logger; public Client(Credentials credentials, HttpClient httpClient = null, ILogger logger = null) { _credentials = credentials; _httpClient = httpClient ?? new HttpClient(); _logger = logger ?? new ConsoleLogger(); } public IEnumerable GetMessages() { var url = $"{_credentials.ApiUrl}/receive"; var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _credentials.ApiKey); _logger.Debug($"Sending query to {url} with content {request.ToString()} to obtain messages."); var response = _httpClient.Send(request); if (!response.IsSuccessStatusCode) { _logger.Error(response.ReasonPhrase); throw new HttpRequestException("Can't receive.", null, response.StatusCode); } var responseContent = response.Content .ReadAsStringAsync() .GetAwaiter() .GetResult(); if (!string.IsNullOrWhiteSpace(responseContent)) { _logger.Debug($"Received response of {responseContent}."); } if (string.IsNullOrWhiteSpace(responseContent)) { return Enumerable.Empty().ToArray(); } var json = JsonNode.Parse(responseContent); var messages = new List(); foreach (var item in json["messages"].AsArray()) { messages.Add(new InboxMessage { Id = item["id"].GetValue(), Payload = item["payload"].GetValue(), PayloadType = item["payloadType"].GetValue(), Sender = item["sender"].GetValue(), }); } _logger.Debug($"Received {messages.Count} messages."); return messages.ToArray(); } public Guid SendMessage(OutboxMessage outboxMessage) { var body = new JsonObject(); if(outboxMessage.ToUserId.HasValue) { body.Add("toUserId", JsonValue.Create(outboxMessage.ToUserId.Value)); } if(outboxMessage.Payload != null) { body.Add("payload", JsonValue.Create(outboxMessage.Payload)); } if(outboxMessage.PayloadType != null) { body.Add("payloadType", JsonValue.Create(outboxMessage.PayloadType)); } if(outboxMessage.LifespanInSeconds != null) { body.Add("lifespanInSeconds", JsonValue.Create(outboxMessage.LifespanInSeconds.Value)); } var content = new StringContent(body.ToString(), Encoding.UTF8, "application/json"); var url = $"{_credentials.ApiUrl}/send"; var request = new HttpRequestMessage(HttpMethod.Post, url); request.Content = content; request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _credentials.ApiKey); _logger.Debug($"Sending query to {url} with content {body.ToString()} to obtain messages."); var response = _httpClient.Send(request); if (!response.IsSuccessStatusCode) { _logger.Error(response.ReasonPhrase); throw new HttpRequestException("Can't send.", null, response.StatusCode); } var responseString = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); var guid = JsonSerializer.Deserialize(responseString); return guid; } public Contact[] GetYellowPages() { var url = $"{_credentials.ApiUrl}/yellowpages"; var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _credentials.ApiKey); _logger.Debug($"Sending query to {url} with content {request.ToString()}."); var response = _httpClient.Send(request); if (!response.IsSuccessStatusCode) { _logger.Error(response.ReasonPhrase); throw new HttpRequestException("Can't receive.", null, response.StatusCode); } var responseContent = response.Content .ReadAsStringAsync() .GetAwaiter() .GetResult(); var json = JsonNode.Parse(responseContent); var contacts = json["users"].AsArray().Select(x => new Contact { Id = x["id"].GetValue(), Name = x["name"].GetValue() }).ToArray(); return contacts; } public void AckMessage(InboxMessage message) { this.AckMessage(message.Id); } public void AckMessage(Guid messageId) { var body = new JsonObject { { "messageId", JsonValue.Create(messageId) } }; var content = new StringContent(body.ToString(), Encoding.UTF8, "application/json"); var url = $"{_credentials.ApiUrl}/ack"; var request = new HttpRequestMessage(HttpMethod.Post, url); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _credentials.ApiKey); _logger.Debug($"Sending query to {url} with content {body.ToString()} to obtain messages."); var response = _httpClient.Send(request); if (!response.IsSuccessStatusCode) { _logger.Error(response.ReasonPhrase); throw new HttpRequestException("Can't send.", null, response.StatusCode); } } public int Peek() { var url = $"{_credentials.ApiUrl}/peek"; var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _credentials.ApiKey); _logger.Debug($"Sending query to {url} with content {request.ToString()} to obtain messages."); var response = _httpClient.Send(request); if (!response.IsSuccessStatusCode) { _logger.Error(response.ReasonPhrase); throw new HttpRequestException("Can't receive.", null, response.StatusCode); } var responseContent = response.Content .ReadAsStringAsync() .GetAwaiter() .GetResult(); if (!string.IsNullOrWhiteSpace(responseContent)) { _logger.Debug($"Received response of {responseContent}."); return int.Parse(responseContent); } throw new InvalidOperationException("Unreadable response."); } public State Verify(Guid messageId) { var url = $"{_credentials.ApiUrl}/verify?messageId={messageId}"; var request = new HttpRequestMessage(HttpMethod.Get, url); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", _credentials.ApiKey); _logger.Debug($"Sending query to {url} to get message state."); var response = _httpClient.Send(request); if (!response.IsSuccessStatusCode) { _logger.Error(response.ReasonPhrase); throw new HttpRequestException("Can't receive.", null, response.StatusCode); } var responseContent = response.Content .ReadAsStringAsync() .GetAwaiter() .GetResult(); if (!string.IsNullOrWhiteSpace(responseContent)) { return JsonSerializer.Deserialize(responseContent); } throw new InvalidOperationException("Unreadable response."); } } }