using System; using System.Linq; using System.Threading.Tasks; using System.Net.Http; using System.Collections.Generic; using WebSocketSharp; using Newtonsoft.Json; namespace Chatr { public class ReceivedEventArgs : EventArgs { public ReceivedEventArgs(T data) { Data=data; } public T Data {get;set;} } internal class WSClient : IDisposable { public class ChatrWSMsgReceivedEventArgs : EventArgs { public ChatrWSMsgReceivedEventArgs(ChatrWSMsg msg){ Message=msg; } public ChatrWSMsg Message {get;set;} } public event EventHandler OnMessage; public event EventHandler OnError; public event EventHandler OnOpen; public event EventHandler OnClose; WebSocket sock; public WSClient(string url,params string[] protocols) { sock=new WebSocket(url,protocols); sock.OnMessage += (sender,e)=>{ if(e.IsText) { OnMessage?.Invoke(this,new ChatrWSMsgReceivedEventArgs(JsonConvert.DeserializeObject(e.Data))); } }; sock.OnError += (sender,e)=>{ OnError?.Invoke(this,e); }; sock.OnOpen+= (sender,e)=>{ OnOpen?.Invoke(this,e); }; sock.OnClose += (sender,e)=>{ OnClose?.Invoke(this,e); }; } public void Connect() { sock.Connect(); } public void Send(ChatrWSMsg msg) { sock.Send(JsonConvert.SerializeObject(msg)); } public void Dispose() { sock.Close(); } } public class ChatrClient { public ChatrClient() { client=new HttpClient(); } HttpClient client; public async Task GetSessionAsync(string url,string username,string password) { HttpRequestMessage msg=new HttpRequestMessage(HttpMethod.Post,$"{url.TrimEnd('/')}/api/login2"); Dictionary ls=new Dictionary(); ls.Add("username",username); ls.Add("password",password); var content=new FormUrlEncodedContent(ls); msg.Content=content; using(var resp=await client.SendAsync(msg)){ if(resp.IsSuccessStatusCode) { var val= await resp.Content.ReadAsStringAsync(); return val; } } return ""; } public ChatrInstance AuthenticateUser(string endpoint,string sessionId) { return new ChatrInstance(client,endpoint,false,sessionId); } public ChatrInstance AuthenticateBot(string endpoint,string apiKey) { return new ChatrInstance(client,endpoint,true,apiKey); } } public class ChatrInstance { public event EventHandler> OnMessage; public event EventHandler> OnNotification; public event EventHandler> OnNotificationEventFire; HttpClient clt; string endpoint; bool isBot; string auth; WSClient wsClt; public async Task GetStateAsync() { if(isBot) return new State(); HttpRequestMessage msg=new HttpRequestMessage(HttpMethod.Get,$"{endpoint.TrimEnd('/')}/api/state.json"); msg.Headers.Add("Cookie",$"Chatr-Session={auth}"); using(var resp=await clt.SendAsync(msg)){ if(resp.IsSuccessStatusCode) { var val= await resp.Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject(val); } } return new State(); } internal ChatrInstance(HttpClient clt,string endpoint,bool isBot,string auth) { this.clt=clt; this.endpoint = endpoint.TrimEnd('/'); this.isBot=isBot; this.auth = auth; } public async Task StartCommunication() { /* // if(e.WS_SAME_AS_HTTP) { var scheme= window.location.protocol == "http" ? "ws" : "wss"; wsStr=`${scheme}://${window.location.host}${window.location.pathname}chatr-ws`; }else{ var scheme = e.WSS ? 'wss' : 'ws'; wsStr=`${scheme}://${window.location.hostname}:${e.WSPort}${window.location.pathname}chatr-ws`; } */ // string data=await clt.GetStringAsync($"{endpoint}/api/appconfig.json"); var res=JsonConvert.DeserializeObject(data); string wsURL=""; var uri=new Uri(endpoint + "/"); if(res.WS_SAME_AS_HTTP) { var scheme = uri.Scheme == "http" ? "ws" : "wss"; wsURL = $"{scheme}://{uri.Host}:{uri.Port}{uri.PathAndQuery.TrimEnd('/')}/chatr-ws"; }else{ var scheme = res.WSS ? "wss" : "ws"; wsURL = $"{scheme}://{uri.Host}:{res.WSPort}{uri.PathAndQuery.TrimEnd('/')}/chatr-ws"; } wsClt=new WSClient(wsURL); var authPkt=new ChatrWSMsg(); if(isBot) { AuthenticateBotPacket botPacket=new AuthenticateBotPacket(); botPacket.ApiKey = auth; authPkt.SetPacketData(botPacket); }else{ AuthenticationUserPacket userPkt=new AuthenticationUserPacket(); userPkt.SessionId = auth; authPkt.SetPacketData(userPkt); } wsClt.OnMessage += (sender,e)=>{ IPacketData packetData; if(e.Message.IsType(PacketType.Message,out packetData)) { var message=(MessagePacket)packetData; OnMessage?.Invoke(this,new ReceivedEventArgs(message)); } if(e.Message.IsType(PacketType.Notification,out packetData)) { var notification =(NotificationPacket)packetData; OnNotification?.Invoke(this,new ReceivedEventArgs(notification)); } if(e.Message.IsType(PacketType.NotificationEventFire,out packetData)) { var noFire = (NotificationEventFirePacket)packetData; OnNotificationEventFire?.Invoke(this,new ReceivedEventArgs(noFire)); } }; wsClt.Connect(); wsClt.Send(authPkt); } public void SendMessage(string userName,string messageData) { MessagePacket pkt=new MessagePacket(); pkt.Content = messageData; pkt.UserStr=userName; wsClt.Send(new ChatrWSMsg(pkt)); } public void SendNotification(string userName,string botNotId,string title,string body,NotificationEvent clicked,params NotificationButton[] links) { NotificationPacket pkt=new NotificationPacket(); pkt.UserName=userName; pkt.BotNotificationId = botNotId; pkt.Title = title; pkt.Body= body; pkt.OnClick = clicked; pkt.NotificationButtons=links.ToList(); wsClt.Send(new ChatrWSMsg(pkt)); } public void Click(NotificationPacket pkt,string eventFired="") { NotificationEventFirePacket efp=new NotificationEventFirePacket(); efp.BotUserString=pkt.BotUserString; efp.BotNotificationId=pkt.BotNotificationId; efp.SourceUserName = pkt.BotOwnerUserName; efp.Button=eventFired; wsClt.Send(new ChatrWSMsg(efp)); } } }