smtp support
This commit is contained in:
parent
07bd928747
commit
3792241774
7 changed files with 387 additions and 3 deletions
18
Dockerfile
18
Dockerfile
|
|
@ -135,8 +135,22 @@ ENV basic_Username='' \
|
||||||
chatgpt_RedisCountIm='60' \
|
chatgpt_RedisCountIm='60' \
|
||||||
onevent_Enabled='false' \
|
onevent_Enabled='false' \
|
||||||
onevent_Count=0 \
|
onevent_Count=0 \
|
||||||
onevent_HideStatusOutput='false'
|
onevent_HideStatusOutput='false' \
|
||||||
|
smtp_Enabled='false' \
|
||||||
|
smtp_AllowEmailAsReplyTarget='false' \
|
||||||
|
smtp_AllowCommandSendMail='false' \
|
||||||
|
smtp_UseAllowedRecivers='false' \
|
||||||
|
smtp_AllowedReciversCSV='none' \
|
||||||
|
smtp_AllowSendAlertStatus='false' \
|
||||||
|
smtp_AllowSendLoginNotice='false' \
|
||||||
|
smtp_MailReplyAddress='me@myemail.tld' \
|
||||||
|
smtp_Port='587' \
|
||||||
|
smtp_Host='smtp.mail.example' \
|
||||||
|
smtp_useSSL='false' \
|
||||||
|
smtp_User='me@email.addr.tld' \
|
||||||
|
smtp_Token='none' \
|
||||||
|
smtp_SendAlertsAndLoginsTo='me@somewhere.tld' \
|
||||||
|
smtp_HideStatusOutput='false'
|
||||||
|
|
||||||
EXPOSE 80
|
EXPOSE 80
|
||||||
ENV ASPNETCORE_URLS http://+:80
|
ENV ASPNETCORE_URLS http://+:80
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,34 @@ namespace SecondBotEvents.Commands
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[About("use the SMTP service to send a email (requires AllowCommandSendMail to be true)")]
|
||||||
|
[ReturnHints("sending")]
|
||||||
|
[ReturnHintsFailure("Send was rejected because: X")]
|
||||||
|
[ReturnHintsFailure("ARG is empty")]
|
||||||
|
[ArgHints("to", "the email addres to send to")]
|
||||||
|
[ArgHints("subject", "the subject of the email")]
|
||||||
|
[ArgHints("body", "the contents of the email")]
|
||||||
|
public object SendEmail(string to, string subject, string body)
|
||||||
|
{
|
||||||
|
if (SecondbotHelpers.isempty(to) == true) {
|
||||||
|
return Failure("to is empty");
|
||||||
|
}
|
||||||
|
else if (SecondbotHelpers.isempty(subject) == true)
|
||||||
|
{
|
||||||
|
return Failure("subject is empty", [ to ]);
|
||||||
|
}
|
||||||
|
else if (SecondbotHelpers.isempty(body) == true)
|
||||||
|
{
|
||||||
|
return Failure("body is empty", [to, subject]);
|
||||||
|
}
|
||||||
|
KeyValuePair<bool, string> reply = master.SmtpService.commandEmail(to, subject, body);
|
||||||
|
if(reply.Key == false)
|
||||||
|
{
|
||||||
|
return Failure("Send was rejected because: "+reply.Value, [ to, subject, body ]);
|
||||||
|
}
|
||||||
|
return BasicReply("sending",[to,subject,body]);
|
||||||
|
}
|
||||||
|
|
||||||
[About("Makes the bot teleport to its home region")]
|
[About("Makes the bot teleport to its home region")]
|
||||||
[ReturnHints("ok")]
|
[ReturnHints("ok")]
|
||||||
public object GoHome()
|
public object GoHome()
|
||||||
|
|
|
||||||
97
SecondBotEvents/Config/SmtpConfig.cs
Normal file
97
SecondBotEvents/Config/SmtpConfig.cs
Normal file
|
|
@ -0,0 +1,97 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace SecondBotEvents.Config
|
||||||
|
{
|
||||||
|
public class SmtpConfig : Config
|
||||||
|
{
|
||||||
|
public SmtpConfig(bool fromENV, string fromFolder = "") : base(fromENV, fromFolder) { }
|
||||||
|
protected override void MakeSettings()
|
||||||
|
{
|
||||||
|
filename = "smtp";
|
||||||
|
settings.Add("Enabled");
|
||||||
|
settings.Add("AllowEmailAsReplyTarget");
|
||||||
|
settings.Add("AllowCommandSendMail");
|
||||||
|
settings.Add("UseAllowedRecivers");
|
||||||
|
settings.Add("AllowedReciversCSV");
|
||||||
|
settings.Add("AllowSendAlertStatus");
|
||||||
|
settings.Add("AllowSendLoginNotice");
|
||||||
|
settings.Add("MailReplyAddress");
|
||||||
|
settings.Add("Port");
|
||||||
|
settings.Add("Host");
|
||||||
|
settings.Add("useSSL");
|
||||||
|
settings.Add("User");
|
||||||
|
settings.Add("Token");
|
||||||
|
settings.Add("SendAlertsAndLoginsTo");
|
||||||
|
settings.Add("HideStatusOutput");
|
||||||
|
|
||||||
|
}
|
||||||
|
public bool GetUseAllowedRecivers()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("UseAllowedRecivers", false);
|
||||||
|
}
|
||||||
|
public string[] GetAllowedRecivers()
|
||||||
|
{
|
||||||
|
return ReadSettingAsString("AllowedReciversCSV", "none").Split(',');
|
||||||
|
}
|
||||||
|
public bool GetUseSSL()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("useSSL", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetMailReplyAddress()
|
||||||
|
{
|
||||||
|
return ReadSettingAsString("MailReplyAddress", "me@myemail.tld");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetSendAlertsAndLoginsTo()
|
||||||
|
{
|
||||||
|
return ReadSettingAsString("SendAlertsAndLoginsTo", "me@somewhere.tld");
|
||||||
|
}
|
||||||
|
public int GetPort()
|
||||||
|
{
|
||||||
|
return ReadSettingAsInt("Port", 587);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetHost()
|
||||||
|
{
|
||||||
|
return ReadSettingAsString("Host", "smtp.mail.example");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetUser()
|
||||||
|
{
|
||||||
|
return ReadSettingAsString("User", "me@email.addr.tld");
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetToken()
|
||||||
|
{
|
||||||
|
return ReadSettingAsString("Token", "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetEnabled()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("Enabled", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetAllowEmailAsReplyTarget()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("AllowEmailAsReplyTarget", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetAllowCommandSendMail()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("AllowCommandSendMail", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetAllowSendAlertStatus()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("AllowSendAlertStatus", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool GetAllowSendLoginNotice()
|
||||||
|
{
|
||||||
|
return ReadSettingAsBool("AllowSendLoginNotice", false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -42,6 +42,8 @@ namespace SecondBotEvents
|
||||||
public EventsService EventsService { get { return (EventsService)GetService("EventsService"); } }
|
public EventsService EventsService { get { return (EventsService)GetService("EventsService"); } }
|
||||||
public DialogService DialogService { get { return (DialogService)GetService("DialogService"); } }
|
public DialogService DialogService { get { return (DialogService)GetService("DialogService"); } }
|
||||||
|
|
||||||
|
public SmtpService SmtpService { get { return (SmtpService)GetService("SmtpService"); } }
|
||||||
|
|
||||||
public ChatGptService ChatGptService { get { return (ChatGptService)GetService("ChatGptService"); } }
|
public ChatGptService ChatGptService { get { return (ChatGptService)GetService("ChatGptService"); } }
|
||||||
|
|
||||||
public TriggerOnEventService TriggerOnEventService { get { return (TriggerOnEventService)GetService("TriggerOnEventService"); } }
|
public TriggerOnEventService TriggerOnEventService { get { return (TriggerOnEventService)GetService("TriggerOnEventService"); } }
|
||||||
|
|
@ -174,6 +176,7 @@ namespace SecondBotEvents
|
||||||
RegisterService("RelayService");
|
RegisterService("RelayService");
|
||||||
RegisterService("ChatGptService");
|
RegisterService("ChatGptService");
|
||||||
RegisterService("RecoveryService");
|
RegisterService("RecoveryService");
|
||||||
|
RegisterService("SmtpService");
|
||||||
if (BotClient.IsLoaded() == false)
|
if (BotClient.IsLoaded() == false)
|
||||||
{
|
{
|
||||||
LogFormater.Info("Config is not loaded :(");
|
LogFormater.Info("Config is not loaded :(");
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
<PackageReference Include="Discord.Net" Version="3.17.1" />
|
<PackageReference Include="Discord.Net" Version="3.17.1" />
|
||||||
<PackageReference Include="Discord.Net.WebSocket" Version="3.17.1" />
|
<PackageReference Include="Discord.Net.WebSocket" Version="3.17.1" />
|
||||||
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
||||||
|
<PackageReference Include="MailKit" Version="4.10.0" />
|
||||||
<PackageReference Include="MSBuildGitHash" Version="2.0.2">
|
<PackageReference Include="MSBuildGitHash" Version="2.0.2">
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using OpenMetaverse.ImportExport.Collada14;
|
using OpenMetaverse.ImportExport.Collada14;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
namespace SecondBotEvents.Services
|
namespace SecondBotEvents.Services
|
||||||
{
|
{
|
||||||
|
|
@ -252,6 +253,10 @@ namespace SecondBotEvents.Services
|
||||||
mode = "IM";
|
mode = "IM";
|
||||||
UUID.TryParse(UUIDfetch, out target_avatar);
|
UUID.TryParse(UUIDfetch, out target_avatar);
|
||||||
}
|
}
|
||||||
|
else if (new EmailAddressAttribute().IsValid(target) == true)
|
||||||
|
{
|
||||||
|
mode = "EMAIL";
|
||||||
|
}
|
||||||
else if (int.TryParse(target, out target_channel) == false)
|
else if (int.TryParse(target, out target_channel) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
@ -287,6 +292,14 @@ namespace SecondBotEvents.Services
|
||||||
LogFormater.Crit("[SmartReply] HTTP failed: " + e.Message + "");
|
LogFormater.Crit("[SmartReply] HTTP failed: " + e.Message + "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(mode == "EMAIL")
|
||||||
|
{
|
||||||
|
KeyValuePair<bool,string> reply = master.SmtpService.sendReplyTarget(target,command,output);
|
||||||
|
if(reply.Key == false)
|
||||||
|
{
|
||||||
|
LogFormater.Crit("[SmartReply] EMAIL failed: " + reply.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
protected HttpClient HTTPclient = new HttpClient();
|
protected HttpClient HTTPclient = new HttpClient();
|
||||||
|
|
||||||
|
|
|
||||||
228
SecondBotEvents/Services/SmtpService.cs
Normal file
228
SecondBotEvents/Services/SmtpService.cs
Normal file
|
|
@ -0,0 +1,228 @@
|
||||||
|
using MailKit.Net.Imap;
|
||||||
|
using MailKit.Net.Smtp;
|
||||||
|
using MimeKit;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using SecondBotEvents.Config;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace SecondBotEvents.Services
|
||||||
|
{
|
||||||
|
public class SmtpService : BotServices
|
||||||
|
{
|
||||||
|
protected new SmtpConfig myConfig;
|
||||||
|
protected int sent = 0;
|
||||||
|
protected int failed = 0;
|
||||||
|
protected bool botConnected = false;
|
||||||
|
public SmtpService(EventsSecondBot setMaster) : base(setMaster)
|
||||||
|
{
|
||||||
|
myConfig = new SmtpConfig(master.fromEnv, master.fromFolder);
|
||||||
|
if (myConfig.GetEnabled() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public override string Status()
|
||||||
|
{
|
||||||
|
if (myConfig == null)
|
||||||
|
{
|
||||||
|
return "No Config";
|
||||||
|
}
|
||||||
|
else if(myConfig.GetEnabled() == false)
|
||||||
|
{
|
||||||
|
return "Disabled";
|
||||||
|
}
|
||||||
|
else if (myConfig.GetHideStatusOutput() == true)
|
||||||
|
{
|
||||||
|
return "hidden";
|
||||||
|
}
|
||||||
|
else if(botConnected == false)
|
||||||
|
{
|
||||||
|
return "Standby";
|
||||||
|
}
|
||||||
|
return "send: "+sent.ToString()+" ~ Failed: "+failed.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void BotAlertMessage(object o, AlertMessageEventArgs e)
|
||||||
|
{
|
||||||
|
if (myConfig == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (myConfig.GetEnabled() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myConfig.GetAllowSendAlertStatus() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(myConfig.GetSendAlertsAndLoginsTo() == "me@somewhere.tld")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SendMail("Bot - Alert message",e.Message, myConfig.GetSendAlertsAndLoginsTo());
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyValuePair<bool,string> commandEmail(string to,string subject, string message)
|
||||||
|
{
|
||||||
|
if(myConfig == null)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false,"No SMTP config");
|
||||||
|
}
|
||||||
|
else if(myConfig.GetEnabled() == false)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false, "SMTP service not enabled");
|
||||||
|
}
|
||||||
|
else if(myConfig.GetAllowCommandSendMail() == false)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false, "Send email via commands not enabled");
|
||||||
|
}
|
||||||
|
return SendMail(subject, message, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyValuePair<bool, string> sendReplyTarget(string to,string command,string output)
|
||||||
|
{
|
||||||
|
if (myConfig == null)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false, "No SMTP config");
|
||||||
|
}
|
||||||
|
else if (myConfig.GetEnabled() == false)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false, "SMTP service not enabled");
|
||||||
|
}
|
||||||
|
else if (myConfig.GetAllowEmailAsReplyTarget() == false)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false, "Send email via command reply is not enabled");
|
||||||
|
}
|
||||||
|
return SendMail(command+"##commandreply", output, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected KeyValuePair<bool, string> SendMail(string subject, string body, string to)
|
||||||
|
{
|
||||||
|
if(myConfig.GetMailReplyAddress() == "me@myemail.tld")
|
||||||
|
{
|
||||||
|
LogFormater.Crit("you need to set the reply address");
|
||||||
|
failed++;
|
||||||
|
return new KeyValuePair<bool, string>(false, "you need to set the reply address");
|
||||||
|
}
|
||||||
|
if(myConfig.GetUseAllowedRecivers() == true)
|
||||||
|
{
|
||||||
|
if(myConfig.GetAllowedRecivers().Contains(to) == false)
|
||||||
|
{
|
||||||
|
return new KeyValuePair<bool, string>(false, to + " is not in allowed recivers");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
MimeMessage message = new MimeMessage();
|
||||||
|
message.From.Add(new MailboxAddress(myConfig.GetMailReplyAddress() + " via secondbot", myConfig.GetMailReplyAddress()));
|
||||||
|
message.To.Add(new MailboxAddress(to, to));
|
||||||
|
message.Subject = subject;
|
||||||
|
message.Body = new TextPart("plain") { Text = body };
|
||||||
|
using (var client = new SmtpClient())
|
||||||
|
{
|
||||||
|
client.Connect(myConfig.GetHost(), myConfig.GetPort(), myConfig.GetUseSSL());
|
||||||
|
|
||||||
|
// Note: only needed if the SMTP server requires authentication
|
||||||
|
if (myConfig.GetToken() != "none")
|
||||||
|
{
|
||||||
|
client.Authenticate(myConfig.GetUser(), myConfig.GetToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
client.Send(message);
|
||||||
|
client.Disconnect(true);
|
||||||
|
}
|
||||||
|
sent++;
|
||||||
|
return new KeyValuePair<bool, string>(true, "Sending");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogFormater.Warn("Failed to send email: "+ex.Message);
|
||||||
|
failed++;
|
||||||
|
return new KeyValuePair<bool, string>(false, "Failed to send email: " + ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void BotClientRestart(object o, BotClientNotice e)
|
||||||
|
{
|
||||||
|
if (e.isStart == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
botConnected = false;
|
||||||
|
LogFormater.Info("SMTP Service [Attached to new client]");
|
||||||
|
GetClient().Network.LoggedOut += BotLoggedOut;
|
||||||
|
GetClient().Network.SimConnected += BotLoggedIn;
|
||||||
|
GetClient().Self.AlertMessage += BotAlertMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void BotLoggedOut(object o, LoggedOutEventArgs e)
|
||||||
|
{
|
||||||
|
botConnected = false;
|
||||||
|
LogFormater.Info("SMTP Service [Standby]");
|
||||||
|
}
|
||||||
|
protected void BotLoggedIn(object o, SimConnectedEventArgs e)
|
||||||
|
{
|
||||||
|
bool loginEvent = false;
|
||||||
|
if(botConnected == false)
|
||||||
|
{
|
||||||
|
loginEvent = true;
|
||||||
|
}
|
||||||
|
LogFormater.Info("SMTP Service [Active]");
|
||||||
|
botConnected = true;
|
||||||
|
if (loginEvent == true)
|
||||||
|
{
|
||||||
|
if (myConfig.GetAllowSendAlertStatus() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (myConfig.GetSendAlertsAndLoginsTo() == "me@somewhere.tld")
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SendMail("Bot - Login message", GetClient().Self.Name + " has signed in", myConfig.GetSendAlertsAndLoginsTo());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Start(bool updateEnabled = false, bool setEnabledTo = false)
|
||||||
|
{
|
||||||
|
if (updateEnabled)
|
||||||
|
{
|
||||||
|
myConfig.setEnabled(setEnabledTo);
|
||||||
|
}
|
||||||
|
if (myConfig.GetEnabled() == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Stop();
|
||||||
|
running = true;
|
||||||
|
master.BotClientNoticeEvent += BotClientRestart;
|
||||||
|
LogFormater.Info("SMTP Service [Starting]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Stop()
|
||||||
|
{
|
||||||
|
if(running == true)
|
||||||
|
{
|
||||||
|
LogFormater.Info("SMTP Service [Stopping]");
|
||||||
|
}
|
||||||
|
running = false;
|
||||||
|
master.BotClientNoticeEvent -= BotClientRestart;
|
||||||
|
if (master.BotClient != null)
|
||||||
|
{
|
||||||
|
if (GetClient() != null)
|
||||||
|
{
|
||||||
|
GetClient().Network.SimConnected -= BotLoggedIn;
|
||||||
|
GetClient().Self.AlertMessage -= BotAlertMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Loading…
Reference in a new issue