Commit 8e623c8b authored by Robert Rudman's avatar Robert Rudman

Fix issue with re-using http client. Added extra details about the room when events are emitted.

parent 07ac9e75
using System;
using System.IO;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Reactive.Linq;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using StackExchangeApi;
......@@ -29,9 +31,9 @@ namespace StackExchangeChat.Console
serviceCollection.AddScoped<SiteAuthenticator>();
serviceCollection.AddScoped<ChatClient>();
serviceCollection.AddTransient<HttpClient>();
serviceCollection.AddTransient(_ => new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }));
serviceCollection.AddTransient<HttpClientWithHandler>();
serviceCollection.AddTransient(_ => new HttpClientWithHandler(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }));
serviceCollection.AddSingleton(_ => config);
serviceCollection.AddSingleton<IChatCredentials>(_ => credentials);
......@@ -43,22 +45,34 @@ namespace StackExchangeChat.Console
//apiThing.TotalQuestionsByTag("stackoverflow", "design").GetAwaiter().GetResult();
//apiThing.TotalQuestionsByTag("stackoverflow", "design").GetAwaiter().GetResult();
var result = apiThing.QuestionsByTag("meta.stackoverflow", "burninate-request").GetAwaiter().GetResult();
//var result = apiThing.QuestionsByTag("meta.stackoverflow", "burninate-request").GetAwaiter().GetResult();
ApiClient.QuotaRemaining.Subscribe(System.Console.WriteLine);
//ApiClient.QuotaRemaining.Subscribe(System.Console.WriteLine);
//// var result = apiThing.TotalQuestionsByTag("design").GetAwaiter().GetResult();
// var result = apiThing.TotalQuestionsByTag("design").GetAwaiter().GetResult();
var chatClient = serviceProvider.GetService<ChatClient>();
//chatClient.SubscribeToEvents(Site.StackOverflow, 167908)
// .Where(c => c.EventType == EventType.MessagePosted || c.EventType == EventType.MessageEdited)
// .Subscribe(async chatEvent =>
// {
// await chatClient.SendMessage(Site.StackOverflow, 167908, $":{chatEvent.MessageId} Replying to message..");
// }, exception =>
// {
// System.Console.WriteLine(exception);
// });
chatClient.SubscribeToEvents(ChatSite.StackExchange, 86421).Subscribe(System.Console.WriteLine);
chatClient.SubscribeToEvents(ChatSite.StackExchange, 86421)
.Where(c =>
c.EventDetails.EventType == EventType.MessagePosted
|| c.EventDetails.EventType == EventType.MessageEdited
|| c.EventDetails.EventType == EventType.UserMentioned
)
.Subscribe(async chatEvent =>
{
try
{
if (chatEvent.EventDetails.UserId != chatEvent.RoomDetails.MyUserId)
{
await chatClient.SendMessage(chatEvent.RoomDetails.ChatSite, chatEvent.RoomDetails.RoomId,
$":{chatEvent.EventDetails.MessageId} Replying to message..");
}
} catch (Exception ex) { }
}, exception =>
{
System.Console.WriteLine(exception);
});
System.Console.ReadKey();
}
......
......@@ -6,7 +6,6 @@ using System.Reactive.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StackExchangeChat.Sites;
using StackExchangeChat.Utilities;
using WebSocketSharp;
......@@ -23,11 +22,11 @@ namespace StackExchangeChat
_httpClient = httpClient;
}
public async Task SendMessage(Site site, int roomId, string message)
public async Task SendMessage(ChatSite chatSite, int roomId, string message)
{
var fkey = await _siteAuthenticator.GetFKeyForRoom(site, roomId);
await _siteAuthenticator.AuthenticateClient(_httpClient, site);
await _httpClient.PostAsync($"https://{site.ChatDomain}/chats/{roomId}/messages/new",
var fkey = (await _siteAuthenticator.GetRoomDetails(chatSite, roomId)).FKey;
await _siteAuthenticator.AuthenticateClient(_httpClient, chatSite);
await _httpClient.PostAsync($"https://{chatSite.ChatDomain}/chats/{roomId}/messages/new",
new FormUrlEncodedContent(
new Dictionary<string, string>
{
......@@ -36,35 +35,35 @@ namespace StackExchangeChat
}));
}
public IObservable<ChatEvent> SubscribeToEvents(Site site, int roomId)
public IObservable<ChatEvent> SubscribeToEvents(ChatSite chatSite, int roomId)
{
return Observable.Create<ChatEvent>(async observer =>
{
var roomFKey = await _siteAuthenticator.GetFKeyForRoom(site, roomId);
await _siteAuthenticator.AuthenticateClient(_httpClient, site);
var wsAuthRequest = await _httpClient.PostAsync($"https://{site.ChatDomain}/ws-auth",
var roomDetails = await _siteAuthenticator.GetRoomDetails(chatSite, roomId);
await _siteAuthenticator.AuthenticateClient(_httpClient, chatSite);
var wsAuthRequest = await _httpClient.PostAsync($"https://{chatSite.ChatDomain}/ws-auth",
new FormUrlEncodedContent(
new Dictionary<string, string>
{
{"fkey", roomFKey},
{"fkey", roomDetails.FKey},
{"roomid", roomId.ToString()}
}));
var wsAuthUrl = JsonConvert.DeserializeObject<JObject>(await wsAuthRequest.Content.ReadAsStringAsync())["url"].Value<string>();
var eventsRequest = await _httpClient.PostAsync($"https://{site.ChatDomain}/chats/{roomId}/events",
var eventsRequest = await _httpClient.PostAsync($"https://{chatSite.ChatDomain}/chats/{roomId}/events",
new FormUrlEncodedContent(
new Dictionary<string, string>
{
{"mode", "events"},
{"msgCount", "0"},
{"fkey", roomFKey}
{"fkey", roomDetails.FKey}
}));
var lastEventTime = JsonConvert.DeserializeObject<JObject>(await eventsRequest.Content.ReadAsStringAsync())["time"].Value<string>();
var webSocket = new WebSocket($"{wsAuthUrl}?l={lastEventTime}") {Origin = $"https://{site.ChatDomain}"};
var webSocket = new WebSocket($"{wsAuthUrl}?l={lastEventTime}") {Origin = $"https://{chatSite.ChatDomain}"};
webSocket.OnMessage += (sender, args) =>
{
var dataObject = JsonConvert.DeserializeObject<JObject>(args.Data);
......@@ -72,9 +71,16 @@ namespace StackExchangeChat
if (eventsObject == null)
return;
var events = eventsObject.ToObject<List<ChatEvent>>();
var events = eventsObject.ToObject<List<EventDetails>>();
foreach (var @event in events)
observer.OnNext(@event);
{
var chatEvent = new ChatEvent
{
RoomDetails = roomDetails,
EventDetails = @event
};
observer.OnNext(chatEvent);
}
};
webSocket.Connect();
......
......@@ -4,29 +4,12 @@ namespace StackExchangeChat
{
public class ChatEvent
{
[JsonProperty(PropertyName = "event_type")]
public EventType EventType { get; set; }
public EventDetails EventDetails { get; set; }
public RoomDetails RoomDetails { get; set; }
[JsonProperty(PropertyName = "time_stamp")]
public int TimeStamp { get; set; }
public string Content { get; set; }
public int Id { get; set; }
[JsonProperty(PropertyName = "user_id")]
public int UserId { get; set; }
[JsonProperty(PropertyName = "user_name")]
public string UserName { get; set; }
[JsonProperty(PropertyName = "room_id")]
public int RoomId { get; set; }
[JsonProperty(PropertyName = "room_name")]
public string RoomName { get; set; }
[JsonProperty(PropertyName = "message_id")]
public int? MessageId { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this, Formatting.Indented);
}
}
}
namespace StackExchangeChat.Sites
namespace StackExchangeChat
{
public class Site
public struct ChatSite
{
public string ChatDomain { get; }
public string LoginDomain { get; }
private Site(string chatDomain, string loginDomain)
private ChatSite(string chatDomain, string loginDomain)
{
ChatDomain = chatDomain;
LoginDomain = loginDomain;
}
public static Site StackOverflow = new Site("chat.stackoverflow.com", "stackoverflow.com");
public static Site StackExchange = new Site("chat.stackexchange.com", "gaming.stackexchange.com");
public static Site MetaStackExchange = new Site("chat.meta.stackexchange.com", "meta.stackexchange.com");
public static ChatSite StackOverflow = new ChatSite("chat.stackoverflow.com", "stackoverflow.com");
public static ChatSite StackExchange = new ChatSite("chat.stackexchange.com", "meta.stackexchange.com");
public static ChatSite MetaStackExchange = new ChatSite("chat.meta.stackexchange.com", "meta.stackexchange.com");
}
}
using Newtonsoft.Json;
namespace StackExchangeChat
{
public class EventDetails
{
[JsonProperty(PropertyName = "event_type")]
public EventType EventType { get; set; }
[JsonProperty(PropertyName = "time_stamp")]
public int TimeStamp { get; set; }
public string Content { get; set; }
public int Id { get; set; }
[JsonProperty(PropertyName = "user_id")]
public int UserId { get; set; }
[JsonProperty(PropertyName = "user_name")]
public string UserName { get; set; }
[JsonProperty(PropertyName = "room_id")]
public int RoomId { get; set; }
[JsonProperty(PropertyName = "room_name")]
public string RoomName { get; set; }
[JsonProperty(PropertyName = "message_id")]
public int? MessageId { get; set; }
}
}
namespace StackExchangeChat
{
public class RoomDetails
{
public ChatSite ChatSite { get; set; }
public int RoomId { get; set; }
public int MyUserId { get; set; }
public string MyUserName { get; set; }
public string FKey { get; set; }
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment