---
title: "Contador de membros em canal de voz no Discord: como fazer com bot"
description: "Crie um canal de voz com Membros: 1.234 no discord.js v14: intent GuildMembers, limite de 2 renomeações a cada 10 minutos e permissões para ninguém entrar."
url: "https://streethosting.com.br/guias/bots-discord/bot-discord-contador-membros-canal-voz"
category: "bots-discord"
slug: "bot-discord-contador-membros-canal-voz"
datePublished: "2026-11-13"
dateModified: "2026-11-13"
author: "Equipe StreetHosting"
difficulty: "intermediario"
language: "pt-BR"
keywords:
  - "contador de membros discord canal de voz"
  - "discord member count voice channel bot"
  - "canal de estatísticas discord"
  - "discord.js renomear canal rate limit"
  - "intent GuildMembers discord.js"
---

# Contador de membros em canal de voz: bot que atualiza o nome sozinho

O canal de estatística mostra o total de membros no nome de um canal de voz que ninguém consegue entrar. O truque está no limite de renomeação do Discord, que só permite 2 mudanças a cada 10 minutos por canal.

> **Resposta rápida**
>
> Crie um canal de voz com a permissão Connect negada para @everyone, guarde o ID dele e rode uma rotina a cada 6 minutos que compara o nome atual com “Membros: {n}” e só chama `channel.setName()` se o número mudou. O Discord aceita só 2 renomeações a cada 10 minutos por canal, então não renomeie a cada entrada de membro. O total simples sai de `guild.memberCount`.

## Como o contador funciona

O canal de estatística é um canal de voz comum com o nome trocado pelo bot. Ele aparece na lista, perto do topo, com um texto como “Membros: 1.234”. Como é um canal de voz, o nome fica sempre visível na barra lateral, e como ninguém consegue entrar nele, serve só de painel.

São três peças:

- O canal, criado uma vez, com permissões que bloqueiam a entrada.
- A contagem, que vem de `guild.memberCount` ou do cache de membros.
- A rotina agendada que atualiza o nome sem passar do limite do Discord.

A terceira peça é onde quase todo tutorial erra: atualizar o nome em cada evento de entrada e saída parece lógico e quebra em servidor grande ou durante um raid, como você vai ver mais abaixo.

## A intent GuildMembers

No discord.js v14 você informa as intents no cliente. A `GuildMembers` é privilegiada e precisa ser ligada no portal de desenvolvedores, em Bot, Privileged Gateway Intents, Server Members Intent. Sem ligar lá, o bot não conecta e devolve o erro de intents não permitidas, tratado no guia de [erro de intents privilegiadas](https://streethosting.com.br/guias/bots-discord/bot-discord-erro-intents-privilegiadas).

```
const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [GatewayIntentBits.Guilds, GatewayIntentBits.GuildMembers],
});
```

Vale saber quando ela é realmente necessária. O total de membros, incluindo bots, está em `guild.memberCount`, mas é a intent que mantém esse número em dia: sem ela, o bot não recebe entradas e saídas, e o valor fica parado no momento em que ele conectou. Quem não quer a intent pode chamar `guild.fetch()` antes de cada atualização e usar o `approximateMemberCount`, que é aproximado. A intent passa a ser obrigatória quando você quer contar só pessoas (sem bots), contar quem tem um cargo, ou escutar `guildMemberAdd` e `guildMemberRemove`. Quando o bot chega a 100 servidores, ele precisa passar pela verificação do Discord, e a partir daí as intents privilegiadas dependem de aprovação.

Com a intent ligada, o discord.js mantém o cache de membros atualizado com as entradas e saídas. Para contar só humanos, busque os membros uma vez ao ligar e depois conte pelo cache:

```
// contagem.js
async function prepararCache(guild) {
  await guild.members.fetch(); // uma vez, ao ligar
}

function contarMembros(guild, semBots) {
  if (!semBots) return guild.memberCount;
  return guild.members.cache.filter((m) => !m.user.bot).size;
}

// formata como Membros: 1.234
function formatarNome(modelo, numero) {
  return modelo.replace('{n}', numero.toLocaleString('pt-BR'));
}

module.exports = { prepararCache, contarMembros, formatarNome };
```

O `toLocaleString('pt-BR')` coloca o ponto de milhar sozinho. Em servidores muito grandes, o `members.fetch()` completo demora e consome memória. Se for o seu caso e você só precisa do total, fique com `memberCount` e dispense a busca.

## Criar o canal que ninguém entra

A configuração que transforma um canal de voz em painel é uma negação de permissão. O cargo @everyone mantém o **View Channel** (ver o canal) e perde o **Connect** (conectar). O resultado é um canal visível, com o cadeado, em que ninguém consegue entrar:

```
const { ChannelType, PermissionFlagsBits } = require('discord.js');
const { contarMembros, formatarNome } = require('./contagem');

async function criarCanalContador(guild, modelo, semBots) {
  const canal = await guild.channels.create({
    name: formatarNome(modelo, contarMembros(guild, semBots)),
    type: ChannelType.GuildVoice,
    permissionOverwrites: [
      {
        id: guild.roles.everyone.id,
        allow: [PermissionFlagsBits.ViewChannel],
        deny: [PermissionFlagsBits.Connect],
      },
    ],
    reason: 'Canal de contador de membros',
  });

  // coloca no topo da lista
  await canal.setPosition(0).catch(() => {});
  return canal;
}
```

O bot precisa da permissão **Manage Channels** (Gerenciar Canais) no servidor para criar e renomear. Ele não precisa entrar no canal. Se você quiser reforçar, negue também `Speak` e `Stream`, mas só negar `Connect` já basta. Cargos de moderação com permissão de administrador ainda conseguem entrar, o que é esperado.

Guarde o ID do canal. Perder esse ID significa recriar o canal e deixar o antigo para trás. Uma tabela simples no SQLite resolve, e o comando `/contador criar` só chama a função acima e grava o resultado:

```
const Database = require('better-sqlite3');

const db = new Database('dados.db');
db.exec(`
  CREATE TABLE IF NOT EXISTS contadores (
    guild_id   TEXT PRIMARY KEY,
    channel_id TEXT NOT NULL,
    modelo     TEXT NOT NULL,
    sem_bots   INTEGER NOT NULL DEFAULT 0
  )
`);

const salvar = db.prepare(
  'INSERT OR REPLACE INTO contadores (guild_id, channel_id, modelo, sem_bots) VALUES (?, ?, ?, ?)'
);
const todos = db.prepare('SELECT * FROM contadores');
const remover = db.prepare('DELETE FROM contadores WHERE guild_id = ?');

// no handler de /contador criar (comando com setDefaultMemberPermissions(ManageChannels))
const canal = await criarCanalContador(interaction.guild, 'Membros: {n}', false);
salvar.run(interaction.guildId, canal.id, 'Membros: {n}', 0);
await interaction.reply({ content: 'Canal criado.', flags: MessageFlags.Ephemeral });
```

## O limite de 2 renomeações a cada 10 minutos

O Discord limita a mudança de nome de um canal a **2 vezes a cada 10 minutos por canal**. É um limite mais apertado do que o das demais rotas, e ele é por canal: renomear outro canal não consome o saldo deste.

O erro clássico é ligar a renomeação direto nos eventos:

```
// NÃO faça isso
client.on('guildMemberAdd', (m) => canal.setName(`Membros: ${m.guild.memberCount}`));
client.on('guildMemberRemove', (m) => canal.setName(`Membros: ${m.guild.memberCount}`));
```

Em um servidor movimentado entram e saem dezenas de pessoas por minuto, e em um raid entram centenas. Cada evento dispara uma renomeação, as duas primeiras passam e todas as demais batem no limite. O discord.js, por padrão, segura a requisição até a janela liberar, então as chamadas ficam empilhadas por minutos, e o nome do canal só mostra um número de dez minutos atrás. Pior: o acúmulo gasta memória e o bot pode ficar com a fila cheia de pedidos que já nem fazem mais sentido.

> **Atenção**
>
> Não tente contornar o limite com vários canais ou tentando de novo em loop. Insistir em rotas limitadas aumenta o risco de bloqueio temporário do bot por excesso de requisições. Veja como funciona o 429 em [corrigir rate limit 429 do Discord](https://streethosting.com.br/guias/bots-discord/corrigir-rate-limit-discord-429).

## Atualização agendada que respeita o limite

A solução é desacoplar: os eventos não renomeiam nada, e uma rotina com intervalo fixo confere o número e renomeia só se mudou. Um intervalo de 6 minutos garante no máximo 2 renomeações em qualquer janela de 10 minutos, e a comparação evita gastar uma chamada quando o número não mudou:

```
// atualizador.js
const { contarMembros, formatarNome, prepararCache } = require('./contagem');

const INTERVALO = 6 * 60 * 1000; // 6 minutos
let rodando = false;

async function atualizarTodos(client, db) {
  if (rodando) return;
  rodando = true;
  try {
    for (const linha of db.todos.all()) {
      const guild = client.guilds.cache.get(linha.guild_id);
      if (!guild) continue;

      try {
        const canal = await guild.channels.fetch(linha.channel_id).catch((err) => {
          if (err.code === 10003) return null; // 10003 = canal apagado
          throw err; // erro temporário: tenta de novo na próxima rodada
        });
        if (!canal) {
          db.remover.run(linha.guild_id); // canal apagado: para de tentar
          continue;
        }

        const nome = formatarNome(linha.modelo, contarMembros(guild, !!linha.sem_bots));
        if (canal.name !== nome) {
          await canal.setName(nome, 'Atualização do contador de membros');
        }
      } catch (err) {
        console.error(`Falha ao atualizar o contador de ${guild.name}:`, err);
      }
    }
  } finally {
    rodando = false;
  }
}

async function iniciarContador(client, db) {
  for (const guild of client.guilds.cache.values()) {
    await prepararCache(guild).catch((err) => console.error('Cache de membros:', err));
  }
  await atualizarTodos(client, db);
  setInterval(() => atualizarTodos(client, db), INTERVALO);
}

module.exports = { iniciarContador };
```

Chame `iniciarContador(client, { todos, remover })` no `Events.ClientReady`. O limite é por canal, e cada servidor tem o seu, então a rotina atende vários servidores sem problema. Se o bot reiniciar muitas vezes seguidas, a primeira atualização de cada partida também conta no limite, e o Discord apenas atrasa a requisição até liberar.

> **Dica**
>
> Quer um número que se mexe mais rápido? Não dá. O limite é do Discord, e nenhum bot passa dele. Se o servidor cresce tanto que 6 minutos de atraso incomodam, aceite o atraso ou mostre o número em uma mensagem fixa, que tem um limite bem mais folgado. Os eventos de entrada continuam úteis para outras coisas, como as [mensagens de boas vindas](https://streethosting.com.br/guias/bots-discord/bot-discord-boas-vindas-mensagem-automatica), e a mesma ideia de agenda serve para o [gerenciamento de canais de voz temporários](https://streethosting.com.br/guias/bots-discord/bot-discord-canais-voz-temporarios).

Outras estatísticas seguem o mesmo molde: número de bots, de canais ou de membros com um cargo. Cada uma é um canal separado, com a sua própria cota de renomeações, e a mesma rotina atende todos. Para quem está online, use o `approximatePresenceCount` que vem do `guild.fetch()`: é uma estimativa, mas dispensa a intent de presenças, bem mais pesada e privilegiada.

## Onde rodar na StreetHosting

O contador só atualiza enquanto o bot está ligado, e como a intent de membros mantém um cache em memória, vale escolher um plano com RAM de sobra. Na [hospedagem de bots da StreetHosting](https://streethosting.com.br/bots) seu código Node.js roda em um container com painel. O plano Discord Essential, de R$ 9,99 por mês, traz 1 GB de RAM e 2 GB de NVMe, suficiente para o contador em servidores pequenos e médios. Se o bot cuida de vários servidores grandes, o Discord Advanced, a R$ 19,99, dobra a RAM para 2 GB.

## Perguntas frequentes

### Por que o contador não atualiza na hora quando alguém entra?

Porque o Discord limita a renomeação de um canal a 2 vezes a cada 10 minutos. Se o bot renomeasse a cada entrada, os pedidos ficariam na fila e o número do canal ficaria atrasado de qualquer jeito. Atualizar a cada 6 minutos é mais previsível e nunca estoura o limite.

### Preciso da intent GuildMembers só para mostrar o total?

Não para o total simples, mas sem ela o guild.memberCount fica parado no valor do momento em que o bot conectou, porque as entradas e saídas não chegam. Nesse caso, chame guild.fetch() antes de cada atualização e use o approximateMemberCount. A intent Server Members é necessária quando você quer excluir bots da conta, contar por cargo ou reagir a entradas e saídas.

### Como impedir que alguém entre no canal de voz?

Negue a permissão Connect (Conectar) ao cargo @everyone no canal. O canal continua visível, mas o botão de entrar fica bloqueado. O bot não precisa entrar no canal, só de Manage Channels no servidor.

### O que acontece se eu estourar o limite de renomeação?

O Discord responde com erro 429 e a biblioteca segura a requisição até a janela liberar, o que pode deixar essa chamada pendurada por vários minutos. Por isso o ideal é uma rotina com intervalo fixo, e não uma renomeação por evento.

### Posso mostrar quantos membros estão online?

Um número aproximado, sim, sem intent privilegiada: guild.fetch() devolve o approximatePresenceCount, a estimativa de membros online. A contagem exata exige a intent GuildPresences, que é privilegiada e pesada, e para a maioria dos servidores não compensa.

## Guias relacionados

- [Erro Used disallowed intents no bot Discord: como corrigir](https://streethosting.com.br/guias/bots-discord/bot-discord-erro-intents-privilegiadas.md)
- [Como corrigir erro 429 rate limit no Discord](https://streethosting.com.br/guias/bots-discord/corrigir-rate-limit-discord-429.md)
- [Canais de voz temporários no Discord: o sistema entre para criar](https://streethosting.com.br/guias/bots-discord/bot-discord-canais-voz-temporarios.md)
- [Como configurar mensagem de boas-vindas automática no Discord com bot](https://streethosting.com.br/guias/bots-discord/bot-discord-boas-vindas-mensagem-automatica.md)
- [Como proteger o Discord contra raid e spam com um bot](https://streethosting.com.br/guias/bots-discord/bot-discord-anti-raid-anti-spam.md)

## Produtos citados

- https://streethosting.com.br/bots

## Dados estruturados

```json
[
  {
    "@context": "https://schema.org",
    "@type": [
      "Article",
      "TechArticle"
    ],
    "headline": "Contador de membros em canal de voz: bot que atualiza o nome sozinho",
    "name": "Contador de membros em canal de voz no Discord: como fazer com bot",
    "abstract": "O canal de estatística mostra o total de membros no nome de um canal de voz que ninguém consegue entrar. O truque está no limite de renomeação do Discord, que só permite 2 mudanças a cada 10 minutos por canal.",
    "description": "Crie um canal de voz com Membros: 1.234 no discord.js v14: intent GuildMembers, limite de 2 renomeações a cada 10 minutos e permissões para ninguém entrar.",
    "datePublished": "2026-11-13",
    "dateModified": "2026-11-13",
    "author": {
      "@type": "Organization",
      "name": "Equipe StreetHosting"
    },
    "publisher": {
      "@type": "Organization",
      "name": "StreetHosting",
      "url": "https://streethosting.com.br"
    },
    "inLanguage": "pt-BR",
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://streethosting.com.br/guias/bots-discord/bot-discord-contador-membros-canal-voz"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "Por que o contador não atualiza na hora quando alguém entra?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Porque o Discord limita a renomeação de um canal a 2 vezes a cada 10 minutos. Se o bot renomeasse a cada entrada, os pedidos ficariam na fila e o número do canal ficaria atrasado de qualquer jeito. Atualizar a cada 6 minutos é mais previsível e nunca estoura o limite."
        }
      },
      {
        "@type": "Question",
        "name": "Preciso da intent GuildMembers só para mostrar o total?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Não para o total simples, mas sem ela o guild.memberCount fica parado no valor do momento em que o bot conectou, porque as entradas e saídas não chegam. Nesse caso, chame guild.fetch() antes de cada atualização e use o approximateMemberCount. A intent Server Members é necessária quando você quer excluir bots da conta, contar por cargo ou reagir a entradas e saídas."
        }
      },
      {
        "@type": "Question",
        "name": "Como impedir que alguém entre no canal de voz?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Negue a permissão Connect (Conectar) ao cargo @everyone no canal. O canal continua visível, mas o botão de entrar fica bloqueado. O bot não precisa entrar no canal, só de Manage Channels no servidor."
        }
      },
      {
        "@type": "Question",
        "name": "O que acontece se eu estourar o limite de renomeação?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "O Discord responde com erro 429 e a biblioteca segura a requisição até a janela liberar, o que pode deixar essa chamada pendurada por vários minutos. Por isso o ideal é uma rotina com intervalo fixo, e não uma renomeação por evento."
        }
      },
      {
        "@type": "Question",
        "name": "Posso mostrar quantos membros estão online?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Um número aproximado, sim, sem intent privilegiada: guild.fetch() devolve o approximatePresenceCount, a estimativa de membros online. A contagem exata exige a intent GuildPresences, que é privilegiada e pesada, e para a maioria dos servidores não compensa."
        }
      }
    ]
  }
]
```
