このコミットが含まれているのは:
Florian Brinker 2022-03-19 23:20:09 +01:00
コミット 61175d4334
11個のファイルの変更3681行の追加0行の削除

4
.gitignore vendored ノーマルファイル
ファイルの表示

@ -0,0 +1,4 @@
vendor/
*.log
public/states/*.json

28
Dockerfile ノーマルファイル
ファイルの表示

@ -0,0 +1,28 @@
FROM php:apache
RUN apt-get update
RUN apt-get install -y libzip-dev
RUN docker-php-ext-install zip
WORKDIR /var/www/html
COPY public/ public
COPY src/ src
COPY app.php app.php
COPY README.md README.md
COPY composer.json composer.json
COPY composer.lock composer.lock
# Application
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
RUN composer install --no-dev
# Apache
COPY docker/vhost.conf /etc/apache2/sites-available/project.conf
RUN a2enmod rewrite &&\
a2dissite 000-default &&\
a2ensite project &&\
service apache2 restart
EXPOSE 80
ENTRYPOINT ["bash", "-c", "apache2-foreground & php app.php"]

ファイルの表示

@ -1,3 +1,36 @@
# VoiceState - Discord Bot
This is a simple bot, tracking the mute state of members currently using the voice chat. The generated json files are named by the userId and contain just the mute state and no other information.
## Example
```
# https://discordbot.f-brinker.de/voice-state/states/userId123.json
{"state":"selfMuted"}
```
### Possible States
* active
* muted
* selfMuted
## Usage
* Add the Bot to your Discord Guild: [Add VoiceState Bot](https://discord.com/api/oauth2/authorize?client_id=954772647575703602&permissions=0&scope=bot)
* Grab the state by fetching https://discordbot.f-brinker.de/voice-state/states/userId123.json
* Replace userId123 with your Discord userId
## Host your own!
You can host your own bot by building the project on your own or by using the pre-built image `fbrinker/discordbot-voice-state`.
You need to create your own Discord application and bot. You need the Bot Token below. Replace `yourBotToken` with your actual token.
### Examle Docker-Compose
```
discordbot-voice-state:
container_name: discordbot-voice-state
image: fbrinker/discordbot-voice-state
restart: always
environment:
- "BOT_TOKEN=yourBotToken"
```
## Contribute
Feel free to add Pull-Request @ https://git.f-brinker.de/fbrinker/discordbot-voice-state

46
app.php ノーマルファイル
ファイルの表示

@ -0,0 +1,46 @@
<?php
error_reporting(E_ALL ^ E_DEPRECATED);
ini_set('memory_limit', '128M');
include __DIR__.'/vendor/autoload.php';
use \Monolog\Logger;
use \Monolog\Handler\ErrorLogHandler;
use \Monolog\Handler\RotatingFileHandler;
use Discord\Discord;
use Discord\WebSockets\Intents;
use Discord\WebSockets\Event;
use Discord\Parts\WebSockets\VoiceStateUpdate;
use VoiceState\Bot;
$botToken = getenv("BOT_TOKEN");
if (empty($botToken)) {
die("Missing BOT_TOKEN");
}
$logger = new Logger(Bot::NAME);
$logger->pushHandler(new ErrorLogHandler(ErrorLogHandler::SAPI, Logger::INFO));
$logger->pushHandler(new RotatingFileHandler(__DIR__ . '/logs/' . Bot::NAME . ".log", Bot::MAX_LOG_FILE_COUNT, Logger::WARNING));
$bot = new Bot(__DIR__ . '/public/states/', $logger);
$discord = new Discord([
'token' => $botToken,
'intents' => [
Intents::GUILD_VOICE_STATES
],
'logger' => $logger
]);
$discord->on('ready', function (Discord $discord) use ($logger) {
$logger->info("Bot is ready!");
});
$discord->on(Event::VOICE_STATE_UPDATE, function (VoiceStateUpdate $state, Discord $discord, $oldstate) use ($bot, $logger) {
$logger->info('Event: ' . Event::VOICE_STATE_UPDATE);
$bot->updateVoiceState($state);
});
$discord->run();

14
composer.json ノーマルファイル
ファイルの表示

@ -0,0 +1,14 @@
{
"autoload": {
"psr-4": {
"VoiceState\\": "src/"
}
},
"require": {
"team-reflex/discord-php": "dev-master",
"league/commonmark": "^2.2"
},
"require-dev": {
"roave/security-advisories": "dev-latest"
}
}

3468
composer.lock generated ノーマルファイル

ファイル差分が大きすぎるため省略します 差分を読み込み

3
docker/vhost.conf ノーマルファイル
ファイルの表示

@ -0,0 +1,3 @@
<VirtualHost *:80>
DocumentRoot /var/www/html/public
</VirtualHost>

0
logs/.gitkeep ノーマルファイル
ファイルの表示

9
public/index.php ノーマルファイル
ファイルの表示

@ -0,0 +1,9 @@
<?php
//error_reporting(0);
include __DIR__.'/../vendor/autoload.php';
use League\CommonMark\CommonMarkConverter;
$converter = new CommonMarkConverter();
echo $converter->convert(file_get_contents(__DIR__ . '/../README.md'));

0
public/states/.gitkeep ノーマルファイル
ファイルの表示

76
src/Bot.php ノーマルファイル
ファイルの表示

@ -0,0 +1,76 @@
<?php
namespace VoiceState;
use \Monolog\Logger;
use Discord\Parts\WebSockets\VoiceStateUpdate;
class Bot
{
public const NAME = "VoiceState";
public const MAX_LOG_FILE_COUNT = 7;
private const STATE_FILE_TEMPLATE = "%s.json";
private const STATE_DEFAULT = [
'state' => null,
];
private const STATE_ACTIVE = 'active';
private const STATE_MUTE = 'muted';
private const STATE_SELF_MUTE = 'selfMuted';
private string $stateFileDir;
private Logger $logger;
public function __construct(string $stateFileDir, Logger $logger)
{
if (!is_dir($stateFileDir)) {
throw new \RuntimeException("stateFileDir is no directory");
}
$this->stateFileDir = rtrim($stateFileDir, '/');
$this->logger = $logger;
}
public function updateVoiceState(VoiceStateUpdate $voiceState): void
{
try {
$stateFile = $this->stateFileDir . '/' . sprintf(self::STATE_FILE_TEMPLATE, $voiceState->user_id);
if (!file_exists($stateFile)) {
$this->createStatusFile($stateFile);
}
$state = $this->getState($voiceState);
file_put_contents($stateFile, json_encode($state));
} catch (\Throwable $t) {
$this->logger->error($t);
}
}
private function getState(VoiceStateUpdate $voiceState)
{
$state = self::STATE_DEFAULT;
$state['state'] = self::STATE_ACTIVE;
if ($voiceState->mute) {
$state['state'] = self::STATE_MUTE;
}
if ($voiceState->self_mute) {
$state['state'] = self::STATE_SELF_MUTE;
}
return $state;
}
private function createStatusFile(string $stateFile): void
{
if (file_exists($stateFile)) {
return;
}
file_put_contents($stateFile, json_encode(self::STATE_DEFAULT));
if (!file_exists($stateFile)) {
throw new \RuntimeException("could not create statefile: " . $stateFile);
}
}
}