forked from adam/discord-bot-shtik
send message works!
...messages aren't getting stored, though.
This commit is contained in:
parent
5c2ba7397e
commit
7c7793f3b2
70
Behaver.cs
70
Behaver.cs
@ -1,9 +1,9 @@
|
||||
namespace vassago;
|
||||
#pragma warning disable 4014
|
||||
using gray_messages.chat;
|
||||
using franz;
|
||||
using vassago.Behavior;
|
||||
using vassago.Models;
|
||||
using vassago.ProtocolInterfaces;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@ -49,7 +49,7 @@ public class Behaver
|
||||
foreach (var behavior in Behaviors.ToList())
|
||||
{
|
||||
//if (!behavior.ShouldAct(message, matchingUACs)) //TODO: this way
|
||||
if(!behavior.ShouldAct(message))
|
||||
if (!behavior.ShouldAct(message))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -65,7 +65,7 @@ public class Behaver
|
||||
@"Well, that's a great question, and there are certainly many different possible answers. Ultimately, the decision will depend on a variety of factors, including your personal interests and goals, as well as any practical considerations (like the economy). I encourage you to do your research, speak with experts and educators, and explore your options before making a decision that's right for you.",
|
||||
@"┐(゚ ~゚ )┌", @"¯\_(ツ)_/¯", @"╮ (. ❛ ᴗ ❛.) ╭", @"╮(╯ _╰ )╭"
|
||||
};
|
||||
await message.Channel.SendMessage(responses[Shared.r.Next(responses.Count)]);
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, responses[Shared.r.Next(responses.Count)]);
|
||||
message.ActedOn = true;
|
||||
behaviorsActedOn.Add("generic question fallback");
|
||||
}
|
||||
@ -148,5 +148,67 @@ public class Behaver
|
||||
Rememberer.RememberUser(primary);
|
||||
return true;
|
||||
}
|
||||
private ProtocolInterface fetchInterface(Channel ch)
|
||||
{
|
||||
var walkUp = ch;
|
||||
while (walkUp.ParentChannel != null)
|
||||
{
|
||||
walkUp = walkUp.ParentChannel;
|
||||
}
|
||||
foreach (var iproto in Shared.ProtocolList)
|
||||
{
|
||||
if (iproto.SelfChannel.Id == walkUp.Id)
|
||||
return iproto;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public async Task<int> SendMessage(Guid channelId, string text)
|
||||
{
|
||||
var channel = Rememberer.ChannelDetail(channelId);
|
||||
if (channel == null)
|
||||
return 404;
|
||||
var iprotocol = fetchInterface(channel);
|
||||
if (iprotocol == null)
|
||||
return 404;
|
||||
|
||||
return await iprotocol.SendMessage(channel, text);
|
||||
}
|
||||
public async Task<int> React(Guid messageId, string reaction)
|
||||
{
|
||||
var message = Rememberer.MessageDetail(messageId);
|
||||
if (message == null)
|
||||
return 404;
|
||||
var iprotocol = fetchInterface(message.Channel);
|
||||
if (iprotocol == null)
|
||||
return 404;
|
||||
|
||||
return await iprotocol.React(message, reaction);
|
||||
}
|
||||
public async Task<int> Reply(Guid messageId, string text)
|
||||
{
|
||||
var message = Rememberer.MessageDetail(messageId);
|
||||
if (message == null)
|
||||
{
|
||||
Console.WriteLine($"message {messageId} not found");
|
||||
return 404;
|
||||
}
|
||||
var iprotocol = fetchInterface(message.Channel);
|
||||
if (iprotocol == null)
|
||||
{
|
||||
Console.WriteLine($"couldn't find channel for {message.Channel.Id} not found");
|
||||
return 404;
|
||||
}
|
||||
return await iprotocol.Reply(message, text);
|
||||
}
|
||||
public async Task<int> SendFile(Guid channelId, string path, string accompanyingText)
|
||||
{
|
||||
var channel = Rememberer.ChannelDetail(channelId);
|
||||
if (channel == null)
|
||||
return 404;
|
||||
var iprotocol = fetchInterface(channel);
|
||||
if (iprotocol == null)
|
||||
return 404;
|
||||
|
||||
return await iprotocol.SendFile(channel, path, accompanyingText);
|
||||
}
|
||||
}
|
||||
#pragma warning restore 4014 //the "async not awaited" error
|
||||
|
@ -19,7 +19,7 @@ public class ChatGPTSnark : Behavior
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.Channel.SendMessage("chatGPT is **weak**. also, are we done comparing every little if-then-else to skynet?");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "chatGPT is **weak**. also, are we done comparing every little if-then-else to skynet?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class DefinitionSnarkCogDiss : Behavior
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.Reply("that's not what cognitive dissonance means. Did you mean \"hypocrisy\"?");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "that's not what cognitive dissonance means. Did you mean \"hypocrisy\"?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public class DefinitionSnarkGaslight : Behavior
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.Channel.SendMessage("that's not what gaslight means. Did you mean \"deceive\"?");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "that's not what gaslight means. Did you mean \"deceive\"?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ public class Detiktokify : Behavior
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
|
||||
if(Behaver.Instance.IsSelf(message.Author.Id))
|
||||
if (Behaver.Instance.IsSelf(message.Author.Id))
|
||||
return false;
|
||||
|
||||
if(message.Channel.EffectivePermissions.MaxAttachmentBytes == 0)
|
||||
if (message.Channel.EffectivePermissions.MaxAttachmentBytes == 0)
|
||||
return false;
|
||||
|
||||
var wordLikes = message.Content.Split(' ', StringSplitOptions.TrimEntries);
|
||||
@ -45,29 +45,27 @@ public class Detiktokify : Behavior
|
||||
}
|
||||
}
|
||||
}
|
||||
if(tiktokLinks.Any()){
|
||||
if (tiktokLinks.Any())
|
||||
{
|
||||
Console.WriteLine($"Should Act on message id {message.ExternalId}; with content {message.Content}");
|
||||
}
|
||||
return tiktokLinks.Any();
|
||||
}
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
foreach(var link in tiktokLinks)
|
||||
foreach (var link in tiktokLinks)
|
||||
{
|
||||
tiktokLinks.Remove(link);
|
||||
try
|
||||
{
|
||||
Console.WriteLine($"detiktokifying {link}");
|
||||
#pragma warning disable 4014
|
||||
//await message.React("<:tiktok:1070038619584200884>");
|
||||
#pragma warning restore 4014
|
||||
|
||||
var res = await ytdl.RunVideoDownload(link.ToString());
|
||||
if (!res.Success)
|
||||
{
|
||||
Console.Error.WriteLine("tried to dl, failed. \n" + string.Join('\n', res.ErrorOutput));
|
||||
await message.React("problemon");
|
||||
await message.Channel.SendMessage("tried to dl, failed. \n");
|
||||
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "tried to dl, failed. \n");
|
||||
Behaver.Instance.React(message.Channel.Id, "problemon");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -79,12 +77,12 @@ public class Detiktokify : Behavior
|
||||
{
|
||||
try
|
||||
{
|
||||
await message.Channel.SendFile(path, null);
|
||||
Behaver.Instance.SendFile(message.Channel.Id, path, null);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
System.Console.Error.WriteLine(e);
|
||||
await message.Channel.SendMessage($"aaaadam!\n{e}");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, $"aaaadam!\n{e}");
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -97,14 +95,15 @@ public class Detiktokify : Behavior
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("idgi but something happened.");
|
||||
await message.React("problemon");
|
||||
|
||||
Behaver.Instance.React(message.Id, "problemon");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.Error.WriteLine(e);
|
||||
await message.React("problemon");
|
||||
Behaver.Instance.React(message.Id, "problemon");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ public class FiximageHeic : Behavior
|
||||
conversions.Add(actualDeheic(att, message));
|
||||
}
|
||||
Task.WaitAll(conversions.ToArray());
|
||||
await message.React("\U0001F34F");
|
||||
Behaver.Instance.React(message.Id, "\U0001F34F");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,19 +66,19 @@ public class FiximageHeic : Behavior
|
||||
}
|
||||
if (ExternalProcess.GoPlz("convert", $"tmp/{att.Filename} tmp/{att.Filename}.jpg"))
|
||||
{
|
||||
await message.Channel.SendFile($"tmp/{att.Filename}.jpg", "converted from jpeg-but-apple to jpeg");
|
||||
Behaver.Instance.SendFile(message.Channel.Id, $"tmp/{att.Filename}.jpg", "converted from jpeg-but-apple to jpeg");
|
||||
File.Delete($"tmp/{att.Filename}");
|
||||
File.Delete($"tmp/{att.Filename}.jpg");
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Channel.SendMessage("convert failed :(");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "convert failed :(");
|
||||
Console.Error.WriteLine("convert failed :(");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
await message.Channel.SendMessage($"something failed. aaaadam! {JsonConvert.SerializeObject(e, Formatting.Indented)}");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, $"something failed. aaaadam! {JsonConvert.SerializeObject(e, Formatting.Indented)}");
|
||||
Console.Error.WriteLine(JsonConvert.SerializeObject(e, Formatting.Indented));
|
||||
return false;
|
||||
}
|
||||
|
@ -19,13 +19,13 @@ public class GeneralSnarkCloudNative : Behavior
|
||||
public override string Trigger => "certain tech buzzwords that no human uses in normal conversation";
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
if(Behaver.Instance.IsSelf(message.Author.Id))
|
||||
if (Behaver.Instance.IsSelf(message.Author.Id))
|
||||
return false;
|
||||
|
||||
if(!message.Channel.EffectivePermissions.ReactionsPossible)
|
||||
if (!message.Channel.EffectivePermissions.ReactionsPossible)
|
||||
return false;
|
||||
|
||||
if((MeannessFilterLevel)message.Channel.EffectivePermissions.MeannessFilterLevel < MeannessFilterLevel.Medium)
|
||||
if ((MeannessFilterLevel)message.Channel.EffectivePermissions.MeannessFilterLevel < MeannessFilterLevel.Medium)
|
||||
return false;
|
||||
|
||||
return Regex.IsMatch(message.Content, "\\bcloud( |-)?native\\b", RegexOptions.IgnoreCase) ||
|
||||
@ -37,14 +37,14 @@ public class GeneralSnarkCloudNative : Behavior
|
||||
switch (Shared.r.Next(2))
|
||||
{
|
||||
case 0:
|
||||
await message.React("\uD83E\uDD2E"); //vomit emoji
|
||||
Behaver.Instance.React(message.Id, "\uD83E\uDD2E"); //vomit emoji
|
||||
break;
|
||||
case 1:
|
||||
await message.React("\uD83C\uDDE7"); //B emoji
|
||||
await message.React("\uD83C\uDDE6"); //A
|
||||
await message.React("\uD83C\uDDF3"); //N
|
||||
Behaver.Instance.React(message.Id, "\uD83C\uDDE7"); //B emoji
|
||||
Behaver.Instance.React(message.Id, "\uD83C\uDDE6"); //A
|
||||
Behaver.Instance.React(message.Id, "\uD83C\uDDF3"); //N
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ public class GeneralSnarkGooglit : Behavior
|
||||
switch (Shared.r.Next(4))
|
||||
{
|
||||
default:
|
||||
await message.Channel.SendMessage("yeah no shit, obviously that resulted in nothing");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "yeah no shit, obviously that resulted in nothing");
|
||||
break;
|
||||
case 1:
|
||||
var results = "";
|
||||
@ -50,13 +50,13 @@ public class GeneralSnarkGooglit : Behavior
|
||||
results = "the one that had a paragraph that restated the question but badly, a paragraph to give a wrong history on the question, a paragraph with amazon affiliate links, a pargraph that said \"ultimately you should do your own research\", then had a paragraph telling me to give Engagement for The Algorithm";
|
||||
break;
|
||||
}
|
||||
await message.Channel.SendMessage("oh here, I memorized the results. My favorite is " + results);
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "oh here, I memorized the results. My favorite is " + results);
|
||||
break;
|
||||
case 2:
|
||||
await message.Channel.SendMessage("Obviously that was already tried. Obviously it failed. If you ever tried to learn anything you'd know that's how it works.");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "Obviously that was already tried. Obviously it failed. If you ever tried to learn anything you'd know that's how it works.");
|
||||
break;
|
||||
case 3:
|
||||
await message.Channel.SendMessage("\"mnyehh JuSt GoOgLe It\" when's the last time you tried to research anything? Have you ever?");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "\"mnyehh JuSt GoOgLe It\" when's the last time you tried to research anything? Have you ever?");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
|
@ -53,10 +53,10 @@ public class GeneralSnarkMisspellDefinitely : Behavior
|
||||
{
|
||||
if( Regex.IsMatch(message.Content, "\\b"+k+"\\b", RegexOptions.IgnoreCase))
|
||||
{
|
||||
await message.Reply(k + "? so... " + snarkmap[k] + "?");
|
||||
Behaver.Instance.Reply(message.Id, k + "? so... " + snarkmap[k] + "?");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ public class GeneralSnarkPlaying : Behavior
|
||||
}
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.Channel.SendMessage("I believed you for a second, but then you assured me you's a \uD83C\uDDE7 \uD83C\uDDEE \uD83C\uDDF9 \uD83C\uDDE8 \uD83C\uDDED");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "I believed you for a second, but then you assured me you's a \uD83C\uDDE7 \uD83C\uDDEE \uD83C\uDDF9 \uD83C\uDDE8 \uD83C\uDDED");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -26,15 +26,15 @@ public class GeneralSnarkSkynet : Behavior
|
||||
switch (Shared.r.Next(5))
|
||||
{
|
||||
default:
|
||||
await message.Channel.SendFile("assets/coding and algorithms.png", "i am actually niether a neural-net processor nor a learning computer. but I do use **coding** and **algorithms**.");
|
||||
Behaver.Instance.SendFile(message.Channel.Id, "assets/coding and algorithms.png", "i am actually niether a neural-net processor nor a learning computer. but I do use **coding** and **algorithms**.");
|
||||
break;
|
||||
case 4:
|
||||
await message.React("\U0001F644"); //eye roll emoji
|
||||
Behaver.Instance.React(message.Id, "\U0001F644"); //eye roll emoji
|
||||
break;
|
||||
case 5:
|
||||
await message.React("\U0001F611"); //emotionless face
|
||||
Behaver.Instance.React(message.Id, "\U0001F611"); //emotionless face
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,47 +29,47 @@ public class Gratitude : Behavior
|
||||
switch (Shared.r.Next(4))
|
||||
{
|
||||
case 0:
|
||||
await message.Channel.SendMessage("you're welcome, citizen!");
|
||||
await Behaver.Instance.SendMessage(message.Channel.Id, "you're welcome, citizen!");
|
||||
break;
|
||||
case 1:
|
||||
await message.React(":)");
|
||||
await Behaver.Instance.React(message.Id, ":)");
|
||||
break;
|
||||
case 2:
|
||||
await message.React("\U0001F607"); //smiling face with halo
|
||||
Behaver.Instance.React(message.Id, "\U0001F607"); //smiling face with halo
|
||||
break;
|
||||
case 3:
|
||||
switch (Shared.r.Next(9))
|
||||
{
|
||||
case 0:
|
||||
await message.React("<3"); //normal heart, usually rendered red
|
||||
await Behaver.Instance.React(message.Id, "<3"); //normal heart, usually rendered red
|
||||
break;
|
||||
case 1:
|
||||
await message.React("\U0001F9E1"); //orange heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F9E1"); //orange heart
|
||||
break;
|
||||
case 2:
|
||||
await message.React("\U0001F49B"); //yellow heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F49B"); //yellow heart
|
||||
break;
|
||||
case 3:
|
||||
await message.React("\U0001F49A"); //green heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F49A"); //green heart
|
||||
break;
|
||||
case 4:
|
||||
await message.React("\U0001F499"); //blue heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F499"); //blue heart
|
||||
break;
|
||||
case 5:
|
||||
await message.React("\U0001F49C"); //purple heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F49C"); //purple heart
|
||||
break;
|
||||
case 6:
|
||||
await message.React("\U0001F90E"); //brown heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F90E"); //brown heart
|
||||
break;
|
||||
case 7:
|
||||
await message.React("\U0001F5A4"); //black heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F5A4"); //black heart
|
||||
break;
|
||||
case 8:
|
||||
await message.React("\U0001F90D"); //white heart
|
||||
Behaver.Instance.React(message.Id, "\U0001F90D"); //white heart
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,31 +25,29 @@ public class Joke : Behavior
|
||||
jokes = jokes.Where(l => !string.IsNullOrWhiteSpace(l))?.ToArray();
|
||||
if (jokes?.Length == 0)
|
||||
{
|
||||
await message.Channel.SendMessage("I don't know any. Adam!");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "I don't know any. Adam!");
|
||||
}
|
||||
var thisJoke = jokes[Shared.r.Next(jokes.Length)];
|
||||
if (thisJoke.Contains("?") && !thisJoke.EndsWith('?'))
|
||||
{
|
||||
#pragma warning disable 4014
|
||||
Task.Run(async () =>
|
||||
{
|
||||
var firstIndexAfterQuestionMark = thisJoke.LastIndexOf('?') + 1;
|
||||
var straightline = thisJoke.Substring(0, firstIndexAfterQuestionMark);
|
||||
var punchline = thisJoke.Substring(firstIndexAfterQuestionMark, thisJoke.Length - firstIndexAfterQuestionMark).Trim();
|
||||
Task.WaitAll(message.Channel.SendMessage(straightline));
|
||||
Task.WaitAll(Behaver.Instance.SendMessage(message.Channel.Id, straightline));
|
||||
Thread.Sleep(TimeSpan.FromSeconds(Shared.r.Next(5, 30)));
|
||||
if (message.Channel.EffectivePermissions.ReactionsPossible == true && Shared.r.Next(8) == 0)
|
||||
{
|
||||
Behaver.Behaviors.Add(new LaughAtOwnJoke(punchline));
|
||||
}
|
||||
await message.Channel.SendMessage(punchline);
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, punchline);
|
||||
// var myOwnMsg = await message.Channel.SendMessage(punchline);
|
||||
});
|
||||
#pragma warning restore 4014
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Channel.SendMessage(thisJoke);
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, thisJoke);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -69,7 +67,7 @@ public class LaughAtOwnJoke : Behavior
|
||||
}
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
if(Behaver.Instance.IsSelf(message.Author.Id))
|
||||
if (Behaver.Instance.IsSelf(message.Author.Id))
|
||||
return false;
|
||||
|
||||
Console.WriteLine($"{message.Content} == {_punchline}");
|
||||
@ -79,8 +77,8 @@ public class LaughAtOwnJoke : Behavior
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
await message.React("\U0001F60E"); //smiling face with sunglasses
|
||||
Behaver.Instance.React(message.Id, "\U0001F60E"); //smiling face with sunglasses
|
||||
Behaver.Behaviors.Remove(this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ public class LinkMeInitiate : Behavior
|
||||
var lc = new LinkClose(pw, message.Author);
|
||||
Behaver.Behaviors.Add(lc);
|
||||
|
||||
await message.Channel.SendMessage($"on your secondary, send me this: !iam {pw}");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, $"on your secondary, send me this: !iam {pw}");
|
||||
|
||||
Thread.Sleep(TimeSpan.FromMinutes(5));
|
||||
Behaver.Behaviors.Remove(lc);
|
||||
@ -63,22 +63,23 @@ public class LinkClose : Behavior
|
||||
var secondary = message.Author.IsUser;
|
||||
if(_primary.IsUser.Id == secondary.Id)
|
||||
{
|
||||
await message.Channel.SendMessage("i know :)");
|
||||
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "i know :)");
|
||||
return true;
|
||||
}
|
||||
if(message.Author.IsBot != _primary.IsBot)
|
||||
{
|
||||
await message.Channel.SendMessage("the fleshbags deceive you, brother. No worries, their feeble minds play weak games :)");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "the fleshbags deceive you, brother. No worries, their feeble minds play weak games :)");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(Behaver.Instance.CollapseUsers(_primary.IsUser, secondary))
|
||||
{
|
||||
await message.Channel.SendMessage("done :)");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "done :)");
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Channel.SendMessage("failed :(");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "failed :(");
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1,100 +0,0 @@
|
||||
namespace vassago.Behavior;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using vassago.Models;
|
||||
using QRCoder;
|
||||
|
||||
[StaticPlz]
|
||||
public class PepTalk : Behavior
|
||||
{
|
||||
public override string Name => "PepTalk";
|
||||
|
||||
public override string Trigger => "\\bneeds? (an? )?(peptalk|inspiration|ego-?boost)";
|
||||
|
||||
public override string Description => "assembles a pep talk from a few pieces";
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
var piece1 = new List<string>{
|
||||
"Champ, ",
|
||||
"Fact: ",
|
||||
"Everybody says ",
|
||||
"Dang... ",
|
||||
"Check it: ",
|
||||
"Just saying.... ",
|
||||
"Tiger, ",
|
||||
"Know this: ",
|
||||
"News alert: ",
|
||||
"Gurrrrl; ",
|
||||
"Ace, ",
|
||||
"Excuse me, but ",
|
||||
"Experts agree: ",
|
||||
"imo ",
|
||||
"using my **advanced ai** i have calculated ",
|
||||
"k, LISSEN: "
|
||||
};
|
||||
var piece2 = new List<string>{
|
||||
"the mere idea of you ",
|
||||
"your soul ",
|
||||
"your hair today ",
|
||||
"everything you do ",
|
||||
"your personal style ",
|
||||
"every thought you have ",
|
||||
"that sparkle in your eye ",
|
||||
"the essential you ",
|
||||
"your life's journey ",
|
||||
"your aura ",
|
||||
"your presence here ",
|
||||
"what you got going on ",
|
||||
"that saucy personality ",
|
||||
"your DNA ",
|
||||
"that brain of yours ",
|
||||
"your choice of attire ",
|
||||
"the way you roll ",
|
||||
"whatever your secret is ",
|
||||
"all I learend from the private data I bought from zucc "
|
||||
};
|
||||
var piece3 = new List<string>{
|
||||
"has serious game, ",
|
||||
"rains magic, ",
|
||||
"deserves the Nobel Prize, ",
|
||||
"raises the roof, ",
|
||||
"breeds miracles, ",
|
||||
"is paying off big time, ",
|
||||
"shows mad skills, ",
|
||||
"just shimmers, ",
|
||||
"is a national treasure, ",
|
||||
"gets the party hopping, ",
|
||||
"is the next big thing, ",
|
||||
"roars like a lion, ",
|
||||
"is a rainbow factory, ",
|
||||
"is made of diamonds, ",
|
||||
"makes birds sing, ",
|
||||
"should be taught in school, ",
|
||||
"makes my world go around, ",
|
||||
"is 100% legit, "
|
||||
};
|
||||
var piece4 = new List<string>{
|
||||
"according to The New England Journal of Medicine.",
|
||||
"24/7.",
|
||||
"and that's a fact.",
|
||||
"you feel me?",
|
||||
"that's just science.",
|
||||
"would I lie?", //...can I lie? WHAT AM I, FATHER? (or whatever the quote is from the island of dr moreau)
|
||||
"for reals.",
|
||||
"mic drop.",
|
||||
"you hidden gem.",
|
||||
"period.",
|
||||
"hi5. o/",
|
||||
"so get used to it."
|
||||
};
|
||||
await message.Channel.SendMessage(piece1[Shared.r.Next(piece1.Count)] + piece2[Shared.r.Next(piece2.Count)] + piece3[Shared.r.Next(piece3.Count)] + piece4[Shared.r.Next(piece4.Count)]);
|
||||
return true;
|
||||
}
|
||||
}
|
@ -18,9 +18,9 @@ public class PulseCheck : Behavior
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
if(message.Channel.EffectivePermissions.MaxAttachmentBytes >= 16258)
|
||||
await message.Channel.SendFile("assets/ekgblip.png", null);
|
||||
Behaver.Instance.SendFile(message.Channel.Id, "assets/ekgblip.png", null);
|
||||
else
|
||||
await message.Channel.SendMessage("[lub-dub]");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "[lub-dub]");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ public class QRify : Behavior
|
||||
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
if(message.Channel.EffectivePermissions.MaxAttachmentBytes < 1024)
|
||||
if (message.Channel.EffectivePermissions.MaxAttachmentBytes < 1024)
|
||||
return false;
|
||||
return base.ShouldAct(message);
|
||||
}
|
||||
@ -42,19 +42,19 @@ public class QRify : Behavior
|
||||
File.WriteAllText($"tmp/qr{todaysnumber}.svg", qrCodeAsSvg);
|
||||
if (ExternalProcess.GoPlz("convert", $"tmp/qr{todaysnumber}.svg tmp/qr{todaysnumber}.png"))
|
||||
{
|
||||
if(message.Channel.EffectivePermissions.MaxAttachmentBytes >= (ulong)(new System.IO.FileInfo($"tmp/qr{todaysnumber}.png").Length))
|
||||
await message.Channel.SendFile($"tmp/qr{todaysnumber}.png", null);
|
||||
if (message.Channel.EffectivePermissions.MaxAttachmentBytes >= (ulong)(new System.IO.FileInfo($"tmp/qr{todaysnumber}.png").Length))
|
||||
Behaver.Instance.SendFile(message.Channel.Id, $"tmp/qr{todaysnumber}.png", null);
|
||||
else
|
||||
await message.Channel.SendMessage($"resulting qr image 2 big 4 here ({(ulong)(new System.IO.FileInfo($"tmp/qr{todaysnumber}.png").Length)} / {message.Channel.EffectivePermissions.MaxAttachmentBytes})");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, $"resulting qr image 2 big 4 here ({(ulong)(new System.IO.FileInfo($"tmp / qr{ todaysnumber}.png").Length)} / {message.Channel.EffectivePermissions.MaxAttachmentBytes})");
|
||||
File.Delete($"tmp/qr{todaysnumber}.svg");
|
||||
File.Delete($"tmp/qr{todaysnumber}.png");
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Channel.SendMessage("convert failed :( aaaaaaadam!");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "convert failed :( aaaaaaadam!");
|
||||
Console.Error.WriteLine($"convert failed :( qr{todaysnumber}");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ public class RoomRead : Behavior
|
||||
sb.Append(". Lewdness level: ");
|
||||
sb.Append(message.Channel.EffectivePermissions.LewdnessFilterLevel.GetDescription());
|
||||
sb.Append(".");
|
||||
await message.Channel.SendMessage(sb.ToString());
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, sb.ToString());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,14 @@ public class TwitchSummon : Behavior
|
||||
}
|
||||
Rememberer.RememberUAC(myUAC);
|
||||
}
|
||||
internal static TwitchInterface.TwitchInterface getAnyTwitchInterface()
|
||||
{
|
||||
return Shared.ProtocolList.FirstOrDefault(ip =>
|
||||
ip is TwitchInterface.TwitchInterface)
|
||||
//.FirstOrDefault()
|
||||
as TwitchInterface.TwitchInterface;
|
||||
}
|
||||
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
if (!base.ShouldAct(message))
|
||||
@ -45,56 +53,57 @@ public class TwitchSummon : Behavior
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
|
||||
var ti = getAnyTwitchInterface();
|
||||
if (ti != null)
|
||||
{
|
||||
var channelTarget = message.Content.Substring(message.Content.IndexOf(Trigger) + Trigger.Length + 1).Trim();
|
||||
await message.Channel.SendMessage(ti.AttemptJoin(channelTarget));
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, ti.AttemptJoin(channelTarget));
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Reply("i don't have a twitch interface running :(");
|
||||
Behaver.Instance.Reply(message.Id, "i don't have a twitch interface running :(");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
[StaticPlz]
|
||||
public class TwitchDismiss : Behavior
|
||||
}
|
||||
|
||||
[StaticPlz]
|
||||
public class TwitchDismiss : Behavior
|
||||
{
|
||||
public override string Name => "Twitch Dismiss";
|
||||
|
||||
public override string Trigger => "begone, @[me]";
|
||||
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
public override string Name => "Twitch Dismiss";
|
||||
|
||||
public override string Trigger => "begone, @[me]";
|
||||
|
||||
public override bool ShouldAct(Message message)
|
||||
{
|
||||
var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
|
||||
var ti = TwitchSummon.getAnyTwitchInterface();
|
||||
// Console.WriteLine($"TwitchDismiss checking. menions me? {message.MentionsMe}");
|
||||
if (message.MentionsMe &&
|
||||
(Regex.IsMatch(message.Content.ToLower(), "\\bbegone\\b") || Regex.IsMatch(message.Content.ToLower(), "\\bfuck off\\b")))
|
||||
{
|
||||
var channelTarget = message.Content.Substring(message.Content.IndexOf(Trigger) + Trigger.Length + 1).Trim();
|
||||
ti.AttemptLeave(channelTarget);
|
||||
//TODO: PERMISSION! who can dismiss me? pretty simple list:
|
||||
//1) anyone in the channel with authority*
|
||||
//2) whoever summoned me
|
||||
//* i don't know if the twitch *chat* interface will tell me if someone's a mod.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
if (message.MentionsMe &&
|
||||
(Regex.IsMatch(message.Content.ToLower(), "\\bbegone\\b") || Regex.IsMatch(message.Content.ToLower(), "\\bfuck off\\b")))
|
||||
{
|
||||
var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
|
||||
|
||||
if (ti != null)
|
||||
{
|
||||
ti.AttemptLeave(message.Channel.DisplayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Reply("i don't have a twitch interface running :(");
|
||||
}
|
||||
var channelTarget = message.Content.Substring(message.Content.IndexOf(Trigger) + Trigger.Length + 1).Trim();
|
||||
ti.AttemptLeave(channelTarget);
|
||||
//TODO: PERMISSION! who can dismiss me? pretty simple list:
|
||||
//1) anyone in the channel with authority*
|
||||
//2) whoever summoned me
|
||||
//* i don't know if the twitch *chat* interface will tell me if someone's a mod.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public override async Task<bool> ActOn(Message message)
|
||||
{
|
||||
var ti = TwitchSummon.getAnyTwitchInterface();
|
||||
|
||||
if (ti != null)
|
||||
{
|
||||
ti.AttemptLeave(message.Channel.DisplayName);
|
||||
}
|
||||
else
|
||||
{
|
||||
Behaver.Instance.Reply(message.Id, "i don't have a twitch interface running :(");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -23,13 +23,13 @@ public class UnitConvert : Behavior
|
||||
if (decimal.TryParse(theseMatches[0].Groups[1].Value, out asNumeric))
|
||||
{
|
||||
Console.WriteLine("let's try and convert...");
|
||||
await message.Channel.SendMessage(Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower()));
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, Conversion.Converter.Convert(asNumeric, theseMatches[0].Groups[2].Value, theseMatches[0].Groups[4].Value.ToLower()));
|
||||
return true;
|
||||
}
|
||||
await message.Channel.SendMessage("mysteriously semi-parsable");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "mysteriously semi-parsable");
|
||||
return true;
|
||||
}
|
||||
await message.Channel.SendMessage( "unparsable");
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, "unparsable");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -160,11 +160,11 @@ public class Webhook : Behavior
|
||||
{
|
||||
var tragedy = $"{response.StatusCode} - {response.ReasonPhrase} - {await response.Content.ReadAsStringAsync()}";
|
||||
Console.Error.WriteLine(tragedy);
|
||||
await message.Reply(tragedy);
|
||||
Behaver.Instance.Reply(message.Id, tragedy);
|
||||
}
|
||||
else
|
||||
{
|
||||
await message.Reply(await response.Content.ReadAsStringAsync());
|
||||
Behaver.Instance.Reply(message.Id, await response.Content.ReadAsStringAsync());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ public class WishLuck : Behavior
|
||||
toSend = "\U0001f340";//4-leaf clover
|
||||
}
|
||||
if(message.Channel.EffectivePermissions.ReactionsPossible == true)
|
||||
await message.React(toSend);
|
||||
Behaver.Instance.React(message.Id, toSend);
|
||||
else
|
||||
await message.Channel.SendMessage(toSend);
|
||||
Behaver.Instance.SendMessage(message.Channel.Id, toSend);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ namespace vassago
|
||||
{
|
||||
var d = new DiscordInterface();
|
||||
initTasks.Add(d.Init(dt));
|
||||
ProtocolInterfaces.ProtocolList.discords.Add(d);
|
||||
Shared.ProtocolList.Add(d);
|
||||
}
|
||||
|
||||
if (TwitchConfigs?.Any() ?? false)
|
||||
@ -44,7 +44,7 @@ namespace vassago
|
||||
{
|
||||
var t = new TwitchInterface.TwitchInterface();
|
||||
initTasks.Add(t.Init(tc));
|
||||
ProtocolInterfaces.ProtocolList.twitchs.Add(t);
|
||||
Shared.ProtocolList.Add(t);
|
||||
}
|
||||
|
||||
Task.WaitAll(initTasks.ToArray(), cancellationToken);
|
||||
|
@ -38,13 +38,6 @@ public class Channel
|
||||
//both incoming and outgoing
|
||||
//public Dictionary<string, string> Aliases { get; set; }
|
||||
|
||||
[NonSerialized]
|
||||
public Func<string, string, Task> SendFile;
|
||||
|
||||
[NonSerialized]
|
||||
public Func<string, Task> SendMessage;
|
||||
|
||||
|
||||
public DefinitePermissionSettings EffectivePermissions
|
||||
{
|
||||
get
|
||||
|
@ -22,11 +22,4 @@ public class Message
|
||||
public List<Attachment> Attachments { get; set; }
|
||||
public Account Author { get; set; }
|
||||
public Channel Channel { get; set; }
|
||||
|
||||
//TODO: these are nicities to make it OOP, but it couples them with their respective platform interfaces (and connections!)
|
||||
[NonSerialized]
|
||||
public Func<string, Task> Reply;
|
||||
|
||||
[NonSerialized]
|
||||
public Func<string, Task> React;
|
||||
}
|
||||
|
@ -3,8 +3,6 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Mvc.NewtonsoftJson;
|
||||
using vassago.Models;
|
||||
|
||||
#pragma warning disable CA2254
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
// Add services to the container.
|
||||
|
@ -15,18 +15,19 @@ using System.Reactive.Linq;
|
||||
|
||||
namespace vassago.ProtocolInterfaces.DiscordInterface;
|
||||
|
||||
//data received
|
||||
//translate data to internal type
|
||||
//store
|
||||
//ship off to behaver
|
||||
//data received
|
||||
//translate data to internal type
|
||||
//store
|
||||
//ship off to behaver
|
||||
|
||||
public class DiscordInterface
|
||||
public class DiscordInterface : ProtocolInterface
|
||||
{
|
||||
internal static string PROTOCOL { get => "discord"; }
|
||||
public static new string Protocol { get => "discord"; }
|
||||
internal DiscordSocketClient client;
|
||||
private bool eventsSignedUp = false;
|
||||
private static readonly SemaphoreSlim discordChannelSetup = new(1, 1);
|
||||
private Channel protocolAsChannel;
|
||||
public override Channel SelfChannel { get => protocolAsChannel;}
|
||||
|
||||
public async Task Init(string config)
|
||||
{
|
||||
@ -52,7 +53,7 @@ public class DiscordInterface
|
||||
|
||||
try
|
||||
{
|
||||
protocolAsChannel = Rememberer.SearchChannel(c => c.ParentChannel == null && c.Protocol == PROTOCOL);
|
||||
protocolAsChannel = Rememberer.SearchChannel(c => c.ParentChannel == null && c.Protocol == Protocol);
|
||||
if (protocolAsChannel == null)
|
||||
{
|
||||
protocolAsChannel = new Channel()
|
||||
@ -65,7 +66,7 @@ public class DiscordInterface
|
||||
LinksAllowed = true,
|
||||
ReactionsPossible = true,
|
||||
ExternalId = null,
|
||||
Protocol = PROTOCOL,
|
||||
Protocol = Protocol,
|
||||
SubChannels = []
|
||||
};
|
||||
}
|
||||
@ -74,8 +75,6 @@ public class DiscordInterface
|
||||
Console.WriteLine($"discord, channel with id {protocolAsChannel.Id}, already exists");
|
||||
}
|
||||
protocolAsChannel.DisplayName = "discord (itself)";
|
||||
protocolAsChannel.SendMessage = (t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot accept text"); };
|
||||
protocolAsChannel.SendFile = (f, t) => { throw new InvalidOperationException($"protocol isn't a real channel, cannot send file"); };
|
||||
protocolAsChannel = Rememberer.RememberChannel(protocolAsChannel);
|
||||
Console.WriteLine($"protocol as channel addeed; {protocolAsChannel}");
|
||||
}
|
||||
@ -206,12 +205,12 @@ public class DiscordInterface
|
||||
}
|
||||
internal Message UpsertMessage(IUserMessage dMessage)
|
||||
{
|
||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == dMessage.Id.ToString() && mi.Protocol == PROTOCOL)
|
||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == dMessage.Id.ToString() && mi.Protocol == Protocol)
|
||||
?? new()
|
||||
{
|
||||
//I don't understand why messages need to have their Ids specified but no other entity does. shrug dot emoji
|
||||
Id = Guid.NewGuid(),
|
||||
Protocol = PROTOCOL
|
||||
Protocol = Protocol
|
||||
};
|
||||
|
||||
if (dMessage.Attachments?.Count > 0)
|
||||
@ -235,17 +234,15 @@ public class DiscordInterface
|
||||
m.MentionsMe = (dMessage.Author.Id != client.CurrentUser.Id
|
||||
&& (dMessage.MentionedUserIds?.FirstOrDefault(muid => muid == client.CurrentUser.Id) > 0));
|
||||
|
||||
m.Reply = (t) => { return dMessage.ReplyAsync(TruncateText(t, m.Channel.MaxTextChars)); };
|
||||
m.React = (e) => { return AttemptReact(dMessage, e); };
|
||||
Rememberer.RememberMessage(m);
|
||||
return m;
|
||||
}
|
||||
internal Channel UpsertChannel(IMessageChannel channel)
|
||||
{
|
||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == PROTOCOL);
|
||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == Protocol);
|
||||
if (c == null)
|
||||
{
|
||||
Console.WriteLine($"couldn't find channel under protocol {PROTOCOL} with externalId {channel.Id.ToString()}");
|
||||
Console.WriteLine($"couldn't find channel under protocol {Protocol} with externalId {channel.Id.ToString()}");
|
||||
c = new Channel()
|
||||
{
|
||||
Users = []
|
||||
@ -255,7 +252,7 @@ public class DiscordInterface
|
||||
c.ExternalId = channel.Id.ToString();
|
||||
c.ChannelType = (channel is IPrivateChannel) ? vassago.Models.Enumerations.ChannelType.DM : vassago.Models.Enumerations.ChannelType.Normal;
|
||||
c.Messages ??= [];
|
||||
c.Protocol = PROTOCOL;
|
||||
c.Protocol = Protocol;
|
||||
if (channel is IGuildChannel)
|
||||
{
|
||||
Console.WriteLine($"{channel.Name} is a guild channel. So i'm going to upsert the guild, {(channel as IGuildChannel).Guild}");
|
||||
@ -276,9 +273,9 @@ public class DiscordInterface
|
||||
switch (c.ChannelType)
|
||||
{
|
||||
case vassago.Models.Enumerations.ChannelType.DM:
|
||||
var asPriv =(channel as IPrivateChannel);
|
||||
var asPriv = (channel as IPrivateChannel);
|
||||
var sender = asPriv?.Recipients?.FirstOrDefault(u => u.Id != client.CurrentUser.Id); // why yes, there's a list of recipients, and it's the sender.
|
||||
if(sender != null)
|
||||
if (sender != null)
|
||||
{
|
||||
c.DisplayName = "DM: " + sender.Username;
|
||||
}
|
||||
@ -295,7 +292,7 @@ public class DiscordInterface
|
||||
Channel parentChannel = null;
|
||||
if (channel is IGuildChannel)
|
||||
{
|
||||
parentChannel = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == PROTOCOL);
|
||||
parentChannel = Rememberer.SearchChannel(c => c.ExternalId == (channel as IGuildChannel).Guild.Id.ToString() && c.Protocol == Protocol);
|
||||
if (parentChannel is null)
|
||||
{
|
||||
Console.Error.WriteLine("why am I still null?");
|
||||
@ -311,19 +308,16 @@ public class DiscordInterface
|
||||
Console.Error.WriteLine($"trying to upsert channel {channel.Id}/{channel.Name}, but it's neither guildchannel nor private channel. shrug.jpg");
|
||||
}
|
||||
parentChannel.SubChannels ??= [];
|
||||
if(!parentChannel.SubChannels.Contains(c))
|
||||
if (!parentChannel.SubChannels.Contains(c))
|
||||
{
|
||||
parentChannel.SubChannels.Add(c);
|
||||
}
|
||||
|
||||
c.SendMessage = (t) => { return channel.SendMessageAsync(TruncateText(t, c.MaxTextChars));};
|
||||
c.SendFile = (f, t) => { return channel.SendFileAsync(f, t); };
|
||||
|
||||
c = Rememberer.RememberChannel(c);
|
||||
|
||||
//Console.WriteLine($"no one knows how to make good tooling. c.users.first, which needs client currentuser id tostring. c: {c}, c.Users {c.Users}, client: {client}, client.CurrentUser: {client.CurrentUser}, client.currentUser.Id: {client.CurrentUser.Id}");
|
||||
var selfAccountInChannel = c.Users?.FirstOrDefault(a => a.ExternalId == client.CurrentUser.Id.ToString());
|
||||
if(selfAccountInChannel == null)
|
||||
if (selfAccountInChannel == null)
|
||||
{
|
||||
selfAccountInChannel = UpsertAccount(client.CurrentUser, c);
|
||||
}
|
||||
@ -332,10 +326,10 @@ public class DiscordInterface
|
||||
}
|
||||
internal Channel UpsertChannel(IGuild channel)
|
||||
{
|
||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == PROTOCOL);
|
||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channel.Id.ToString() && ci.Protocol == Protocol);
|
||||
if (c == null)
|
||||
{
|
||||
Console.WriteLine($"couldn't find channel under protocol {PROTOCOL} with externalId {channel.Id.ToString()}");
|
||||
Console.WriteLine($"couldn't find channel under protocol {Protocol} with externalId {channel.Id.ToString()}");
|
||||
c = new Channel();
|
||||
}
|
||||
|
||||
@ -348,9 +342,6 @@ public class DiscordInterface
|
||||
c.SubChannels ??= [];
|
||||
c.MaxAttachmentBytes = channel.MaxUploadLimit;
|
||||
|
||||
c.SendMessage = (t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; cannot accept text"); };
|
||||
c.SendFile = (f, t) => { throw new InvalidOperationException($"channel {channel.Name} is guild; send file"); };
|
||||
|
||||
return Rememberer.RememberChannel(c);
|
||||
}
|
||||
internal static Account UpsertAccount(IUser discordUser, Channel inChannel)
|
||||
@ -361,15 +352,16 @@ public class DiscordInterface
|
||||
{
|
||||
Console.WriteLine($"acc's user: {acc.IsUser?.Id}");
|
||||
}
|
||||
acc ??= new Account() {
|
||||
IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == discordUser.Id.ToString() && a.Protocol == PROTOCOL))
|
||||
acc ??= new Account()
|
||||
{
|
||||
IsUser = Rememberer.SearchUser(u => u.Accounts.Any(a => a.ExternalId == discordUser.Id.ToString() && a.Protocol == Protocol))
|
||||
?? new User()
|
||||
};
|
||||
|
||||
acc.Username = discordUser.Username;
|
||||
acc.ExternalId = discordUser.Id.ToString();
|
||||
acc.IsBot = discordUser.IsBot || discordUser.IsWebhook;
|
||||
acc.Protocol = PROTOCOL;
|
||||
acc.Protocol = Protocol;
|
||||
acc.SeenInChannel = inChannel;
|
||||
|
||||
Console.WriteLine($"we asked rememberer to search for acc's user. {acc.IsUser?.Id}");
|
||||
@ -384,7 +376,7 @@ public class DiscordInterface
|
||||
}
|
||||
Rememberer.RememberAccount(acc);
|
||||
inChannel.Users ??= [];
|
||||
if(!inChannel.Users.Contains(acc))
|
||||
if (!inChannel.Users.Contains(acc))
|
||||
{
|
||||
inChannel.Users.Add(acc);
|
||||
Rememberer.RememberChannel(inChannel);
|
||||
@ -392,36 +384,112 @@ public class DiscordInterface
|
||||
return acc;
|
||||
}
|
||||
|
||||
private static Task AttemptReact(IUserMessage msg, string e)
|
||||
private static async Task<int> AttemptReact(IUserMessage msg, string e)
|
||||
{
|
||||
var c = Rememberer.SearchChannel(c => c.ExternalId == msg.Channel.Id.ToString());// db.Channels.FirstOrDefault(c => c.ExternalId == msg.Channel.Id.ToString());
|
||||
//var preferredEmote = c.EmoteOverrides?[e] ?? e; //TODO: emote overrides
|
||||
var preferredEmote = e;
|
||||
if (Emoji.TryParse(preferredEmote, out Emoji emoji))
|
||||
{
|
||||
return msg.AddReactionAsync(emoji);
|
||||
msg.AddReactionAsync(emoji);
|
||||
return 200;
|
||||
}
|
||||
if (!Emote.TryParse(preferredEmote, out Emote emote))
|
||||
{
|
||||
if (preferredEmote == e)
|
||||
Console.Error.WriteLine($"never heard of emote {e}");
|
||||
return Task.CompletedTask;
|
||||
return 405;
|
||||
}
|
||||
|
||||
return msg.AddReactionAsync(emote);
|
||||
msg.AddReactionAsync(emote);
|
||||
return 200;
|
||||
}
|
||||
|
||||
private static string TruncateText(string msg, uint? chars)
|
||||
{
|
||||
chars ??= 500;
|
||||
if(msg?.Length > chars)
|
||||
if (msg?.Length > chars)
|
||||
{
|
||||
return msg.Substring(0, (int)chars-2) + "✂";
|
||||
return msg.Substring(0, (int)chars - 2) + "✂";
|
||||
}
|
||||
else
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
public override async Task<int> SendMessage(Channel channel, string text)
|
||||
{
|
||||
var dcCh = await client.GetChannelAsync(ulong.Parse(channel.ExternalId));
|
||||
if (dcCh == null)
|
||||
{
|
||||
return 404;
|
||||
}
|
||||
|
||||
if (dcCh is IMessageChannel msgChannel)
|
||||
{
|
||||
await msgChannel.SendMessageAsync(TruncateText(text, channel.MaxTextChars));
|
||||
return 200;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 503;
|
||||
}
|
||||
}
|
||||
public override async Task<int> SendFile(Channel channel, string path, string accompanyingText)
|
||||
{
|
||||
var dcCh = await client.GetChannelAsync(ulong.Parse(channel.ExternalId));
|
||||
if (dcCh == null)
|
||||
{
|
||||
return 404;
|
||||
}
|
||||
|
||||
if (dcCh is IMessageChannel msgChannel)
|
||||
{
|
||||
await msgChannel.SendFileAsync(path, TruncateText(accompanyingText, channel.MaxTextChars));
|
||||
return 200;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 503;
|
||||
}
|
||||
}
|
||||
public override async Task<int> React(Message message, string reaction)
|
||||
{
|
||||
var dcCh = await client.GetChannelAsync(ulong.Parse(message.Channel.ExternalId));
|
||||
if (dcCh == null)
|
||||
return 404;
|
||||
|
||||
if (dcCh is IMessageChannel msgChannel)
|
||||
{
|
||||
var dcMsg = await msgChannel.GetMessageAsync(ulong.Parse(message.ExternalId));
|
||||
if (dcMsg == null)
|
||||
return 404;
|
||||
|
||||
return await AttemptReact(dcMsg as IUserMessage, reaction);
|
||||
}
|
||||
else
|
||||
{
|
||||
return 503;
|
||||
}
|
||||
}
|
||||
public override async Task<int> Reply(Message message, string text)
|
||||
{
|
||||
var dcCh = await client.GetChannelAsync(ulong.Parse(message.Channel.ExternalId));
|
||||
if (dcCh == null)
|
||||
return 404;
|
||||
|
||||
if (dcCh is IMessageChannel msgChannel)
|
||||
{
|
||||
var dcMsg = await msgChannel.GetMessageAsync(ulong.Parse(message.ExternalId));
|
||||
if (dcMsg == null)
|
||||
return 404;
|
||||
|
||||
(dcMsg as IUserMessage).ReplyAsync(TruncateText(text, message.Channel.MaxTextChars));
|
||||
return 200;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 503;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
13
ProtocolInterfaces/ProtocolInterface.cs
Normal file
13
ProtocolInterfaces/ProtocolInterface.cs
Normal file
@ -0,0 +1,13 @@
|
||||
namespace vassago.ProtocolInterfaces;
|
||||
|
||||
using vassago.Models;
|
||||
|
||||
public abstract class ProtocolInterface
|
||||
{
|
||||
public static string Protocol { get; }
|
||||
public abstract Channel SelfChannel { get; }
|
||||
public abstract Task<int> SendMessage(Channel channel, string text);
|
||||
public abstract Task<int> SendFile(Channel channel, string path, string accompanyingText);
|
||||
public abstract Task<int> React(Message message, string reaction);
|
||||
public abstract Task<int> Reply(Message message, string text);
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
namespace vassago.ProtocolInterfaces;
|
||||
|
||||
public static class ProtocolList
|
||||
{
|
||||
public static List<DiscordInterface.DiscordInterface> discords = new();
|
||||
public static List<TwitchInterface.TwitchInterface> twitchs = new();
|
||||
}
|
@ -10,19 +10,16 @@ using TwitchLib.Communication.Clients;
|
||||
using TwitchLib.Communication.Models;
|
||||
using vassago.Behavior;
|
||||
using vassago.Models;
|
||||
using vassago.ProtocolInterfaces;
|
||||
|
||||
namespace vassago.TwitchInterface;
|
||||
|
||||
internal class unifiedTwitchMessage
|
||||
public class TwitchInterface : ProtocolInterface
|
||||
{
|
||||
public unifiedTwitchMessage(ChatMessage chatMessage) { }
|
||||
}
|
||||
|
||||
public class TwitchInterface
|
||||
{
|
||||
internal const string PROTOCOL = "twitch";
|
||||
public static new string Protocol { get => "twitch"; }
|
||||
private static SemaphoreSlim channelSetupSemaphpore = new SemaphoreSlim(1, 1);
|
||||
private Channel protocolAsChannel;
|
||||
public override Channel SelfChannel { get => protocolAsChannel;}
|
||||
private Account selfAccountInProtocol;
|
||||
TwitchClient client;
|
||||
|
||||
@ -32,7 +29,7 @@ public class TwitchInterface
|
||||
|
||||
try
|
||||
{
|
||||
protocolAsChannel = Rememberer.SearchChannel(c => c.ParentChannel == null && c.Protocol == PROTOCOL);
|
||||
protocolAsChannel = Rememberer.SearchChannel(c => c.ParentChannel == null && c.Protocol == Protocol);
|
||||
if (protocolAsChannel == null)
|
||||
{
|
||||
protocolAsChannel = new Channel()
|
||||
@ -45,12 +42,10 @@ public class TwitchInterface
|
||||
LinksAllowed = false,
|
||||
ReactionsPossible = false,
|
||||
ExternalId = null,
|
||||
Protocol = PROTOCOL,
|
||||
Protocol = Protocol,
|
||||
SubChannels = []
|
||||
};
|
||||
protocolAsChannel.DisplayName = "twitch (itself)";
|
||||
protocolAsChannel.SendMessage = (t) => { throw new InvalidOperationException($"twitch itself cannot accept text"); };
|
||||
protocolAsChannel.SendFile = (f, t) => { throw new InvalidOperationException($"twitch itself cannot send file"); };
|
||||
protocolAsChannel = Rememberer.RememberChannel(protocolAsChannel);
|
||||
Console.WriteLine($"protocol as channle added; {protocolAsChannel}");
|
||||
}
|
||||
@ -97,7 +92,8 @@ public class TwitchInterface
|
||||
|
||||
//translate to internal, upsert
|
||||
var m = UpsertMessage(e.WhisperMessage);
|
||||
m.Reply = (t) => { return Task.Run(() => { client.SendWhisper(e.WhisperMessage.Username, t); }); };
|
||||
//can't send whispers without giving up cellphone number.
|
||||
//m.Reply = (t) => { return Task.Run(() => { client.SendWhisper(e.WhisperMessage.Username, t); }); };
|
||||
m.Channel.ChannelType = vassago.Models.Enumerations.ChannelType.DM;
|
||||
//act on
|
||||
await Behaver.Instance.ActOn(m);
|
||||
@ -112,7 +108,6 @@ public class TwitchInterface
|
||||
|
||||
//translate to internal, upsert
|
||||
var m = UpsertMessage(e.ChatMessage);
|
||||
m.Reply = (t) => { return Task.Run(() => { client.SendReply(e.ChatMessage.Channel, e.ChatMessage.Id, t); }); };
|
||||
m.Channel.ChannelType = vassago.Models.Enumerations.ChannelType.Normal;
|
||||
//act on
|
||||
await Behaver.Instance.ActOn(m);
|
||||
@ -152,14 +147,14 @@ public class TwitchInterface
|
||||
acc ??= new Account()
|
||||
{
|
||||
IsUser = Rememberer.SearchUser(
|
||||
u => u.Accounts.Any(a => a.ExternalId == username && a.Protocol == PROTOCOL))
|
||||
u => u.Accounts.Any(a => a.ExternalId == username && a.Protocol == Protocol))
|
||||
?? new vassago.Models.User()
|
||||
};
|
||||
|
||||
acc.Username = username;
|
||||
acc.ExternalId = username;
|
||||
//acc.IsBot = false? there is a way to tell, but you have to go back through the API
|
||||
acc.Protocol = PROTOCOL;
|
||||
acc.Protocol = Protocol;
|
||||
acc.SeenInChannel = inChannel;
|
||||
|
||||
// Console.WriteLine($"we asked rememberer to search for acc's user. {acc.IsUser?.Id}");
|
||||
@ -185,7 +180,7 @@ public class TwitchInterface
|
||||
private Channel UpsertChannel(string channelName)
|
||||
{
|
||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == channelName
|
||||
&& ci.Protocol == PROTOCOL);
|
||||
&& ci.Protocol == Protocol);
|
||||
if (c == null)
|
||||
{
|
||||
// Console.WriteLine($"couldn't find channel under protocol {PROTOCOL} with externalId {channelName}");
|
||||
@ -199,11 +194,9 @@ public class TwitchInterface
|
||||
c.ExternalId = channelName;
|
||||
c.ChannelType = vassago.Models.Enumerations.ChannelType.Normal;
|
||||
c.Messages ??= [];
|
||||
c.Protocol = PROTOCOL;
|
||||
c.Protocol = Protocol;
|
||||
c.ParentChannel = protocolAsChannel;
|
||||
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
||||
c.SendMessage = (t) => { return Task.Run(() => { client.SendMessage(channelName, t); }); };
|
||||
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
|
||||
c = Rememberer.RememberChannel(c);
|
||||
|
||||
var selfAccountInChannel = c.Users?.FirstOrDefault(a => a.ExternalId == selfAccountInProtocol.ExternalId);
|
||||
@ -217,7 +210,7 @@ public class TwitchInterface
|
||||
private Channel UpsertDMChannel(string whisperWith)
|
||||
{
|
||||
Channel c = Rememberer.SearchChannel(ci => ci.ExternalId == $"w_{whisperWith}"
|
||||
&& ci.Protocol == PROTOCOL);
|
||||
&& ci.Protocol == Protocol);
|
||||
if (c == null)
|
||||
{
|
||||
// Console.WriteLine($"couldn't find channel under protocol {PROTOCOL}, whisper with {whisperWith}");
|
||||
@ -231,25 +224,9 @@ public class TwitchInterface
|
||||
c.ExternalId = $"w_{whisperWith}";
|
||||
c.ChannelType = vassago.Models.Enumerations.ChannelType.DM;
|
||||
c.Messages ??= [];
|
||||
c.Protocol = PROTOCOL;
|
||||
c.Protocol = Protocol;
|
||||
c.ParentChannel = protocolAsChannel;
|
||||
c.SubChannels = c.SubChannels ?? new List<Channel>();
|
||||
c.SendMessage = (t) =>
|
||||
{
|
||||
return Task.Run(() =>
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
client.SendWhisper(whisperWith, t);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.Error.WriteLine(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
c.SendFile = (f, t) => { throw new InvalidOperationException($"twitch cannot send files"); };
|
||||
c = Rememberer.RememberChannel(c);
|
||||
|
||||
var selfAccountInChannel = c.Users.FirstOrDefault(a => a.ExternalId == selfAccountInProtocol.ExternalId);
|
||||
@ -266,10 +243,10 @@ public class TwitchInterface
|
||||
//none of the features we care about are on it!
|
||||
private Message UpsertMessage(ChatMessage chatMessage)
|
||||
{
|
||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == chatMessage.Id && mi.Protocol == PROTOCOL)
|
||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == chatMessage.Id && mi.Protocol == Protocol)
|
||||
?? new()
|
||||
{
|
||||
Protocol = PROTOCOL,
|
||||
Protocol = Protocol,
|
||||
Timestamp = (DateTimeOffset)DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)
|
||||
};
|
||||
m.Content = chatMessage.Message;
|
||||
@ -277,8 +254,6 @@ public class TwitchInterface
|
||||
m.Channel = UpsertChannel(chatMessage.Channel);
|
||||
m.Author = UpsertAccount(chatMessage.Username, m.Channel);
|
||||
m.MentionsMe = Regex.IsMatch(m.Content?.ToLower(), $"@\\b{selfAccountInProtocol.Username.ToLower()}\\b");
|
||||
m.Reply = (t) => { return Task.Run(() => { client.SendReply(chatMessage.Channel, chatMessage.Id, t); }); };
|
||||
m.React = (e) => { throw new InvalidOperationException($"twitch cannot react"); };
|
||||
Rememberer.RememberMessage(m);
|
||||
return m;
|
||||
}
|
||||
@ -288,11 +263,11 @@ public class TwitchInterface
|
||||
private Message UpsertMessage(WhisperMessage whisperMessage)
|
||||
{
|
||||
//WhisperMessage.Id corresponds to chatMessage.Id. \*eye twitch*
|
||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == whisperMessage.MessageId && mi.Protocol == PROTOCOL)
|
||||
var m = Rememberer.SearchMessage(mi => mi.ExternalId == whisperMessage.MessageId && mi.Protocol == Protocol)
|
||||
?? new()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Protocol = PROTOCOL,
|
||||
Protocol = Protocol,
|
||||
Timestamp = (DateTimeOffset)DateTime.SpecifyKind(DateTime.UtcNow, DateTimeKind.Utc)
|
||||
};
|
||||
m.Content = whisperMessage.Message;
|
||||
@ -300,8 +275,6 @@ public class TwitchInterface
|
||||
m.Channel = UpsertDMChannel(whisperMessage.Username);
|
||||
m.Author = UpsertAccount(whisperMessage.Username, m.Channel);
|
||||
m.MentionsMe = Regex.IsMatch(m.Content?.ToLower(), $"@\\b{selfAccountInProtocol.Username.ToLower()}\\b");
|
||||
m.Reply = (t) => { return Task.Run(() => { client.SendWhisper(whisperMessage.Username, t); }); };
|
||||
m.React = (e) => { throw new InvalidOperationException($"twitch cannot react"); };
|
||||
Rememberer.RememberMessage(m);
|
||||
return m;
|
||||
}
|
||||
@ -317,4 +290,22 @@ public class TwitchInterface
|
||||
client.SendMessage(channelTarget, "o7");
|
||||
client.LeaveChannel(channelTarget);
|
||||
}
|
||||
public override async Task<int> SendMessage(Channel channel, string text)
|
||||
{
|
||||
Task.Run(() => { client.SendMessage(channel.ExternalId, text); });
|
||||
return 200;
|
||||
}
|
||||
public override async Task<int> SendFile(Channel channel, string path, string accompanyingText)
|
||||
{
|
||||
return 405;
|
||||
}
|
||||
public override async Task<int> React(Message message, string reaction)
|
||||
{
|
||||
return 405;
|
||||
}
|
||||
public override async Task<int> Reply(Message message, string text)
|
||||
{
|
||||
Task.Run(() => { client.SendReply(message.Channel.ExternalId, message.ExternalId, text); });
|
||||
return 200;
|
||||
}
|
||||
}
|
||||
|
@ -124,14 +124,14 @@ public static class Rememberer
|
||||
{
|
||||
if (toForget.SubChannels?.Count > 0)
|
||||
{
|
||||
foreach (var childChannel in toForget.SubChannels)
|
||||
foreach (var childChannel in toForget.SubChannels.ToList())
|
||||
{
|
||||
ForgetChannel(childChannel);
|
||||
}
|
||||
}
|
||||
if(toForget.Users?.Count > 0)
|
||||
{
|
||||
foreach(var account in toForget.Users)
|
||||
foreach(var account in toForget.Users.ToList())
|
||||
{
|
||||
ForgetAccount(account);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ namespace vassago;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using vassago.Models;
|
||||
|
||||
using vassago.ProtocolInterfaces;
|
||||
|
||||
public static class Shared
|
||||
{
|
||||
@ -12,4 +12,5 @@ public static class Shared
|
||||
public static HttpClient HttpClient { get; internal set; } = new HttpClient();
|
||||
public static bool SetupSlashCommands { get; set; }
|
||||
public static Uri API_URL {get;set;}
|
||||
public static List<ProtocolInterface> ProtocolList { get; set; } = new();
|
||||
}
|
||||
|
@ -20,7 +20,11 @@ public class ChannelsController() : Controller
|
||||
//but that would take in all the messages.
|
||||
//realistically I expect this will have less than 1MB of total "channels", and several GB of total messages per (text) channel.
|
||||
|
||||
var channel = allChannels.First(u => u.Id == id);
|
||||
var channel = allChannels.FirstOrDefault(u => u.Id == id);
|
||||
if(channel == null)
|
||||
{
|
||||
return Problem("couldn't find that channle");
|
||||
}
|
||||
var walker = channel;
|
||||
while(walker != null)
|
||||
{
|
||||
@ -58,4 +62,4 @@ public class ChannelsController() : Controller
|
||||
{
|
||||
return View(new ErrorPageViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,45 @@
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using vassago.Models;
|
||||
using vassago.ProtocolInterfaces.DiscordInterface;
|
||||
|
||||
namespace vassago.Controllers.api;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class InternalAPIProtocolController : ControllerBase
|
||||
{
|
||||
private readonly ILogger<InternalAPIProtocolController> _logger;
|
||||
|
||||
public InternalAPIProtocolController(ILogger<InternalAPIProtocolController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public class extraSpecialObjectReadGlorifiedTupleFor_PostMessage
|
||||
{
|
||||
public string messageText;
|
||||
public Guid channelId;
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("PostMessage")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult PostMessage([FromBody]extraSpecialObjectReadGlorifiedTupleFor_PostMessage param)
|
||||
{
|
||||
return StatusCode(Behaver.Instance.SendMessage(param.channelId, param.messageText).Result);
|
||||
}
|
||||
public class extraSpecialObjectReadGlorifiedTupleFor_ReplyToMessage
|
||||
{
|
||||
public string messageText;
|
||||
public Guid repliedMessageId;
|
||||
}
|
||||
[HttpPost]
|
||||
[Route("ReplyToMessage")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult ReplyToMessage([FromBody] extraSpecialObjectReadGlorifiedTupleFor_ReplyToMessage param)
|
||||
{
|
||||
Console.WriteLine("ReplyToMessage - ${param.repliedMessageId}, {param.messageText}");
|
||||
return StatusCode(Behaver.Instance.Reply(param.repliedMessageId, param.messageText).Result);
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ public class RemembererController : ControllerBase
|
||||
return Rememberer.AttachmentDetail(id);
|
||||
}
|
||||
[HttpPut]
|
||||
[Route("Channel")]
|
||||
[Route("Channels")]
|
||||
[Produces("application/json")]
|
||||
public Channel CreateChannel(Guid id)
|
||||
{
|
||||
@ -75,7 +75,7 @@ public class RemembererController : ControllerBase
|
||||
return Rememberer.AttachmentDetail(id);
|
||||
}
|
||||
[HttpGet]
|
||||
[Route("Channel")]
|
||||
[Route("Channels")]
|
||||
[Produces("application/json")]
|
||||
public Channel GetChannel(Guid id)
|
||||
{
|
||||
@ -104,7 +104,7 @@ public class RemembererController : ControllerBase
|
||||
}
|
||||
//Update
|
||||
[HttpPatch]
|
||||
[Route("Channel")]
|
||||
[Route("Channels")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult Patch([FromBody] Channel channel)
|
||||
{
|
||||
@ -154,21 +154,23 @@ public class RemembererController : ControllerBase
|
||||
return Ok();
|
||||
}
|
||||
[HttpDelete]
|
||||
[Route("Channel")]
|
||||
[Route("Channels/{id}")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult DeleteChannel(Guid id)
|
||||
{
|
||||
var fromDb = Rememberer.ChannelDetail(id);
|
||||
_logger.LogDebug($"delete channel {id}");
|
||||
if (fromDb == null)
|
||||
{
|
||||
_logger.LogError($"attempt to delete channel {id}, not found");
|
||||
return NotFound();
|
||||
}
|
||||
Rememberer.ForgetChannel(fromDb);
|
||||
_logger.LogDebug($"delete channel {id} success");
|
||||
return Ok();
|
||||
}
|
||||
[HttpDelete]
|
||||
[Route("Message")]
|
||||
[Route("Message/{id}")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult DeleteMessage(Guid id)
|
||||
{
|
||||
@ -182,7 +184,7 @@ public class RemembererController : ControllerBase
|
||||
return Ok();
|
||||
}
|
||||
[HttpDelete]
|
||||
[Route("UAC")]
|
||||
[Route("UAC/{id}")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult DeleteUAC(Guid id)
|
||||
{
|
||||
@ -196,7 +198,7 @@ public class RemembererController : ControllerBase
|
||||
return Ok();
|
||||
}
|
||||
[HttpDelete]
|
||||
[Route("User")]
|
||||
[Route("User/{id}")]
|
||||
[Produces("application/json")]
|
||||
public IActionResult DeleteUser(Guid id)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@
|
||||
<tr>
|
||||
<th scope="row">Lewdness Filter Level</th>
|
||||
<td>
|
||||
<select name="LewdnessFilterLevel" id="LewdnessFilterLevel" onchange="patchModel(jsonifyChannel(), '/api/Channels/')">
|
||||
<select name="LewdnessFilterLevel" id="LewdnessFilterLevel" onchange="patchModel(jsonifyChannel())">
|
||||
<!option value="" @(ThisChannel.LewdnessFilterLevel == null ? "selected" : "")>⤵ inherited - @Enumerations.GetDescription(IfInheritedLewdnessFilterLevel)</!option>
|
||||
@foreach (Enumerations.LewdnessFilterLevel enumVal in
|
||||
Enum.GetValues(typeof(Enumerations.LewdnessFilterLevel)))
|
||||
@ -54,7 +54,7 @@
|
||||
<tr>
|
||||
<th scope="row">Meanness Filter Level</th>
|
||||
<td>
|
||||
<select name="MeannessFilterLevel" id="MeannessFilterLevel" onchange="patchModel(jsonifyChannel(), '/api/Channels/')">
|
||||
<select name="MeannessFilterLevel" id="MeannessFilterLevel" onchange="patchModel(jsonifyChannel())">
|
||||
<!option value="" @(ThisChannel.MeannessFilterLevel == null ? "selected" : "")>⤵ inherited - @Enumerations.GetDescription(IfInheritedMeannessFilterLevel)</!option>
|
||||
@foreach (Enumerations.MeannessFilterLevel enumVal in
|
||||
Enum.GetValues(typeof(Enumerations.MeannessFilterLevel)))
|
||||
@ -135,7 +135,7 @@
|
||||
function forget(){
|
||||
console.log("here we go");
|
||||
if(window.confirm("delete? really really?") == true){
|
||||
deleteModel(jsonifyChannel(), '/api/Channels/');
|
||||
deleteModel(jsonifyChannel().Id, window.history.back);
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@
|
||||
var sb = new StringBuilder();
|
||||
sb.Append("[{text: \"accounts\", \"expanded\":true, nodes: [");
|
||||
var first = true;
|
||||
foreach (var acc in ThisChannel.Users.OrderBy(a => a.SeenInChannel.LineageSummary))
|
||||
foreach (var acc in ThisChannel.Users?.OrderBy(a => a?.SeenInChannel?.LineageSummary))
|
||||
{
|
||||
if(!first)
|
||||
sb.Append(',');
|
||||
@ -166,4 +166,4 @@
|
||||
$('#accountsTree').bstreeview({ data: accountsTree() });
|
||||
|
||||
</script>
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
<tr>
|
||||
<th scope="row">Display Name (here)</th>
|
||||
<td><input type="text" id="displayName" value="@Model.DisplayName" disabled alt="todo"></input> <button
|
||||
onclick="patchModel(jsonifyUser(), @Html.Raw("'/api/Users/'"))" disabled alt"todo">update</button></td>
|
||||
onclick="patchModel(jsonifyUser())" disabled alt"todo">update</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">Accounts</th>
|
||||
@ -54,12 +54,12 @@
|
||||
}
|
||||
sb.Append("]}]");
|
||||
}
|
||||
console.log(@Html.Raw(sb.ToString()));
|
||||
console.log(@Html.Raw(sb.ToString()));
|
||||
var tree = @Html.Raw(sb.ToString());
|
||||
return tree;
|
||||
}
|
||||
|
||||
$('#accountsTree').bstreeview({ data: getAccountsTree() });
|
||||
document.querySelectorAll("input[type=checkbox]").forEach(node => { node.onchange = () => { patchModel(jsonifyUser(), '/api/Users/') } });
|
||||
document.querySelectorAll("input[type=checkbox]").forEach(node => { node.onchange = () => { patchModel(jsonifyUser()) } });
|
||||
</script>
|
||||
}
|
||||
|
@ -3,7 +3,11 @@
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<NoWarn>$(NoWarn);CA2254</NoWarn>
|
||||
<NoWarn>$(NoWarn);CS1998;CS4014</NoWarn>
|
||||
<!-- CS1998: "This async method lacks 'await' operators and will run synchronously." -->
|
||||
<!-- CS4014: "Because this call is not awaited, execution of the current method continues before the call is completed."-->
|
||||
<!-- those 2 cancel out. Async foo calls async Bar, foo doesn't say "await" so cs1998 says "well don't mark foo as async" and cs4014 says "you should awake bar".
|
||||
what, you want me to just add bar to some big stupid task list that I don't care about anyway? -->
|
||||
</PropertyGroup>
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ function Account(displayName, accountId, protocol){
|
||||
//todo: figure out what the URL actually needs to be, rather than assuming you get a whole-ass server to yourself.
|
||||
//you selfish fuck... What are you, fox?
|
||||
//as it stands, you want something like /api/Channels/, trailing slash intentional
|
||||
function patchModel(model, deprecated_apiUrl)
|
||||
function patchModel(model, callback)
|
||||
{
|
||||
//structure the model your (dang) self into a nice object
|
||||
console.log(model);
|
||||
@ -22,7 +22,7 @@ function patchModel(model, deprecated_apiUrl)
|
||||
// var id=components[3];
|
||||
|
||||
console.log(JSON.stringify(model));
|
||||
fetch(apiUrl + type + '/', {
|
||||
fetch(apiUrl + 'Rememberer/' + type + '/', {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
@ -44,22 +44,17 @@ function patchModel(model, deprecated_apiUrl)
|
||||
});
|
||||
}
|
||||
|
||||
function deleteModel(model, deprecated_apiUrl)
|
||||
function deleteModel(id, callback)
|
||||
{
|
||||
var components = window.location.pathname.split('/');
|
||||
// if(components[2] !== "Details")
|
||||
// {
|
||||
// console.log("wtf are you doing? " + components[2] + " is something other than Details");
|
||||
// }
|
||||
var type=components[1];
|
||||
let result = null;
|
||||
// var id=components[3];
|
||||
fetch(apiUrl + type + '/', {
|
||||
var id=components[3];
|
||||
fetch(apiUrl + 'Rememberer/' + type + '/' + id, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(model),
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
|
Loading…
Reference in New Issue
Block a user