namespace App\Console\Commands;
use App\Models\DiscordGuild;
+use App\Models\DiscordRole;
use Discord\Discord;
use Discord\Parts\Channel\Message;
use Discord\Parts\Guild\Guild;
+use Discord\Parts\Guild\Role;
use Discord\WebSockets\Event;
use Illuminate\Console\Command;
use Monolog\Handler\StreamHandler;
'token' => config('discord.token'),
]);
$discord->on(Event::GUILD_CREATE, function (Guild $guild, Discord $discord) {
- DiscordGuild::sync($guild);
+ try {
+ DiscordGuild::onUpstreamCreate($guild);
+ } catch (\Exception $e) {
+ $this->error('guild create: '.$e->getMessage());
+ }
});
- $discord->on(Event::GUILD_UPDATE, function (Guild $guild, Discord $discord, Guild $old) {
- DiscordGuild::sync($guild);
+ $discord->on(Event::GUILD_UPDATE, function (Guild $guild, Discord $discord, ?Guild $old) {
+ try {
+ DiscordGuild::onUpstreamUpdate($guild);
+ } catch (\Exception $e) {
+ $this->error('guild update: '.$e->getMessage());
+ }
+ });
+ $discord->on(Event::GUILD_ROLE_CREATE, function (Role $role, Discord $discord) {
+ try {
+ DiscordRole::onUpstreamCreate($role);
+ } catch (\Exception $e) {
+ $this->error('guild role create: '.$e->getMessage());
+ }
+ });
+ $discord->on(Event::GUILD_ROLE_UPDATE, function (Role $role, Discord $discordi, ?Role $old) {
+ try {
+ DiscordRole::onUpstreamUpdate($role);
+ } catch (\Exception $e) {
+ $this->error('guild role update: '.$e->getMessage());
+ }
+ });
+ $discord->on(Event::GUILD_ROLE_DELETE, function ($role, Discord $discord) {
+ try {
+ DiscordRole::onUpstreamDelete($role);
+ } catch (\Exception $e) {
+ $this->error('guild role delete: '.$e->getMessage());
+ }
});
$discord->on('ready', function (Discord $discord) {
$discord->on(Event::MESSAGE_CREATE, function (Message $message, Discord $discord) {
use HasFactory;
+ public static function onUpstreamCreate(Guild $guild) {
+ static::sync($guild);
+ }
+
+ public static function onUpstreamUpdate(Guild $guild) {
+ static::sync($guild);
+ }
+
public static function sync(Guild $guild) {
$model = static::firstOrNew([
'guild_id' => $guild->id,
$model->owner = $guild->owner_id;
$model->locale = $guild->preferred_locale;
$model->save();
+
+ $role_ids = [];
+ foreach ($guild->roles as $role) {
+ DiscordRole::sync($model, $role);
+ $role_ids[] = $role->id;
+ }
+ $model->roles()->whereNotIn('role_id', $role_ids)->delete();
+ }
+
+ public function roles() {
+ return $this->hasMany(DiscordRole::class);
}
protected $fillable = [
--- /dev/null
+<?php
+
+namespace App\Models;
+
+use Discord\Parts\Guild\Role;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class DiscordRole extends Model
+{
+ use HasFactory;
+
+ public static function onUpstreamCreate(Role $role) {
+ $guild = DiscordGuild::firstWhere('guild_id', $role->guild_id);
+ if (!$guild) return;
+ static::sync($guild, $role);
+ }
+
+ public static function onUpstreamUpdate(Role $role) {
+ $guild = DiscordGuild::firstWhere('guild_id', $role->guild_id);
+ if (!$guild) return;
+ static::sync($guild, $role);
+ }
+
+ public static function onUpstreamDelete($role) {
+ if (!$role) return;
+ $model = static::firstWhere('role_id', $role->id);
+ if (!$model) return;
+ $model->delete();
+ }
+
+ public static function sync(DiscordGuild $guild, Role $role) {
+ $model = static::firstOrNew([
+ 'discord_guild_id' => $guild->id,
+ 'role_id' => $role->id,
+ ]);
+ $model->name = $role->name;
+ $model->color = $role->color;
+ $model->position = $role->position;
+ $model->permissions = $role->permissions->bitwise;
+ $model->save();
+ }
+
+ public function guild() {
+ return $this->belongsTo(DiscordGuild::class);
+ }
+
+ protected $fillable = [
+ 'discord_guild_id',
+ 'role_id',
+ ];
+
+}
--- /dev/null
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::create('discord_roles', function (Blueprint $table) {
+ $table->id();
+ $table->foreignId('discord_guild_id')->constrained();
+ $table->string('role_id')->unique();
+ $table->string('name');
+ $table->integer('color');
+ $table->integer('position');
+ $table->bigInteger('permissions');
+ $table->timestamps();
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('discord_roles');
+ }
+};