> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ghosting.fun/llms.txt
> Use this file to discover all available pages before exploring further.

# Bot Discord: consulte perfis Ghosting com Discord.js v14

> Crie um slash command /ghosting no Discord.js v14 que consulta perfis da API Ghosting. Inclui tratamento de perfis ativos, suspensos e não encontrados.

Este guia mostra como criar um slash command `/ghosting` em Discord.js v14 que consulta a API pública Ghosting e exibe o perfil como embed. O exemplo trata os três cenários possíveis: perfil ativo, perfil suspenso (que retorna `HTTP 200 OK`) e perfil não encontrado.

<Steps>
  <Step title="Instale as dependências">
    Seu projeto precisa de Discord.js v14 e Node.js 18+ (para `fetch` nativo).

    ```bash theme={null}
    npm install discord.js
    ```
  </Step>

  <Step title="Crie o slash command">
    Salve o arquivo abaixo em `commands/ghosting.js` (ou o caminho equivalente na sua estrutura de bot).

    ```javascript commands/ghosting.js theme={null}
    const { SlashCommandBuilder, EmbedBuilder } = require("discord.js");

    module.exports = {
      data: new SlashCommandBuilder()
        .setName("ghosting")
        .setDescription("Consulta informações de um usuário no Ghosting")
        .addStringOption(opt =>
          opt.setName("usuario")
            .setDescription("Nome de usuário no Ghosting (ex: ghosting)")
            .setRequired(true)
        ),

      async execute(interaction) {
        await interaction.deferReply();

        const rawUsername = interaction.options.getString("usuario");
        const username = rawUsername.trim().replace(/^@/, "");

        try {
          const res = await fetch(`https://ghosting.fun/api/v1/users/${username}`);
          const body = await res.json();

          if (!body.success || !body.data) {
            return interaction.editReply({
              content: `❌ O usuário **@${username}** não foi encontrado no Ghosting.`
            });
          }

          const user = body.data;

          // Tratamento especial para perfil suspenso (retorna 200 OK)
          if (user.status === "suspended") {
            const banEmbed = new EmbedBuilder()
              .setTitle(`⚠️ @${user.username} — Perfil Suspenso`)
              .setURL(user.pageUrl)
              .setColor("#ef4444")
              .setThumbnail(user.avatarUrl)
              .setDescription(
                `Este perfil foi suspenso pela moderação do Ghosting.\n\n` +
                `**Motivo:** ${user.banInfo?.reason || "Violação das Diretrizes da Comunidade"}\n` +
                `**Data:** ${user.banInfo?.bannedAt ? new Date(user.banInfo.bannedAt).toLocaleDateString("pt-BR") : "N/A"}`
              )
              .setFooter({ text: "Ghosting Moderação • API Pública" });

            return interaction.editReply({ embeds: [banEmbed] });
          }

          // Perfil ativo
          const embed = new EmbedBuilder()
            .setTitle(`${user.displayName} (@${user.username})`)
            .setURL(user.pageUrl)
            .setThumbnail(user.avatarUrl)
            .setDescription(user.bio || "*Nenhuma biografia informada.*")
            .setColor(user.badges.isOfficial ? "#22c55e" : "#3b82f6")
            .addFields(
              { name: "Visualizações", value: user.views.toLocaleString("pt-BR"), inline: true },
              { name: "Dias Ativo", value: `${user.accountAgeDays} dias`, inline: true },
              { name: "Verificado", value: user.badges.isVerified ? "✅ Sim" : "❌ Não", inline: true }
            )
            .setFooter({ text: "Ghosting API v1 • ghosting.fun" });

          if (user.avatarDecoration?.url) {
            embed.setAuthor({
              name: `Moldura: ${user.avatarDecoration.name}`,
              iconURL: user.avatarDecoration.url
            });
          }

          return interaction.editReply({ embeds: [embed] });

        } catch (err) {
          console.error("Erro no comando /ghosting:", err);
          return interaction.editReply({
            content: "❌ Ocorreu um erro interno ao consultar a API do Ghosting."
          });
        }
      },
    };
    ```
  </Step>

  <Step title="Registre e teste">
    Registre o comando no Discord (guild ou global) usando o script de deploy que já faz parte do seu bot, e teste digitando `/ghosting usuario:ghosting` em qualquer canal.
  </Step>
</Steps>

<Note>
  O bloco de código verifica `user.status === "suspended"` porque a API retorna `HTTP 200 OK` mesmo para perfis suspensos. Não use apenas `res.ok` para decidir se o perfil está acessível. Veja [Arquitetura de moderação](/guias/moderacao) para detalhes.
</Note>

<Tip>
  Se preferir exibir o motivo formatado, use `user.banInfo.message` em vez de `user.banInfo.reason`. O campo `message` já vem com uma frase pronta para exibição em interfaces públicas.
</Tip>

## Próximos passos

<CardGroup cols={2}>
  <Card title="Exemplos de código" icon="code" href="/guias/exemplos-codigo">
    Snippets em outras linguagens (Python, cURL, Axios).
  </Card>

  <Card title="Schema User" icon="layers" href="/schemas/user">
    Todos os campos do objeto de perfil.
  </Card>
</CardGroup>
