XmppBotDemo/XmppBotDemo/Program.cs

134 lines
4.0 KiB
C#

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using S22.Xmpp;
using S22.Xmpp.Client;
using S22.Xmpp.Im;
namespace XmppBotDemo
{
public static class MainClass
{
private static XmppClient client;
private static Jid ourJid = null;
private static string password = null;
public static int Main(string[] args)
{
// Read in the environment variables
ourJid = new Jid(Environment.GetEnvironmentVariable("XMPP_JID"));
password = Environment.GetEnvironmentVariable("XMPP_PASSWORD");
// Ensure they are present
if (ourJid == null || password == null) {
Console.Error.WriteLine("XMPP Bot Demo");
Console.Error.WriteLine("=============");
Console.Error.WriteLine("");
Console.Error.WriteLine("Usage:");
Console.Error.WriteLine(" ./XmppBotDemo.exe");
Console.Error.WriteLine("");
Console.Error.WriteLine("Environment Variables:");
Console.Error.WriteLine(" XMPP_JID Required. Specifies the JID to login with.");
Console.Error.WriteLine(" XMPP_PASSWORD Required. Specifies the password to login with.");
return 1;
}
// Create the client instance
client = new XmppClient(ourJid.Domain, ourJid.Node, password);
client.Error += errorHandler;
client.SubscriptionRequest += subscriptionRequestHandler;
client.Message += messageHandler;
client.Connect();
// Wait for a connection
while (!client.Connected)
Thread.Sleep(100);
Console.WriteLine($"[Main] Connected as {ourJid}.");
// Wait forever.
Thread.Sleep(Timeout.Infinite);
// TODO: Automatically reconnect to the server when we get disconnected.
return 0;
}
#region Event Handlers
/// <summary>
/// Handles requests to talk to us.
/// </summary>
/// <remarks>
/// Only allow people to talk to us if they are on the same domain we are.
/// You probably don't want this for production, but for developmental purposes
/// it offers some measure of protection.
/// </remarks>
/// <param name="from">The JID of the remote user who wants to talk to us.</param>
/// <returns>Whether we're going to allow the requester to talk to us or not.</returns>
public static bool subscriptionRequestHandler(Jid from) {
Console.WriteLine($"[Handler/SubscriptionRequest] {from} is requesting access, I'm saying {(from.Domain == ourJid.Domain?"yes":"no")}");
return from.Domain == ourJid.Domain;
}
/// <summary>
/// Handles incoming messages.
/// </summary>
private static void messageHandler(object sender, MessageEventArgs eventArgs) {
Console.WriteLine($"[Handler/Message] {eventArgs.Message.Body.Length} chars from {eventArgs.Jid}");
char[] messageCharArray = eventArgs.Message.Body.ToCharArray();
Array.Reverse(messageCharArray);
sendChatReply(
eventArgs.Message,
new string(messageCharArray)
);
}
/// <summary>
/// Handles any errors thrown by the XMPP client engine.
/// </summary>
private static void errorHandler(object sender, ErrorEventArgs eventArgs) {
Console.Error.WriteLine($"Error: {eventArgs.Reason}");
Console.Error.WriteLine(eventArgs.Exception);
}
#endregion
#region Message Senders
/// <summary>
/// Sends a chat message to the specified JID.
/// </summary>
/// <param name="to">The JID to send the message to.</param>
/// <param name="message">The messaage to send.</param>
private static void sendChatMessage(Jid to, string message)
{
//Console.WriteLine($"[Rhino/Send/Chat] Sending {message} -> {to}");
client.SendMessage(
to, message,
null, null, MessageType.Chat
);
}
/// <summary>
/// Sends a chat message in direct reply to a given incoming message.
/// </summary>
/// <param name="originalMessage">Original message.</param>
/// <param name="reply">Reply.</param>
private static void sendChatReply(Message originalMessage, string reply)
{
//Console.WriteLine($"[Rhino/Send/Reply] Sending {reply} -> {originalMessage.From}");
client.SendMessage(
originalMessage.From, reply,
null, originalMessage.Thread, MessageType.Chat
);
}
#endregion
}
}