diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..add57be
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+bin/
+obj/
+/packages/
+riderModule.iml
+/_ReSharper.Caches/
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..21c26b7
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "LibMatrix"]
+ path = LibMatrix
+ url = https://cgit.rory.gay/matrix/LibMatrix.git
diff --git a/.idea/.idea.MatrixInviteLogger/.idea/.gitignore b/.idea/.idea.MatrixInviteLogger/.idea/.gitignore
new file mode 100644
index 0000000..60697e7
--- /dev/null
+++ b/.idea/.idea.MatrixInviteLogger/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/contentModel.xml
+/projectSettingsUpdater.xml
+/.idea.MatrixInviteLogger.iml
+/modules.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.idea.MatrixInviteLogger/.idea/encodings.xml b/.idea/.idea.MatrixInviteLogger/.idea/encodings.xml
new file mode 100644
index 0000000..df87cf9
--- /dev/null
+++ b/.idea/.idea.MatrixInviteLogger/.idea/encodings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
+</project>
\ No newline at end of file
diff --git a/.idea/.idea.MatrixInviteLogger/.idea/indexLayout.xml b/.idea/.idea.MatrixInviteLogger/.idea/indexLayout.xml
new file mode 100644
index 0000000..7b08163
--- /dev/null
+++ b/.idea/.idea.MatrixInviteLogger/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="UserContentModel">
+ <attachedFolders />
+ <explicitIncludes />
+ <explicitExcludes />
+ </component>
+</project>
\ No newline at end of file
diff --git a/.idea/.idea.MatrixInviteLogger/.idea/vcs.xml b/.idea/.idea.MatrixInviteLogger/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/.idea.MatrixInviteLogger/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
+ </component>
+</project>
\ No newline at end of file
diff --git a/LibMatrix b/LibMatrix
new file mode 160000
+Subproject 08b552fc3ad6e81d8ebddc238043681da90673b
diff --git a/MatrixInviteLogger.sln b/MatrixInviteLogger.sln
new file mode 100644
index 0000000..a97dae9
--- /dev/null
+++ b/MatrixInviteLogger.sln
@@ -0,0 +1,308 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MatrixInviteLogger", "MatrixInviteLogger\MatrixInviteLogger.csproj", "{876AA01B-0F3F-4954-8C57-27A8540504EE}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LibMatrix", "LibMatrix", "{6C4179B9-BFAA-0403-502F-9DAF28C26A6E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ArcaneLibs", "ArcaneLibs", "{17E2FB3F-0F61-3CDC-2874-2686F1726316}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs", "LibMatrix\ArcaneLibs\ArcaneLibs\ArcaneLibs.csproj", "{F3D13E8E-EDFF-4407-9442-9963C61D9EFF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.Blazor.Components", "LibMatrix\ArcaneLibs\ArcaneLibs.Blazor.Components\ArcaneLibs.Blazor.Components.csproj", "{164E2865-D5CF-48CF-9036-CD70B945BE82}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.Legacy", "LibMatrix\ArcaneLibs\ArcaneLibs.Legacy\ArcaneLibs.Legacy.csproj", "{9085E25B-2C3D-487E-9B52-304CAE2F88B8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.Logging", "LibMatrix\ArcaneLibs\ArcaneLibs.Logging\ArcaneLibs.Logging.csproj", "{5D0041E0-FEB3-460F-90FA-AE50173D8EE6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.StringNormalisation", "LibMatrix\ArcaneLibs\ArcaneLibs.StringNormalisation\ArcaneLibs.StringNormalisation.csproj", "{F98BECAE-E25F-436E-8D69-F00E83164E13}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.Tests", "LibMatrix\ArcaneLibs\ArcaneLibs.Tests\ArcaneLibs.Tests.csproj", "{7CF6BBC9-2176-452A-A55F-A315F611923A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.Timings", "LibMatrix\ArcaneLibs\ArcaneLibs.Timings\ArcaneLibs.Timings.csproj", "{C1F04A37-F946-4AA9-872D-A38A289F41BE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArcaneLibs.UsageTest", "LibMatrix\ArcaneLibs\ArcaneLibs.UsageTest\ArcaneLibs.UsageTest.csproj", "{545A47FC-6BAA-4C92-BAD1-C1ED413077BC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.EventTypes", "LibMatrix\LibMatrix.EventTypes\LibMatrix.EventTypes.csproj", "{59745535-3681-423D-AE8F-5C08D4671ADC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix", "LibMatrix\LibMatrix\LibMatrix.csproj", "{6FE1B566-08DF-4BC0-AC2F-F9176AA17087}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.Tests", "LibMatrix\Tests\LibMatrix.Tests\LibMatrix.Tests.csproj", "{F04E9976-C303-4DEA-AA8D-EEDE6DF44069}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.DebugDataValidationApi", "LibMatrix\Utilities\LibMatrix.DebugDataValidationApi\LibMatrix.DebugDataValidationApi.csproj", "{A61BAD5E-77AC-49A0-8028-5E84EF990987}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.DevTestBot", "LibMatrix\Utilities\LibMatrix.DevTestBot\LibMatrix.DevTestBot.csproj", "{E6F92ED7-6EE2-4D71-8962-15613CD379BC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.E2eeTestKit", "LibMatrix\Utilities\LibMatrix.E2eeTestKit\LibMatrix.E2eeTestKit.csproj", "{3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.HomeserverEmulator", "LibMatrix\Utilities\LibMatrix.HomeserverEmulator\LibMatrix.HomeserverEmulator.csproj", "{272B0A44-B985-47FF-8C93-32A77F5919C9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.JsonSerializerContextGenerator", "LibMatrix\Utilities\LibMatrix.JsonSerializerContextGenerator\LibMatrix.JsonSerializerContextGenerator.csproj", "{D852D486-F1DA-48A6-BBAF-43FF3396527D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.TestDataGenerator", "LibMatrix\Utilities\LibMatrix.TestDataGenerator\LibMatrix.TestDataGenerator.csproj", "{6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibMatrix.Utilities.Bot", "LibMatrix\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj", "{E526424D-ADC7-41DB-AD63-E359AC2954D9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Debug|x64.Build.0 = Debug|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Debug|x86.Build.0 = Debug|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Release|x64.ActiveCfg = Release|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Release|x64.Build.0 = Release|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Release|x86.ActiveCfg = Release|Any CPU
+ {876AA01B-0F3F-4954-8C57-27A8540504EE}.Release|x86.Build.0 = Release|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Debug|x64.Build.0 = Debug|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Debug|x86.Build.0 = Debug|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Release|x64.ActiveCfg = Release|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Release|x64.Build.0 = Release|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Release|x86.ActiveCfg = Release|Any CPU
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF}.Release|x86.Build.0 = Release|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Debug|x64.Build.0 = Debug|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Debug|x86.Build.0 = Debug|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Release|Any CPU.Build.0 = Release|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Release|x64.ActiveCfg = Release|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Release|x64.Build.0 = Release|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Release|x86.ActiveCfg = Release|Any CPU
+ {164E2865-D5CF-48CF-9036-CD70B945BE82}.Release|x86.Build.0 = Release|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Debug|x64.Build.0 = Debug|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Debug|x86.Build.0 = Debug|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Release|x64.ActiveCfg = Release|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Release|x64.Build.0 = Release|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Release|x86.ActiveCfg = Release|Any CPU
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8}.Release|x86.Build.0 = Release|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Debug|x64.Build.0 = Debug|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Debug|x86.Build.0 = Debug|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Release|x64.ActiveCfg = Release|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Release|x64.Build.0 = Release|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Release|x86.ActiveCfg = Release|Any CPU
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6}.Release|x86.Build.0 = Release|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Debug|x64.Build.0 = Debug|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Debug|x86.Build.0 = Debug|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Release|x64.ActiveCfg = Release|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Release|x64.Build.0 = Release|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Release|x86.ActiveCfg = Release|Any CPU
+ {F98BECAE-E25F-436E-8D69-F00E83164E13}.Release|x86.Build.0 = Release|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Debug|x64.Build.0 = Debug|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Debug|x86.Build.0 = Debug|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Release|x64.ActiveCfg = Release|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Release|x64.Build.0 = Release|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Release|x86.ActiveCfg = Release|Any CPU
+ {7CF6BBC9-2176-452A-A55F-A315F611923A}.Release|x86.Build.0 = Release|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Debug|x64.Build.0 = Debug|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Debug|x86.Build.0 = Debug|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Release|x64.ActiveCfg = Release|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Release|x64.Build.0 = Release|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Release|x86.ActiveCfg = Release|Any CPU
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE}.Release|x86.Build.0 = Release|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Debug|x64.Build.0 = Debug|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Debug|x86.Build.0 = Debug|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Release|x64.ActiveCfg = Release|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Release|x64.Build.0 = Release|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Release|x86.ActiveCfg = Release|Any CPU
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC}.Release|x86.Build.0 = Release|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Debug|x64.Build.0 = Debug|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Debug|x86.Build.0 = Debug|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Release|x64.ActiveCfg = Release|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Release|x64.Build.0 = Release|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Release|x86.ActiveCfg = Release|Any CPU
+ {59745535-3681-423D-AE8F-5C08D4671ADC}.Release|x86.Build.0 = Release|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Debug|x64.Build.0 = Debug|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Debug|x86.Build.0 = Debug|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Release|x64.ActiveCfg = Release|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Release|x64.Build.0 = Release|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Release|x86.ActiveCfg = Release|Any CPU
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087}.Release|x86.Build.0 = Release|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Debug|x64.Build.0 = Debug|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Debug|x86.Build.0 = Debug|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Release|x64.ActiveCfg = Release|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Release|x64.Build.0 = Release|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Release|x86.ActiveCfg = Release|Any CPU
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069}.Release|x86.Build.0 = Release|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Debug|x64.Build.0 = Debug|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Debug|x86.Build.0 = Debug|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Release|Any CPU.Build.0 = Release|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Release|x64.ActiveCfg = Release|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Release|x64.Build.0 = Release|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Release|x86.ActiveCfg = Release|Any CPU
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987}.Release|x86.Build.0 = Release|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Debug|x64.Build.0 = Debug|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Debug|x86.Build.0 = Debug|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Release|x64.ActiveCfg = Release|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Release|x64.Build.0 = Release|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Release|x86.ActiveCfg = Release|Any CPU
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC}.Release|x86.Build.0 = Release|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Debug|x86.Build.0 = Debug|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Release|x64.Build.0 = Release|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50}.Release|x86.Build.0 = Release|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Debug|x64.Build.0 = Debug|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Debug|x86.Build.0 = Debug|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Release|x64.ActiveCfg = Release|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Release|x64.Build.0 = Release|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Release|x86.ActiveCfg = Release|Any CPU
+ {272B0A44-B985-47FF-8C93-32A77F5919C9}.Release|x86.Build.0 = Release|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Debug|x64.Build.0 = Debug|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Debug|x86.Build.0 = Debug|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Release|x64.ActiveCfg = Release|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Release|x64.Build.0 = Release|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Release|x86.ActiveCfg = Release|Any CPU
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D}.Release|x86.Build.0 = Release|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Debug|x64.Build.0 = Debug|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Debug|x86.Build.0 = Debug|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Release|x64.ActiveCfg = Release|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Release|x64.Build.0 = Release|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Release|x86.ActiveCfg = Release|Any CPU
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A}.Release|x86.Build.0 = Release|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Debug|x64.Build.0 = Debug|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Debug|x86.Build.0 = Debug|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Release|x64.ActiveCfg = Release|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Release|x64.Build.0 = Release|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Release|x86.ActiveCfg = Release|Any CPU
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {17E2FB3F-0F61-3CDC-2874-2686F1726316} = {6C4179B9-BFAA-0403-502F-9DAF28C26A6E}
+ {F3D13E8E-EDFF-4407-9442-9963C61D9EFF} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {164E2865-D5CF-48CF-9036-CD70B945BE82} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {9085E25B-2C3D-487E-9B52-304CAE2F88B8} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {5D0041E0-FEB3-460F-90FA-AE50173D8EE6} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {F98BECAE-E25F-436E-8D69-F00E83164E13} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {7CF6BBC9-2176-452A-A55F-A315F611923A} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {C1F04A37-F946-4AA9-872D-A38A289F41BE} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {545A47FC-6BAA-4C92-BAD1-C1ED413077BC} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {59745535-3681-423D-AE8F-5C08D4671ADC} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {6FE1B566-08DF-4BC0-AC2F-F9176AA17087} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {F04E9976-C303-4DEA-AA8D-EEDE6DF44069} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {A61BAD5E-77AC-49A0-8028-5E84EF990987} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {E6F92ED7-6EE2-4D71-8962-15613CD379BC} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {3D5DDCB4-3840-4ACE-AB17-A217F3A27F50} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {272B0A44-B985-47FF-8C93-32A77F5919C9} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {D852D486-F1DA-48A6-BBAF-43FF3396527D} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {6C5E7FB8-D6E8-4CBD-95FC-89EAB773472A} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ {E526424D-ADC7-41DB-AD63-E359AC2954D9} = {17E2FB3F-0F61-3CDC-2874-2686F1726316}
+ EndGlobalSection
+EndGlobal
diff --git a/MatrixInviteLogger.sln.DotSettings.user b/MatrixInviteLogger.sln.DotSettings.user
new file mode 100644
index 0000000..3b9e228
--- /dev/null
+++ b/MatrixInviteLogger.sln.DotSettings.user
@@ -0,0 +1,4 @@
+<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
+ <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AExceptionDispatchInfo_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fea51ca5e833244688d7ca912cfc70784d19c00_003F97_003Ffb30ee1f_003FExceptionDispatchInfo_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+ <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AObjectExtensions_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8fd5e96d6574456095123be1ecfbdfa914200_003Fe2_003F3561a383_003FObjectExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
+ <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AStackFrameIterator_002Ecs_002Fl_003A_002E_002E_003F_002E_002E_003F_002E_002E_003F_002Econfig_003FJetBrains_003FRider2024_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003Fea51ca5e833244688d7ca912cfc70784d19c00_003F86_003F8b4aa64e_003FStackFrameIterator_002Ecs/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
\ No newline at end of file
diff --git a/MatrixInviteLogger/InviteLogger.cs b/MatrixInviteLogger/InviteLogger.cs
new file mode 100644
index 0000000..22a519b
--- /dev/null
+++ b/MatrixInviteLogger/InviteLogger.cs
@@ -0,0 +1,117 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using ArcaneLibs;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State.RoomInfo;
+using LibMatrix.Helpers;
+using LibMatrix.Utilities.Bot.Services;
+using MatrixInviteLogger;
+
+public class InviteLogger(ILogger<InviteLogger> logger, InviteLoggerConfiguration config) : InviteHandlerHostedService.IInviteHandler
+{
+ public async Task HandleInviteAsync(InviteHandlerHostedService.InviteEventArgs invite)
+ {
+ logger.LogInformation("Received invite to room {}", invite.RoomId);
+ var logRoom = invite.Homeserver.GetRoom(config.LogRoom);
+ var inviterName = await GetInviterNameAsync(invite);
+ string roomName = await GetRoomNameAsync(invite);
+
+ logger.LogInformation("Inviter: {}, Room: {}", inviterName, roomName);
+
+ var message = new MessageBuilder()
+ .WithBody("Received invite to ").WithMention(invite.RoomId, roomName).WithBody(" from ").WithMention(invite.MemberEvent.Sender!, inviterName)
+ .Build();
+
+ // TODO: can we filter this somehow to stay within event size limits?
+ // var serialisedInviteData = JsonNode.Parse(invite.InviteData.ToJson(ignoreNull: true));
+ // message.AdditionalData!["gay.rory.invite_logger.invite_data"] = serialisedInviteData!;
+
+ var inviteData = invite.InviteData.ToJsonUtf8Bytes();
+ var inviteDataFileUri = await invite.Homeserver.UploadFile(invite.RoomId + ".json", inviteData, "application/json");
+ logger.LogInformation("Uploaded invite data ({}) to {}", Util.BytesToString(inviteData.Length), inviteDataFileUri);
+
+ // Dictionary<string, JsonElement>
+ message.AdditionalData!["gay.rory.invite_logger.invite_data_uri"] = JsonDocument.Parse($"\"{inviteDataFileUri}\"").RootElement;
+
+ await logRoom.SendMessageEventAsync(message);
+
+ if (config.SendInviteDataAsFile)
+ {
+ await logRoom.SendMessageEventAsync(new()
+ {
+ MessageType = "m.file",
+ Body = invite.RoomId + ".json",
+ FileName = invite.RoomId + ".json",
+ Url = inviteDataFileUri,
+ FileInfo = new() { Size = inviteData.Length, MimeType = "application/json" }
+ });
+ }
+ }
+
+ private async Task<string> GetInviterNameAsync(InviteHandlerHostedService.InviteEventArgs invite)
+ {
+ var name = invite.InviteData.InviteState?.Events?
+ .FirstOrDefault(evt => evt is { Type: RoomMemberEventContent.EventId } && evt.StateKey == invite.MemberEvent.Sender)?
+ .ContentAs<RoomMemberEventContent>()?.DisplayName;
+
+ if (!string.IsNullOrWhiteSpace(name))
+ return name;
+
+ try
+ {
+ await invite.Homeserver.GetProfileAsync(invite.MemberEvent.Sender!);
+ }
+ catch
+ {
+ //ignored
+ }
+
+ return invite.MemberEvent.Sender!;
+ }
+
+ private async Task<string> GetRoomNameAsync(InviteHandlerHostedService.InviteEventArgs invite)
+ {
+ // try get room name from invite state
+ var name = invite.InviteData.InviteState?.Events?
+ .FirstOrDefault(evt => evt is { Type: RoomNameEventContent.EventId, StateKey: "" })?
+ .ContentAs<RoomNameEventContent>()?.Name;
+
+ if (!string.IsNullOrWhiteSpace(name))
+ return name;
+
+ // try get room alias
+ var alias = invite.InviteData.InviteState?.Events?
+ .FirstOrDefault(evt => evt is { Type: RoomCanonicalAliasEventContent.EventId, StateKey: "" })?
+ .ContentAs<RoomCanonicalAliasEventContent>()?.Alias;
+
+ if (!string.IsNullOrWhiteSpace(alias))
+ return alias;
+
+ // try get room name via public previews
+ try
+ {
+ name = await invite.Homeserver.GetRoom(invite.RoomId).GetNameOrFallbackAsync();
+ if (name != invite.RoomId && !string.IsNullOrWhiteSpace(name))
+ return name;
+ }
+ catch
+ {
+ //ignored
+ }
+
+ // fallback to room alias via public previews
+ try
+ {
+ alias = (await invite.Homeserver.GetRoom(invite.RoomId).GetCanonicalAliasAsync())?.Alias;
+ if (!string.IsNullOrWhiteSpace(alias))
+ return alias;
+ }
+ catch
+ {
+ //ignored
+ }
+
+ // fall back to room ID
+ return invite.RoomId;
+ }
+}
\ No newline at end of file
diff --git a/MatrixInviteLogger/InviteLoggerConfiguration.cs b/MatrixInviteLogger/InviteLoggerConfiguration.cs
new file mode 100644
index 0000000..8fe1a29
--- /dev/null
+++ b/MatrixInviteLogger/InviteLoggerConfiguration.cs
@@ -0,0 +1,9 @@
+using Microsoft.Extensions.Configuration;
+
+namespace MatrixInviteLogger;
+
+public class InviteLoggerConfiguration {
+ public InviteLoggerConfiguration(IConfiguration config) => config.GetRequiredSection("InviteLogger").Bind(this);
+ public string LogRoom { get; set; }
+ public bool SendInviteDataAsFile { get; set; }
+}
\ No newline at end of file
diff --git a/MatrixInviteLogger/MatrixInviteLogger.csproj b/MatrixInviteLogger/MatrixInviteLogger.csproj
new file mode 100644
index 0000000..5a322ce
--- /dev/null
+++ b/MatrixInviteLogger/MatrixInviteLogger.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk.Worker">
+
+ <PropertyGroup>
+ <TargetFramework>net9.0</TargetFramework>
+ <Nullable>enable</Nullable>
+ <ImplicitUsings>enable</ImplicitUsings>
+ <UserSecretsId>dotnet-MatrixInviteLogger-87d8c346-8c07-42f9-8bfb-f2a714bbd663</UserSecretsId>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Extensions.Hosting" Version="9.0.2"/>
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\LibMatrix\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj" />
+ </ItemGroup>
+</Project>
diff --git a/MatrixInviteLogger/Program.cs b/MatrixInviteLogger/Program.cs
new file mode 100644
index 0000000..403f066
--- /dev/null
+++ b/MatrixInviteLogger/Program.cs
@@ -0,0 +1,16 @@
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using LibMatrix.Services;
+using LibMatrix.Utilities.Bot;
+using MatrixInviteLogger;
+
+var builder = Host.CreateApplicationBuilder(args);
+// builder.Services.AddHostedService<Worker>();
+
+builder.Services.AddSingleton<InviteLoggerConfiguration>();
+builder.Services.AddRoryLibMatrixServices()
+ .AddMatrixBot()
+ .WithInviteHandler<InviteLogger>();
+
+var host = builder.Build();
+host.Run();
\ No newline at end of file
diff --git a/MatrixInviteLogger/Properties/launchSettings.json b/MatrixInviteLogger/Properties/launchSettings.json
new file mode 100644
index 0000000..383a8e2
--- /dev/null
+++ b/MatrixInviteLogger/Properties/launchSettings.json
@@ -0,0 +1,12 @@
+{
+ "$schema": "https://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "MatrixInviteLogger": {
+ "commandName": "Project",
+ "dotnetRunMessages": true,
+ "environmentVariables": {
+ "DOTNET_ENVIRONMENT": "Development"
+ }
+ }
+ }
+}
diff --git a/MatrixInviteLogger/appsettings.Development.json b/MatrixInviteLogger/appsettings.Development.json
new file mode 100644
index 0000000..ffdfb9c
--- /dev/null
+++ b/MatrixInviteLogger/appsettings.Development.json
@@ -0,0 +1,16 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "LibMatrixBot": {
+ "Homeserver": "rory.gay",
+ "AccessTokenPath": "/home/Rory/matrix_access_token"
+ },
+ "InviteLogger": {
+ "LogRoom": "!GrLSwdAkdrvfMrRYKR:rory.gay",
+ "SendInviteDataAsFile": true // default: false
+ }
+}
diff --git a/MatrixInviteLogger/appsettings.json b/MatrixInviteLogger/appsettings.json
new file mode 100644
index 0000000..b2dcdb6
--- /dev/null
+++ b/MatrixInviteLogger/appsettings.json
@@ -0,0 +1,8 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ }
+}
|