Contexto
O sistema de moderação possui uma arquitetura de platform adapters que permite executar ações de moderação em múltiplas plataformas. Atualmente, apenas o WebModerationAdapter está implementado (suspensão/ban na plataforma web). O Discord é a principal plataforma da comunidade e precisa de um adapter dedicado.
Objetivo
Implementar DiscordModerationAdapter que execute ações de moderação (warn, mute, kick, ban) via Discord REST API e notifique os usuários por DM.
Interfaces Envolvidas
ModerationPlatformContract
// app-modules/moderation/src/Platform/ModerationPlatformContract.php
interface ModerationPlatformContract
{
public function platform(): Platform;
public function ingest(array $rawPayload): ModerationContentDTO;
public function execute(ModerationAction $action, User $target): ExecutionResultDTO;
public function notify(User $user, string $message, array $context = []): void;
public function supports(): array; // ActionType[]
public function resolveUser(string $externalId): ?User;
}
ExecutionResultDTO
// app-modules/moderation/src/DTOs/ExecutionResultDTO.php
final readonly class ExecutionResultDTO
{
public Platform $platform;
public bool $success;
public ?string $error;
public array $platformResponse;
public static function success(Platform $platform, array $response = []): self;
public static function failure(Platform $platform, string $error, array $response = []): self;
}
Como o adapter é chamado
// app-modules/moderation/src/Enforcement/ExecuteAction.php
public function handle(): void
{
$platforms = app()->tagged('moderation.platforms');
foreach ($platforms as $adapter) {
if (in_array($adapter->platform()->value, $this->action->target_platforms, true)) {
$results[] = $adapter->execute($this->action, $this->target);
}
}
// salva resultados, atualiza case, dispara evento
}
Implementação Referência
O WebModerationAdapter (app-modules/moderation/src/Platform/WebModerationAdapter.php) serve como referência:
- Retorna
Platform::Web no platform()
- Suporta: Warn, Suspend, Ban, ContentRemove
- Usa
match no ActionType pra executar a ação correta
- Retorna
ExecutionResultDTO::success() ou ::failure()
- Notifica via Laravel Notification
Passo a Passo
1. Criar o adapter
Arquivo: app-modules/bot-discord/src/Moderation/DiscordModerationAdapter.php
class DiscordModerationAdapter implements ModerationPlatformContract
{
public function platform(): Platform
{
return Platform::Discord;
}
public function supports(): array
{
return [ActionType::Warn, ActionType::Mute, ActionType::Kick, ActionType::Ban];
}
}
2. Implementar execute()
Usar a Discord REST API via Http facade do Laravel:
| ActionType |
Discord API |
Endpoint |
| Warn |
Apenas DM pro user |
POST /users/@me/channels → POST /channels/{id}/messages |
| Mute |
Timeout (communication_disabled_until) |
PATCH /guilds/{guild}/members/{user} com communication_disabled_until |
| Kick |
Kick member |
DELETE /guilds/{guild}/members/{user} |
| Ban |
Ban member |
PUT /guilds/{guild}/bans/{user} com delete_message_seconds |
Headers necessários: Authorization: Bot {token} (token do bot do Discord)
3. Implementar notify()
Enviar DM embed pro usuário com detalhes da ação:
- Criar DM channel:
POST /users/@me/channels com recipient_id
- Enviar mensagem:
POST /channels/{channel_id}/messages com embed formatado
O embed deve conter: tipo da ação, motivo, duração (se aplicável), e link pra appeal.
4. Implementar resolveUser()
Mapear Discord ID externo → User interno usando a tabela external_identities.
5. Implementar ingest()
Transformar payload de mensagem do Discord em ModerationContentDTO.
6. Registrar o adapter
Arquivo: app-modules/bot-discord/src/BotDiscordServiceProvider.php
$this->app->singleton(DiscordModerationAdapter::class);
$this->app->tag(DiscordModerationAdapter::class, 'moderation.platforms');
7. Tratar durations
| Duração |
Mute (timeout) |
Ban |
24h |
24 horas |
Ban + delete 24h messages |
7d |
7 dias (max timeout) |
Ban + delete 7d messages |
30d |
N/A (max 28 dias) |
Ban permanente |
permanent |
N/A |
Ban permanente |
Discord timeout máximo: 28 dias. Pra durações maiores, considerar ban temporário com agendamento de unban.
8. Testes
Arquivos Relacionados
| Arquivo |
Propósito |
app-modules/moderation/src/Platform/ModerationPlatformContract.php |
Contrato a implementar |
app-modules/moderation/src/Platform/WebModerationAdapter.php |
Implementação de referência |
app-modules/moderation/src/ModerationServiceProvider.php |
Padrão de registro (singleton + tag) |
app-modules/moderation/src/Enforcement/ExecuteAction.php |
Job que chama os adapters |
app-modules/moderation/src/DTOs/ExecutionResultDTO.php |
DTO de resultado |
app-modules/moderation/src/DTOs/ModerationContentDTO.php |
DTO de conteúdo |
app-modules/bot-discord/src/BotDiscordServiceProvider.php |
ServiceProvider do bot |
app-modules/bot-discord/config/bot-discord.php |
Config do Discord (channels, roles) |
Critérios de Aceite
Contexto
O sistema de moderação possui uma arquitetura de platform adapters que permite executar ações de moderação em múltiplas plataformas. Atualmente, apenas o
WebModerationAdapterestá implementado (suspensão/ban na plataforma web). O Discord é a principal plataforma da comunidade e precisa de um adapter dedicado.Objetivo
Implementar
DiscordModerationAdapterque execute ações de moderação (warn, mute, kick, ban) via Discord REST API e notifique os usuários por DM.Interfaces Envolvidas
ModerationPlatformContractExecutionResultDTOComo o adapter é chamado
Implementação Referência
O
WebModerationAdapter(app-modules/moderation/src/Platform/WebModerationAdapter.php) serve como referência:Platform::Webnoplatform()matchnoActionTypepra executar a ação corretaExecutionResultDTO::success()ou::failure()Passo a Passo
1. Criar o adapter
Arquivo:
app-modules/bot-discord/src/Moderation/DiscordModerationAdapter.php2. Implementar
execute()Usar a Discord REST API via
Httpfacade do Laravel:POST /users/@me/channels→POST /channels/{id}/messagesPATCH /guilds/{guild}/members/{user}comcommunication_disabled_untilDELETE /guilds/{guild}/members/{user}PUT /guilds/{guild}/bans/{user}comdelete_message_secondsHeaders necessários:
Authorization: Bot {token}(token do bot do Discord)3. Implementar
notify()Enviar DM embed pro usuário com detalhes da ação:
POST /users/@me/channelscomrecipient_idPOST /channels/{channel_id}/messagescom embed formatadoO embed deve conter: tipo da ação, motivo, duração (se aplicável), e link pra appeal.
4. Implementar
resolveUser()Mapear Discord ID externo → User interno usando a tabela
external_identities.5. Implementar
ingest()Transformar payload de mensagem do Discord em
ModerationContentDTO.6. Registrar o adapter
Arquivo:
app-modules/bot-discord/src/BotDiscordServiceProvider.php7. Tratar durations
24h7d30dpermanent8. Testes
Arquivos Relacionados
app-modules/moderation/src/Platform/ModerationPlatformContract.phpapp-modules/moderation/src/Platform/WebModerationAdapter.phpapp-modules/moderation/src/ModerationServiceProvider.phpapp-modules/moderation/src/Enforcement/ExecuteAction.phpapp-modules/moderation/src/DTOs/ExecutionResultDTO.phpapp-modules/moderation/src/DTOs/ModerationContentDTO.phpapp-modules/bot-discord/src/BotDiscordServiceProvider.phpapp-modules/bot-discord/config/bot-discord.phpCritérios de Aceite
DiscordModerationAdapterimplementaModerationPlatformContractExecutionResultDTO::failure()sem crashar