-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
182 lines (163 loc) · 6.3 KB
/
index.js
File metadata and controls
182 lines (163 loc) · 6.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
// Main bot logic for MarnicBot
const { Client, GatewayIntentBits, Partials } = require('discord.js');
const sqlite3 = require('sqlite3').verbose();
const path = require('path');
// === CONFIGURATION ===
const BOT_TOKEN = 'YOUR_BOT_TOKEN'; // <-- Replace with your bot token
const ACTIVE_ROLE_NAME = 'Active';
const INACTIVE_ROLE_NAME = 'Inactive';
const CHECK_INTERVAL_HOURS = 12; // How often to check for inactive users
const INACTIVE_DAYS = 7; // Days of inactivity before switching to Inactive
// === DATABASE SETUP ===
const db = new sqlite3.Database(path.join(__dirname, 'activity.sqlite'));
db.serialize(() => {
db.run('CREATE TABLE IF NOT EXISTS user_activity (user_id TEXT PRIMARY KEY, last_message INTEGER)');
});
// === DISCORD CLIENT SETUP ===
const client = new Client({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent,
GatewayIntentBits.GuildMembers
],
partials: [Partials.Message, Partials.Channel, Partials.GuildMember]
});
// === HELPER FUNCTIONS ===
function updateLastMessage(userId, timestamp) {
db.run(
'INSERT INTO user_activity (user_id, last_message) VALUES (?, ?) ON CONFLICT(user_id) DO UPDATE SET last_message=excluded.last_message',
[userId, timestamp],
(err) => {
if (err) console.error('Database error updating last message:', err);
}
);
}
function getLastMessage(userId, cb) {
db.get('SELECT last_message FROM user_activity WHERE user_id = ?', [userId], (err, row) => {
if (err) return cb(null);
cb(row ? row.last_message : null);
});
}
async function setRole(member, roleName, add) {
try {
const role = member.guild.roles.cache.find(r => r.name === roleName);
if (!role) return;
if (add) {
if (!member.roles.cache.has(role.id)) await member.roles.add(role);
} else {
if (member.roles.cache.has(role.id)) await member.roles.remove(role);
}
} catch (error) {
console.error(`Error setting role ${roleName} for ${member.user.tag}:`, error.message);
}
}
// === EVENT: On Message ===
client.on('messageCreate', async (message) => {
try {
if (message.author.bot || !message.guild) return;
const userId = message.author.id;
const now = Date.now();
updateLastMessage(userId, now);
// Check if user is currently inactive and needs to be re-activated
const member = await message.guild.members.fetch(userId);
const hasInactive = member.roles.cache.some(r => r.name === INACTIVE_ROLE_NAME);
const hasActive = member.roles.cache.some(r => r.name === ACTIVE_ROLE_NAME);
let roleChanged = false;
if (hasInactive) {
await setRole(member, INACTIVE_ROLE_NAME, false);
roleChanged = true;
}
if (!hasActive) {
await setRole(member, ACTIVE_ROLE_NAME, true);
roleChanged = true;
}
// Logging: only log if roles were changed
if (roleChanged) {
message.guild.channels.cache.forEach(channel => {
if (
channel.type === 0 && // 0 = GuildText in discord.js v14
channel.name.toLowerCase().includes('log') &&
channel.id !== message.channel.id // avoid echoing in the same channel
) {
channel.send({
content: `[${message.author.tag}] in #${message.channel.name}: ${message.content}`
}).catch(() => {});
}
});
}
} catch (error) {
console.error('Error in messageCreate event:', error);
}
});
// === PERIODIC CHECK FOR INACTIVE USERS ===
async function checkInactiveUsers() {
try {
for (const [guildId, guild] of client.guilds.cache) {
try {
const activeRole = guild.roles.cache.find(r => r.name === ACTIVE_ROLE_NAME);
const inactiveRole = guild.roles.cache.find(r => r.name === INACTIVE_ROLE_NAME);
if (!activeRole || !inactiveRole) continue;
const members = await guild.members.fetch();
for (const [memberId, member] of members) {
if (member.user.bot) continue;
getLastMessage(member.id, async (lastMsg) => {
try {
const now = Date.now();
const isInactive = !lastMsg || now - lastMsg > INACTIVE_DAYS * 24 * 60 * 60 * 1000;
const hasActive = member.roles.cache.has(activeRole.id);
const hasInactive = member.roles.cache.has(inactiveRole.id);
if (isInactive && !hasInactive) {
// Became inactive
await setRole(member, ACTIVE_ROLE_NAME, false);
await setRole(member, INACTIVE_ROLE_NAME, true);
// Logging for inactivity
guild.channels.cache.forEach(channel => {
if (channel.type === 0 && channel.name.toLowerCase().includes('log')) {
channel.send({
content: `[${member.user.tag}] became INACTIVE.`
}).catch(() => {});
}
});
} else if (!isInactive && !hasActive) {
// Became active
await setRole(member, INACTIVE_ROLE_NAME, false);
await setRole(member, ACTIVE_ROLE_NAME, true);
// Logging for activity
guild.channels.cache.forEach(channel => {
if (channel.type === 0 && channel.name.toLowerCase().includes('log')) {
channel.send({
content: `[${member.user.tag}] became ACTIVE.`
}).catch(() => {});
}
});
}
} catch (error) {
console.error(`Error processing member ${member.user.tag}:`, error.message);
}
});
}
} catch (error) {
console.error(`Error checking guild ${guild.name}:`, error.message);
}
}
} catch (error) {
console.error('Error in checkInactiveUsers:', error);
}
}
setInterval(checkInactiveUsers, CHECK_INTERVAL_HOURS * 60 * 60 * 1000);
// === ERROR HANDLERS ===
client.on('error', (error) => {
console.error('Discord client error:', error);
});
process.on('unhandledRejection', (error) => {
console.error('Unhandled promise rejection:', error);
});
client.once('ready', () => {
console.log(`Logged in as ${client.user.tag}`);
checkInactiveUsers();
});
client.login(BOT_TOKEN).catch((error) => {
console.error('Failed to login:', error);
process.exit(1);
});