diff --git a/Behaver.cs b/Behaver.cs
index 6cb6d23..10b2da0 100644
--- a/Behaver.cs
+++ b/Behaver.cs
@@ -1,7 +1,7 @@
namespace vassago;
-#pragma warning disable 4014
+#pragma warning disable 4014 //the "not awaited" error
using gray_messages.chat;
-using franz;//the "not awaited" error
+using franz;
using vassago.Behavior;
using vassago.Models;
using System;
diff --git a/Behavior/TwitchSummon.cs b/Behavior/TwitchSummon.cs
index ea5a0da..3e9521b 100644
--- a/Behavior/TwitchSummon.cs
+++ b/Behavior/TwitchSummon.cs
@@ -17,14 +17,16 @@ public class TwitchSummon : Behavior
public TwitchSummon()
{
myUAC = Rememberer.SearchUAC(uac => uac.OwnerId == uacID);
- if(myUAC == null)
+ if (myUAC == null)
{
myUAC = new()
{
OwnerId = uacID,
- DisplayName = Name
+ DisplayName = Name,
+ Description = @"matching this means you can summon the bot to any twitch channel"
};
}
+ Rememberer.RememberUAC(myUAC);
}
public override bool ShouldAct(Message message)
{
@@ -44,7 +46,7 @@ public class TwitchSummon : Behavior
public override async Task ActOn(Message message)
{
var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
- if(ti != null)
+ if (ti != null)
{
var channelTarget = message.Content.Substring(message.Content.IndexOf(Trigger) + Trigger.Length + 1).Trim();
await message.Channel.SendMessage(ti.AttemptJoin(channelTarget));
@@ -55,4 +57,44 @@ public class TwitchSummon : Behavior
}
return true;
}
+ [StaticPlz]
+ public class TwitchDismiss : Behavior
+ {
+ public override string Name => "Twitch Dismiss";
+
+ public override string Trigger => "begone, @[me]";
+
+ public override bool ShouldAct(Message message)
+ {
+ var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
+ // 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 ActOn(Message message)
+ {
+ 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 :(");
+ }
+ return true;
+ }
+ }
}
diff --git a/Behavior/TwitchUnsummon.cs b/Behavior/TwitchUnsummon.cs
deleted file mode 100644
index d6e336b..0000000
--- a/Behavior/TwitchUnsummon.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-namespace vassago.Behavior;
-
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using vassago.Models;
-
-[StaticPlz]
-public class TwitchDismiss : Behavior
-{
- public override string Name => "Twitch Dismiss";
-
- public override string Trigger => "begone, @[me]";
-
- public override bool ShouldAct(Message message)
- {
- var ti = ProtocolInterfaces.ProtocolList.twitchs.FirstOrDefault();
- // 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 ActOn(Message message)
- {
- 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 :(");
- }
- return true;
- }
-}
diff --git a/Behavior/Webhook.cs b/Behavior/Webhook.cs
index 575f121..e91dc08 100644
--- a/Behavior/Webhook.cs
+++ b/Behavior/Webhook.cs
@@ -36,14 +36,17 @@ public class Webhook : Behavior
{
Console.WriteLine($"{kvp[0]}: {kvp[1]}");
}
+ var changed = false;
var myUAC = Rememberer.SearchUAC(uac => uac.OwnerId == conf.uacID);
if (myUAC == null)
{
myUAC = new()
{
OwnerId = conf.uacID,
- DisplayName = confName
+ DisplayName = confName,
+ Description = conf.Description
};
+ changed = true;
Rememberer.RememberUAC(myUAC);
}
else
@@ -51,9 +54,16 @@ public class Webhook : Behavior
if (myUAC.DisplayName != confName)
{
myUAC.DisplayName = confName;
- Rememberer.RememberUAC(myUAC);
+ changed = true;
+ }
+ if (myUAC.Description != conf.Description)
+ {
+ myUAC.Description = conf.Description;
+ changed = true;
}
}
+ if (changed)
+ Rememberer.RememberUAC(myUAC);
}
}
@@ -160,7 +170,7 @@ public class Webhook : Behavior
}
private string translate(WebhookActionOrder actionOrder, Message message)
{
- if(string.IsNullOrWhiteSpace(actionOrder.Conf.Content))
+ if (string.IsNullOrWhiteSpace(actionOrder.Conf.Content))
return "";
var msgContent = actionOrder.Conf.Content.Replace("{text}", actionOrder.webhookContent);
msgContent = msgContent.Replace("{msgid}", message.Id.ToString());
@@ -179,6 +189,7 @@ public class WebhookConf
public Enumerations.HttpVerb Method { get; set; }
public List> Headers { get; set; }
public string Content { get; set; }
+ public string Description { get; set; }
}
public class WebhookActionOrder
{
diff --git a/Migrations/20250523181842_channelAliases.Designer.cs b/Migrations/20250523181842_channelAliases.Designer.cs
new file mode 100644
index 0000000..dcb88fc
--- /dev/null
+++ b/Migrations/20250523181842_channelAliases.Designer.cs
@@ -0,0 +1,386 @@
+//
+using System;
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using vassago.Models;
+
+#nullable disable
+
+namespace vassago.Migrations
+{
+ [DbContext(typeof(ChattingContext))]
+ [Migration("20250523181842_channelAliases")]
+ partial class channelAliases
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore");
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("AccountUAC", b =>
+ {
+ b.Property("AccountInChannelsId")
+ .HasColumnType("uuid");
+
+ b.Property("UACsId")
+ .HasColumnType("uuid");
+
+ b.HasKey("AccountInChannelsId", "UACsId");
+
+ b.HasIndex("UACsId");
+
+ b.ToTable("AccountUAC");
+ });
+
+ modelBuilder.Entity("ChannelUAC", b =>
+ {
+ b.Property("ChannelsId")
+ .HasColumnType("uuid");
+
+ b.Property("UACsId")
+ .HasColumnType("uuid");
+
+ b.HasKey("ChannelsId", "UACsId");
+
+ b.HasIndex("UACsId");
+
+ b.ToTable("ChannelUAC");
+ });
+
+ modelBuilder.Entity("UACUser", b =>
+ {
+ b.Property("UACsId")
+ .HasColumnType("uuid");
+
+ b.Property("UsersId")
+ .HasColumnType("uuid");
+
+ b.HasKey("UACsId", "UsersId");
+
+ b.HasIndex("UsersId");
+
+ b.ToTable("UACUser");
+ });
+
+ modelBuilder.Entity("vassago.Models.Account", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DisplayName")
+ .HasColumnType("text");
+
+ b.Property("ExternalId")
+ .HasColumnType("text");
+
+ b.Property("IsBot")
+ .HasColumnType("boolean");
+
+ b.Property("IsUserId")
+ .HasColumnType("uuid");
+
+ b.Property("Protocol")
+ .HasColumnType("text");
+
+ b.Property("SeenInChannelId")
+ .HasColumnType("uuid");
+
+ b.Property("Username")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("IsUserId");
+
+ b.HasIndex("SeenInChannelId");
+
+ b.ToTable("Accounts");
+ });
+
+ modelBuilder.Entity("vassago.Models.Attachment", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Content")
+ .HasColumnType("bytea");
+
+ b.Property("ContentType")
+ .HasColumnType("text");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("ExternalId")
+ .HasColumnType("numeric(20,0)");
+
+ b.Property("Filename")
+ .HasColumnType("text");
+
+ b.Property("MessageId")
+ .HasColumnType("uuid");
+
+ b.Property("Size")
+ .HasColumnType("integer");
+
+ b.Property("Source")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MessageId");
+
+ b.ToTable("Attachments");
+ });
+
+ modelBuilder.Entity("vassago.Models.Channel", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property>("Aliases")
+ .HasColumnType("hstore");
+
+ b.Property("ChannelType")
+ .HasColumnType("integer");
+
+ b.Property("DisplayName")
+ .HasColumnType("text");
+
+ b.Property("ExternalId")
+ .HasColumnType("text");
+
+ b.Property("LewdnessFilterLevel")
+ .HasColumnType("integer");
+
+ b.Property("LinksAllowed")
+ .HasColumnType("boolean");
+
+ b.Property("MaxAttachmentBytes")
+ .HasColumnType("numeric(20,0)");
+
+ b.Property("MaxTextChars")
+ .HasColumnType("bigint");
+
+ b.Property("MeannessFilterLevel")
+ .HasColumnType("integer");
+
+ b.Property("ParentChannelId")
+ .HasColumnType("uuid");
+
+ b.Property("Protocol")
+ .HasColumnType("text");
+
+ b.Property("ReactionsPossible")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ParentChannelId");
+
+ b.ToTable("Channels");
+ });
+
+ modelBuilder.Entity("vassago.Models.Message", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ActedOn")
+ .HasColumnType("boolean");
+
+ b.Property("AuthorId")
+ .HasColumnType("uuid");
+
+ b.Property("ChannelId")
+ .HasColumnType("uuid");
+
+ b.Property("Content")
+ .HasColumnType("text");
+
+ b.Property("ExternalId")
+ .HasColumnType("text");
+
+ b.Property("MentionsMe")
+ .HasColumnType("boolean");
+
+ b.Property("Protocol")
+ .HasColumnType("text");
+
+ b.Property("Timestamp")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AuthorId");
+
+ b.HasIndex("ChannelId");
+
+ b.ToTable("Messages");
+ });
+
+ modelBuilder.Entity("vassago.Models.UAC", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("DisplayName")
+ .HasColumnType("text");
+
+ b.Property("OwnerId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.ToTable("UACs");
+ });
+
+ modelBuilder.Entity("vassago.Models.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.ToTable("Users");
+ });
+
+ modelBuilder.Entity("AccountUAC", b =>
+ {
+ b.HasOne("vassago.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("AccountInChannelsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("vassago.Models.UAC", null)
+ .WithMany()
+ .HasForeignKey("UACsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("ChannelUAC", b =>
+ {
+ b.HasOne("vassago.Models.Channel", null)
+ .WithMany()
+ .HasForeignKey("ChannelsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("vassago.Models.UAC", null)
+ .WithMany()
+ .HasForeignKey("UACsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("UACUser", b =>
+ {
+ b.HasOne("vassago.Models.UAC", null)
+ .WithMany()
+ .HasForeignKey("UACsId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("vassago.Models.User", null)
+ .WithMany()
+ .HasForeignKey("UsersId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("vassago.Models.Account", b =>
+ {
+ b.HasOne("vassago.Models.User", "IsUser")
+ .WithMany("Accounts")
+ .HasForeignKey("IsUserId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.HasOne("vassago.Models.Channel", "SeenInChannel")
+ .WithMany("Users")
+ .HasForeignKey("SeenInChannelId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("IsUser");
+
+ b.Navigation("SeenInChannel");
+ });
+
+ modelBuilder.Entity("vassago.Models.Attachment", b =>
+ {
+ b.HasOne("vassago.Models.Message", "Message")
+ .WithMany("Attachments")
+ .HasForeignKey("MessageId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("Message");
+ });
+
+ modelBuilder.Entity("vassago.Models.Channel", b =>
+ {
+ b.HasOne("vassago.Models.Channel", "ParentChannel")
+ .WithMany("SubChannels")
+ .HasForeignKey("ParentChannelId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("ParentChannel");
+ });
+
+ modelBuilder.Entity("vassago.Models.Message", b =>
+ {
+ b.HasOne("vassago.Models.Account", "Author")
+ .WithMany()
+ .HasForeignKey("AuthorId");
+
+ b.HasOne("vassago.Models.Channel", "Channel")
+ .WithMany("Messages")
+ .HasForeignKey("ChannelId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ b.Navigation("Author");
+
+ b.Navigation("Channel");
+ });
+
+ modelBuilder.Entity("vassago.Models.Channel", b =>
+ {
+ b.Navigation("Messages");
+
+ b.Navigation("SubChannels");
+
+ b.Navigation("Users");
+ });
+
+ modelBuilder.Entity("vassago.Models.Message", b =>
+ {
+ b.Navigation("Attachments");
+ });
+
+ modelBuilder.Entity("vassago.Models.User", b =>
+ {
+ b.Navigation("Accounts");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/Migrations/20250523181842_channelAliases.cs b/Migrations/20250523181842_channelAliases.cs
new file mode 100644
index 0000000..5bb25e7
--- /dev/null
+++ b/Migrations/20250523181842_channelAliases.cs
@@ -0,0 +1,45 @@
+using System.Collections.Generic;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace vassago.Migrations
+{
+ ///
+ public partial class channelAliases : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterDatabase()
+ .Annotation("Npgsql:PostgresExtension:hstore", ",,");
+
+ migrationBuilder.AddColumn(
+ name: "Description",
+ table: "UACs",
+ type: "text",
+ nullable: true);
+
+ migrationBuilder.AddColumn>(
+ name: "Aliases",
+ table: "Channels",
+ type: "hstore",
+ nullable: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "Description",
+ table: "UACs");
+
+ migrationBuilder.DropColumn(
+ name: "Aliases",
+ table: "Channels");
+
+ migrationBuilder.AlterDatabase()
+ .OldAnnotation("Npgsql:PostgresExtension:hstore", ",,");
+ }
+ }
+}
diff --git a/Migrations/ChattingContextModelSnapshot.cs b/Migrations/ChattingContextModelSnapshot.cs
index 15593f0..505991b 100644
--- a/Migrations/ChattingContextModelSnapshot.cs
+++ b/Migrations/ChattingContextModelSnapshot.cs
@@ -1,5 +1,6 @@
//
using System;
+using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
@@ -20,6 +21,7 @@ namespace vassago.Migrations
.HasAnnotation("ProductVersion", "7.0.5")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
+ NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "hstore");
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("AccountUAC", b =>
@@ -146,6 +148,9 @@ namespace vassago.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
+ b.Property>("Aliases")
+ .HasColumnType("hstore");
+
b.Property("ChannelType")
.HasColumnType("integer");
@@ -231,6 +236,9 @@ namespace vassago.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("uuid");
+ b.Property("Description")
+ .HasColumnType("text");
+
b.Property("DisplayName")
.HasColumnType("text");
diff --git a/Models/Channel.cs b/Models/Channel.cs
index d51f7dc..de9bbdc 100644
--- a/Models/Channel.cs
+++ b/Models/Channel.cs
@@ -25,7 +25,7 @@ public class Channel
public List Messages { get; set; }
[DeleteBehavior(DeleteBehavior.Cascade)]
public List Users { get; set; }
- public ChannelType ChannelType {get; set; }
+ public ChannelType ChannelType { get; set; }
//Permissions
public ulong? MaxAttachmentBytes { get; set; }
@@ -34,8 +34,9 @@ public class Channel
public bool? ReactionsPossible { get; set; }
public Enumerations.LewdnessFilterLevel? LewdnessFilterLevel { get; set; }
public Enumerations.MeannessFilterLevel? MeannessFilterLevel { get; set; }
-
public List UACs { get; set; }
+ //both incoming and outgoing
+ //public Dictionary Aliases { get; set; }
[NonSerialized]
public Func SendFile;
@@ -51,14 +52,14 @@ public class Channel
var path = new Stack(); //omg i actually get to use a data structure from university
var walker = this;
path.Push(this);
- while(walker.ParentChannel != null)
+ while (walker.ParentChannel != null)
{
walker = walker.ParentChannel;
path.Push(walker);
}
DefinitePermissionSettings toReturn = new DefinitePermissionSettings();
-
- while(path.Count > 0)
+
+ while (path.Count > 0)
{
walker = path.Pop();
toReturn.LewdnessFilterLevel = walker.LewdnessFilterLevel ?? toReturn.LewdnessFilterLevel;
@@ -76,7 +77,7 @@ public class Channel
{
get
{
- if(this.ParentChannel != null)
+ if (this.ParentChannel != null)
{
return this.ParentChannel.LineageSummary + '/' + this.DisplayName;
}
@@ -94,7 +95,7 @@ public class Channel
{
var toReturn = this.MemberwiseClone() as Channel;
toReturn.ParentChannel = null;
- if(toReturn.Users?.Count > 0)
+ if (toReturn.Users?.Count > 0)
{
foreach (var account in toReturn.Users)
{
diff --git a/appsettings.json b/appsettings.json
index 35fb96e..de251d1 100644
--- a/appsettings.json
+++ b/appsettings.json
@@ -19,7 +19,13 @@
{
"uacID": "9a94855a-e5a2-43b5-8420-ce670472ce95",
"Trigger": "test",
- "Uri": "http://localhost"
+ "Description": "test",
+ "Uri": "http://localhost",
+ "Method": "POST",
+ "Headers": [
+ ["Content-Type", "application/json"]
+ ],
+ "Content": "{\"content\": \"Hello, this is a message from my webhook: {text}. username: {account}, user: {user}\"}"
}
],
"KafkaBootstrap":"http://localhost:9092",