- Katılım
- 9 Şub 2024
- Mesajlar
- 925
- Tepkime puanı
- 1,765
- Puanları
- 93
jhaeger
Discord Davet Takip (Invite Logger) Sistemi Nasıl Yapılır?
discord.js v14 ile kimin kimi davet ettiğini takip eden bot
discord.js v14 ile kimin kimi davet ettiğini takip eden bot
Davet takip sistemi nedir?
Bir kullanıcı sunucuya katıldığında hangi davet linkiyle ve kim tarafından geldiğini gösteren sisteme invite logger denir. Şu işler için kullanılır:
- Kimin kaç kişi davet ettiğini görmek
- Davet yarışması ve ödüllü etkinlik düzenlemek
- Sahte hesap ve spam girişlerini fark etmek
- Giriş-çıkış loglarını tutmak
Sistem nasıl çalışır?
Discord bize "bu kullanıcı şu linkle girdi" demez. Bu yüzden şu mantığı kullanırız:
- Bot açılınca sunucudaki tüm davetleri ve kullanım sayılarını hafızaya alır.
- Biri sunucuya girince davetler tekrar çekilir.
- Kullanım sayısı artan davet bulunur, o davetin sahibi davet eden kişidir.
- Hafıza güncellenir.
Gerekenler
- Node.js 18 veya üstü
- discord.js v14 (
npm i discord.js) - Botta Sunucuyu Yönet (Manage Server) yetkisi (davetleri okumak için şart)
- Developer Portal'da Server Members Intent açık olmalı
- Bildirimlerin gideceği bir log kanalı
Kod
JavaScript:
const { Client, GatewayIntentBits, Collection, EmbedBuilder, Events } = require('discord.js');
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildInvites
]
});
const LOG_CHANNEL_ID = 'LOG_KANAL_ID';
// guildId -> (davet kodu -> kullanım sayısı)
const invitesCache = new Collection();
// "guildId-userId" -> daveti yapan kişinin ID'si
const inviterOf = new Map();
// "guildId-inviterId" -> toplam davet sayısı
const inviteCounts = new Map();
const toCache = (invites) => new Collection(invites.map(i => [i.code, i.uses]));
client.once(Events.ClientReady, async () => {
for (const guild of client.guilds.cache.values()) {
try {
invitesCache.set(guild.id, toCache(await guild.invites.fetch()));
} catch {
console.log(`${guild.name}: davetler okunamadı (yetki eksik olabilir)`);
}
}
console.log(`${client.user.tag} hazır, davet takibi aktif.`);
});
// Yeni davet oluşturulunca hafızaya ekle
client.on(Events.InviteCreate, (invite) => {
const cache = invitesCache.get(invite.guild.id) ?? new Collection();
cache.set(invite.code, invite.uses ?? 0);
invitesCache.set(invite.guild.id, cache);
});
// Davet silinince hafızadan çıkar
client.on(Events.InviteDelete, (invite) => {
invitesCache.get(invite.guild.id)?.delete(invite.code);
});
// Üye girince hangi davet kullanıldı?
client.on(Events.GuildMemberAdd, async (member) => {
const cached = invitesCache.get(member.guild.id);
let newInvites;
try {
newInvites = await member.guild.invites.fetch();
} catch {
return;
}
const used = newInvites.find(i => i.uses > (cached?.get(i.code) ?? 0));
invitesCache.set(member.guild.id, toCache(newInvites));
const logChannel = member.guild.channels.cache.get(LOG_CHANNEL_ID);
if (!logChannel) return;
const embed = new EmbedBuilder()
.setColor(0x57f287)
.setTitle('Yeni Üye Katıldı')
.setThumbnail(member.user.displayAvatarURL());
if (used && used.inviter) {
const key = `${member.guild.id}-${used.inviter.id}`;
inviteCounts.set(key, (inviteCounts.get(key) ?? 0) + 1);
inviterOf.set(`${member.guild.id}-${member.id}`, used.inviter.id);
embed.setDescription(
`${member} sunucuya katıldı.\n` +
`**Davet eden:** ${used.inviter}\n` +
`**Davet kodu:** \`${used.code}\`\n` +
`**Toplam daveti:** ${inviteCounts.get(key)}`
);
} else {
embed.setDescription(`${member} sunucuya katıldı.\n**Davet eden:** Bulunamadı (özel URL veya tek kullanımlık davet olabilir)`);
}
logChannel.send({ embeds: [embed] });
});
// Üye çıkınca davet edenin sayısını düşür
client.on(Events.GuildMemberRemove, async (member) => {
const inviterId = inviterOf.get(`${member.guild.id}-${member.id}`);
const logChannel = member.guild.channels.cache.get(LOG_CHANNEL_ID);
if (!logChannel) return;
const embed = new EmbedBuilder()
.setColor(0xed4245)
.setTitle('Üye Ayrıldı');
if (inviterId) {
const key = `${member.guild.id}-${inviterId}`;
inviteCounts.set(key, Math.max((inviteCounts.get(key) ?? 1) - 1, 0));
embed.setDescription(`**${member.user.tag}** sunucudan ayrıldı.\n**Onu davet eden:** <@${inviterId}>\n**Kalan daveti:** ${inviteCounts.get(key)}`);
} else {
embed.setDescription(`**${member.user.tag}** sunucudan ayrıldı.`);
}
logChannel.send({ embeds: [embed] });
});
client.login('BOT_TOKEN');
Sık yapılan hatalar
- Davet eden hep "bulunamadı" çıkıyor: Botta Sunucuyu Yönet yetkisi yoktur veya
GuildInvitesintent'i eksiktir. - Üye girince bot hiç tepki vermiyor: Developer Portal'da Server Members Intent kapalıdır.
- Özel URL (vanity) ile girenler: Vanity URL ile girenleri bu yöntemle yakalayamazsınız, ayrıca ele almak gerekir.
- Tek kullanımlık davetler: Kullanıldıktan sonra silindiği için yeni listede görünmez, davet eden bulunamaz.
- Bot kapanınca sayılar sıfırlanıyor: Kodda sayılar hafızada tutuluyor. Kalıcı olması için veritabanına kaydetmek gerekir (aşağıdaki rehbere bakın).
Sonraki adımlar
- Davet sayılarını veritabanına kaydedip botun yeniden başlamasından etkilenmemesini sağlamak: "Discord Botunda Veritabanı Kullanmak: Kalıcı Kayıt Sistemi" rehberine bakabilirsiniz.
/davetlerimslash komutu ekleyip herkesin kendi davet sayısını görmesini sağlamak- Davet liderlik tablosu yapmak
- X kişi davet edene otomatik rol vermek
Sorusu olan veya hata alan olursa konunun altına yazsın, birlikte çözelim.
Son düzenleme:




