Merge pull request 'Dev' (#1) from Dev into main

Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
2026-03-29 04:37:06 +01:00
3 changed files with 125 additions and 239 deletions

View File

@@ -1,151 +1,101 @@
<!DOCTYPE html> # Privacy Policy
<html lang="en">
<body>
<h1>Privacy Policy</h1> **Effective Date:** March 11, 2026
<p><strong>Effective Date:</strong> March 11, 2026</p> This Privacy Policy describes how Reactor collects, uses, and stores information when used within a Valour server.
<p> ---
This Privacy Policy describes how Reactor collects, uses,
and stores information when used within a Valour server.
</p>
<hr> ## 1. Information Collected
<h2>1. Information Collected</h2>
<p>
Reactor collects only the minimum data required to function. Reactor collects only the minimum data required to function.
</p>
<h3>Information Stored (Persisted to Disk)</h3> ### Information Stored (Persisted to Disk)
<ul>
<li>Planet IDs</li>
<li>Channel IDs</li>
<li>Message IDs of reaction role messages</li>
<li>Emoji-to-role mappings</li>
<li>Confirmation message delete delay settings</li>
</ul>
<h3>Information Not Stored</h3> - Planet IDs
<ul> - Channel IDs
<li>Message content (beyond the initial reaction message text provided by the administrator)</li> - Message IDs of reaction role messages
<li>User IDs (beyond what is transiently used to assign or remove roles during a reaction event)</li> - Emoji-to-role mappings
<li>Direct Messages (DMs)</li> - Confirmation message delete delay settings
<li>User credentials</li>
<li>Email addresses</li>
<li>Passwords</li>
<li>IP addresses</li>
<li>Analytics or tracking data</li>
</ul>
<hr> ### Information Not Stored
<h2>2. Purpose of Data Collection</h2> - Message content (beyond the initial reaction message text provided by the administrator)
- User IDs (beyond what is transiently used to assign or remove roles during a reaction event)
- Direct Messages (DMs)
- User credentials
- Email addresses
- Passwords
- IP addresses
- Analytics or tracking data
<p>Stored information is used exclusively to:</p> ---
<ol> ## 2. Purpose of Data Collection
<li>Track which messages are configured as reaction role messages</li>
<li>Map emoji reactions to planet roles</li> Stored information is used exclusively to:
<li>Assign or remove roles from members when they react or unreact to a tracked message</li>
<li>Automatically clean up stale data when messages are deleted</li> 1. Track which messages are configured as reaction role messages
</ol> 2. Map emoji reactions to planet roles
3. Assign or remove roles from members when they react or unreact to a tracked message
4. Automatically clean up stale data when messages are deleted
<p>
Data is not used for marketing, advertising, profiling, or analytics. Data is not used for marketing, advertising, profiling, or analytics.
</p>
<hr> ---
<h2>3. Data Storage and Security</h2> ## 3. Data Storage and Security
<p> All data is stored in a local SQLite database file (`reactor.db`) on the hosting server.
All data is stored in a local SQLite database file (<code>reactor.db</code>) on the hosting server.
</p>
<p> The operator of the self-hosted instance is responsible for securing the hosting environment and the database file.
The operator of the self-hosted instance is responsible for securing the hosting environment
and the database file.
</p>
<p>
Stale or deleted reaction messages are automatically removed from the database on bot startup. Stale or deleted reaction messages are automatically removed from the database on bot startup.
</p>
<hr> ---
<h2>4. Third-Party Processing</h2> ## 4. Third-Party Processing
<p> Reactor does not transmit any data to external services beyond the Valour.gg API, which is required for core bot functionality such as assigning roles and sending messages.
Reactor does not transmit any data to external services beyond the Valour.gg API,
which is required for core bot functionality such as assigning roles and sending messages.
</p>
<p>
Reactor does not use any external AI providers, analytics services, or cloud storage. Reactor does not use any external AI providers, analytics services, or cloud storage.
</p>
<hr> ---
<h2>5. Data Retention</h2> ## 5. Data Retention
<p>
Reaction role message data is retained in the SQLite database until: Reaction role message data is retained in the SQLite database until:
</p>
<ul> - The reaction message is deleted from Valour (automatic cleanup on bot startup)
<li>The reaction message is deleted from Valour (automatic cleanup on bot startup)</li> - An administrator runs the `r.delete` command
<li>An administrator runs the <code>r.delete</code> command</li> - The database file is manually deleted by the host operator
<li>The database file is manually deleted by the host operator</li>
</ul>
<hr> ---
<h2>6. Self-Hosted Responsibility</h2> ## 6. Self-Hosted Responsibility
<p>
Reactor is designed for self-hosting. Reactor is designed for self-hosting.
</p>
<p>
The hosting operator is responsible for: The hosting operator is responsible for:
</p>
<ul> - Server security
<li>Server security</li> - Network configuration
<li>Network configuration</li> - Bot token protection
<li>Bot token protection</li> - Database file security
<li>Database file security</li> - Compliance with applicable laws
<li>Compliance with applicable laws</li>
</ul>
<hr> ---
<h2>7. Changes to This Policy</h2> ## 7. Changes to This Policy
<p> If data collection practices change in future versions, this Privacy Policy will be updated prior to implementation.
If data collection practices change in future versions,
this Privacy Policy will be updated prior to implementation.
</p>
<p> Continued use of the Bot after updates constitutes acceptance of the revised policy.
Continued use of the Bot after updates constitutes acceptance
of the revised policy.
</p>
<hr> ---
<h2>8. Contact Information</h2> ## 8. Contact Information
<p>
For privacy-related inquiries: For privacy-related inquiries:
</p>
<p>
Email: contact@skyjoshua.xyz Email: contact@skyjoshua.xyz
</p>
</body>
</html>

200
README.md
View File

@@ -1,166 +1,102 @@
<!DOCTYPE html> # Reactor
<html lang="en">
<body>
<h1>Reactor</h1> Reactor is a Valour.gg bot that enables server administrators to create reaction role messages. Users can react to a message with an emoji to automatically be assigned or removed from a role.
<p> ---
Reactor is a Valour.gg bot that enables server administrators to create reaction role messages.
Users can react to a message with an emoji to automatically be assigned or removed from a role.
</p>
<hr> ## Features
<h2>Features</h2> - Create reaction role messages in any planet channel
<ul> - Map emojis to roles — reacting adds the role, removing the reaction removes it
<li>Create reaction role messages in any planet channel</li> - Automatic cleanup of deleted reaction messages from the database
<li>Map emojis to roles — reacting adds the role, removing the reaction removes it</li> - Persistent storage via SQLite — survives bot restarts
<li>Automatic cleanup of deleted reaction messages from the database</li> - Permission-based command access (Manage Roles or Full Control required)
<li>Persistent storage via SQLite — survives bot restarts</li> - Built with .NET and the Valour SDK
<li>Permission-based command access (Manage Roles or Full Control required)</li> - Open-source under AGPL-3.0
<li>Built with .NET and the Valour SDK</li>
<li>Open-source under AGPL-3.0</li>
</ul>
<hr> ---
<h2>How It Works</h2> ## How It Works
<p>Reactor connects to the Valour.gg API and listens for reactions on configured messages.</p>
<ul>
<li>Reaction role messages and their emoji-to-role mappings are stored in a local SQLite database</li>
<li>When a user reacts to a tracked message, Reactor assigns the mapped role</li>
<li>When a user removes their reaction, Reactor removes the mapped role</li>
<li>Stale messages (deleted from Valour) are automatically pruned from the database on startup</li>
</ul>
<hr> Reactor connects to the Valour.gg API and listens for reactions on configured messages.
<h2>Requirements</h2> - Reaction role messages and their emoji-to-role mappings are stored in a local SQLite database
<ul> - When a user reacts to a tracked message, Reactor assigns the mapped role
<li>.NET 10+</li> - When a user removes their reaction, Reactor removes the mapped role
<li>Valid Valour bot token</li> - Stale messages (deleted from Valour) are automatically pruned from the database on startup
</ul>
<hr> ---
<h2>Installation</h2> ## Requirements
<pre><code>fork the project - .NET 10+
git clone https://github.com/YOUR_USERNAME/Reactor.git - Valid Valour bot token
---
## Installation
```bash
git clone https://git.skyjoshua.xyz/SkyJoshua/Reactor.git
cd Reactor cd Reactor
dotnet restore</code></pre> dotnet restore
```
<p> All required NuGet packages are installed automatically via the `.csproj` file.
All required NuGet packages are installed automatically via the <code>.csproj</code> file.
</p>
<hr> ---
<h2>Configuration</h2> ## Configuration
<p>Create a <code>.env</code> file in the root directory:</p> Create a `.env` file in the root directory:
```
TOKEN=your-valour-bot-token
```
<pre><code>TOKEN=your-valour-bot-token</code></pre>
<p>
Do not commit this file to version control. Do not commit this file to version control.
</p>
<hr> ---
<h2>Running the Bot</h2> ## Running the Bot
```bash
dotnet run
```
<pre><code>dotnet run</code></pre> ---
<hr> ## Commands
<h2>Commands</h2> All commands require **Manage Roles** or **Full Control** permissions, except `r.help` and `r.source`.
<p>All commands require <strong>Manage Roles</strong> or <strong>Full Control</strong> permissions, except <code>r.help</code> and <code>r.source</code>.</p> | Command | Description |
|---|---|
| `r.help` | Shows the list of available commands |
| `r.source` | Shows the source code of the bot |
| `r.create <message text>` | Creates a new reaction role message in the current channel |
| `r.add <messageId> <emoji> <roleId>` | Maps an emoji to a role on a reaction message |
| `r.remove <messageId> <emoji>` | Removes an emoji-to-role mapping from a reaction message |
| `r.delete <messageId>` | Deletes a reaction message and all its role mappings |
<table border="1" cellpadding="6"> ---
<tr>
<th>Command</th>
<th>Description</th>
</tr>
<tr>
<td><code>r.help</code></td>
<td>Shows the list of available commands</td>
</tr>
<tr>
<td><code>r.source</code></td>
<td>Shows the source code of the bot</td>
</tr>
<tr>
<td><code>r.create &lt;message text&gt;</code></td>
<td>Creates a new reaction role message in the current channel</td>
</tr>
<tr>
<td><code>r.add &lt;messageId&gt; &lt;emoji&gt; &lt;roleId&gt;</code></td>
<td>Maps an emoji to a role on a reaction message</td>
</tr>
<tr>
<td><code>r.remove &lt;messageId&gt; &lt;emoji&gt;</code></td>
<td>Removes an emoji-to-role mapping from a reaction message</td>
</tr>
<tr>
<td><code>r.delete &lt;messageId&gt;</code></td>
<td>Deletes a reaction message and all its role mappings</td>
</tr>
</table>
<hr> ## Data Storage
<h2>Data Storage</h2> Reactor stores the following data in a local SQLite database (`reactor.db`):
<p>Reactor stores the following data in a local SQLite database (<code>reactor.db</code>):</p> - Reaction message IDs, channel IDs, and planet IDs
<ul> - Emoji-to-role mappings per reaction message
<li>Reaction message IDs, channel IDs, and planet IDs</li> - Configurable delete delay for confirmation messages (default: 5 seconds)
<li>Emoji-to-role mappings per reaction message</li>
<li>Configurable delete delay for confirmation messages (default: 5 seconds)</li>
</ul>
<p> Full privacy policy:
Full privacy policy:<br> https://git.skyjoshua.xyz/SkyJoshua/Reactor/blob/main/PRIVACY.md
<a href="https://github.com/SkyJoshua/Reactor/blob/main/PRIVACY.md">
https://github.com/SkyJoshua/Reactor/blob/main/PRIVACY.md
</a>
</p>
<hr> ---
<h2>License</h2> ## License
<p>
This project is licensed under the
<strong>GNU Affero General Public License v3.0 (AGPL-3.0)</strong>.
</p>
<p> This project is licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0)**.
See the LICENSE file for details:<br>
<a href="https://github.com/SkyJoshua/Reactor/blob/main/LICENSE">
https://github.com/SkyJoshua/Reactor/blob/main/LICENSE
</a>
</p>
<p> See the LICENSE file for details:
If you modify and deploy this project publicly (including as a hosted service), https://git.skyjoshua.xyz/SkyJoshua/Reactor/blob/main/LICENSE
you must make your source code available under the same AGPL-3.0 license.
</p>
<hr> If you modify and deploy this project publicly (including as a hosted service), you must make your source code available under the same AGPL-3.0 license.
<h2>Contributing</h2>
<p>
Contributions are welcome. By submitting a contribution, you agree that your
contributions will be licensed under AGPL-3.0.
</p>
<ol>
<li>Fork the repository</li>
<li>Create a feature branch</li>
<li>Submit a pull request</li>
</ol>
</body>
</html>

View File

@@ -25,7 +25,7 @@ namespace Reactor.Services
var member = await message.FetchAuthorMemberAsync(); var member = await message.FetchAuthorMemberAsync();
string memberPing = member != null ? $"«@m-{member.Id}»" : ""; string memberPing = member != null ? $"«@m-{member.Id}»" : "";
bool hasPermission = await HasPermissionAsync(member, channelCache[channelId]); bool hasPermission = await HasPermissionAsync(member);
string withoutPrefix = content.Substring(prefix.Length); string withoutPrefix = content.Substring(prefix.Length);
@@ -150,7 +150,7 @@ namespace Reactor.Services
} }
} }
private static async Task<bool> HasPermissionAsync(PlanetMember member, Channel channel) private static async Task<bool> HasPermissionAsync(PlanetMember member)
{ {
if (member == null) return false; if (member == null) return false;