247 lines
8.5 KiB
C#
247 lines
8.5 KiB
C#
|
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<T> : 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<ChatrWSMsgReceivedEventArgs> OnMessage;
|
|||
|
public event EventHandler<ErrorEventArgs> OnError;
|
|||
|
|
|||
|
public event EventHandler<EventArgs> OnOpen;
|
|||
|
|
|||
|
public event EventHandler<CloseEventArgs> 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<ChatrWSMsg>(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<string> GetSessionAsync(string url,string username,string password)
|
|||
|
{
|
|||
|
HttpRequestMessage msg=new HttpRequestMessage(HttpMethod.Post,$"{url.TrimEnd('/')}/api/login2");
|
|||
|
Dictionary<string,string> ls=new Dictionary<string, string>();
|
|||
|
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<ReceivedEventArgs<MessagePacket>> OnMessage;
|
|||
|
|
|||
|
public event EventHandler<ReceivedEventArgs<NotificationPacket>> OnNotification;
|
|||
|
|
|||
|
public event EventHandler<ReceivedEventArgs<NotificationEventFirePacket>> OnNotificationEventFire;
|
|||
|
HttpClient clt;
|
|||
|
string endpoint;
|
|||
|
bool isBot;
|
|||
|
string auth;
|
|||
|
|
|||
|
WSClient wsClt;
|
|||
|
public async Task<State> 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<State>(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<appcfg>(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<MessagePacket>(message));
|
|||
|
}
|
|||
|
if(e.Message.IsType(PacketType.Notification,out packetData))
|
|||
|
{
|
|||
|
var notification =(NotificationPacket)packetData;
|
|||
|
OnNotification?.Invoke(this,new ReceivedEventArgs<NotificationPacket>(notification));
|
|||
|
}
|
|||
|
if(e.Message.IsType(PacketType.NotificationEventFire,out packetData))
|
|||
|
{
|
|||
|
var noFire = (NotificationEventFirePacket)packetData;
|
|||
|
OnNotificationEventFire?.Invoke(this,new ReceivedEventArgs<NotificationEventFirePacket>(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));
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
}
|