update
このコミットが含まれているのは:
コミット
61175d4334
4
.gitignore
vendored
ノーマルファイル
4
.gitignore
vendored
ノーマルファイル
@ -0,0 +1,4 @@
|
||||
vendor/
|
||||
|
||||
*.log
|
||||
public/states/*.json
|
28
Dockerfile
ノーマルファイル
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"]
|
33
README.md
33
README.md
@ -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
ノーマルファイル
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
ノーマルファイル
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
ノーマルファイル
3468
composer.lock
generated
ノーマルファイル
ファイル差分が大きすぎるため省略します
差分を読み込み
3
docker/vhost.conf
ノーマルファイル
3
docker/vhost.conf
ノーマルファイル
@ -0,0 +1,3 @@
|
||||
<VirtualHost *:80>
|
||||
DocumentRoot /var/www/html/public
|
||||
</VirtualHost>
|
0
logs/.gitkeep
ノーマルファイル
0
logs/.gitkeep
ノーマルファイル
9
public/index.php
ノーマルファイル
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
ノーマルファイル
0
public/states/.gitkeep
ノーマルファイル
76
src/Bot.php
ノーマルファイル
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);
|
||||
}
|
||||
}
|
||||
}
|
読み込み中…
新しいイシューから参照
ユーザーをブロックする