mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-16 14:11:50 +00:00
Fix username change logging and saving. Re-enable migrations.
This commit is contained in:
parent
1b1ae98714
commit
e231faf51f
12 changed files with 255 additions and 119 deletions
|
@ -16,7 +16,7 @@
|
||||||
"MEMBER_ROLE_REMOVE": "🔑 {userMention(member)}: role(s) **{roles}** removed by {userMention(mod)}",
|
"MEMBER_ROLE_REMOVE": "🔑 {userMention(member)}: role(s) **{roles}** removed by {userMention(mod)}",
|
||||||
"MEMBER_ROLE_CHANGES": "🔑 {userMention(member)}: roles changed: added **{addedRoles}**, removed **{removedRoles}** by {userMention(mod)}",
|
"MEMBER_ROLE_CHANGES": "🔑 {userMention(member)}: roles changed: added **{addedRoles}**, removed **{removedRoles}** by {userMention(mod)}",
|
||||||
"MEMBER_NICK_CHANGE": "✏ {userMention(member)}: nickname changed from **{oldNick}** to **{newNick}**",
|
"MEMBER_NICK_CHANGE": "✏ {userMention(member)}: nickname changed from **{oldNick}** to **{newNick}**",
|
||||||
"MEMBER_USERNAME_CHANGE": "✏ {userMention(member)}: username changed from **{oldName}** to **{newName}**",
|
"MEMBER_USERNAME_CHANGE": "✏ {userMention(user)}: username changed from **{oldName}** to **{newName}**",
|
||||||
"MEMBER_RESTORE": "💿 Restored {restoredData} for {userMention(member)} on rejoin",
|
"MEMBER_RESTORE": "💿 Restored {restoredData} for {userMention(member)} on rejoin",
|
||||||
|
|
||||||
"CHANNEL_CREATE": "🖊 Channel {channelMention(channel)} was created",
|
"CHANNEL_CREATE": "🖊 Channel {channelMention(channel)} was created",
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
import { BaseRepository } from "./BaseRepository";
|
|
||||||
import { getRepository, Repository } from "typeorm";
|
|
||||||
import { NameHistoryEntry } from "./entities/NameHistoryEntry";
|
|
||||||
|
|
||||||
const MAX_ENTRIES_PER_USER = 10;
|
|
||||||
|
|
||||||
export class GuildNameHistory extends BaseRepository {
|
|
||||||
private nameHistory: Repository<NameHistoryEntry>;
|
|
||||||
|
|
||||||
constructor(guildId) {
|
|
||||||
super(guildId);
|
|
||||||
this.nameHistory = getRepository(NameHistoryEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getByUserId(userId): Promise<NameHistoryEntry[]> {
|
|
||||||
return this.nameHistory.find({
|
|
||||||
where: {
|
|
||||||
guild_id: this.guildId,
|
|
||||||
user_id: userId
|
|
||||||
},
|
|
||||||
order: {
|
|
||||||
id: "DESC"
|
|
||||||
},
|
|
||||||
take: MAX_ENTRIES_PER_USER
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getLastEntryByType(userId, type): Promise<NameHistoryEntry> {
|
|
||||||
return this.nameHistory.findOne({
|
|
||||||
where: {
|
|
||||||
guild_id: this.guildId,
|
|
||||||
user_id: userId,
|
|
||||||
type
|
|
||||||
},
|
|
||||||
order: {
|
|
||||||
id: "DESC"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async addEntry(userId, type, value) {
|
|
||||||
await this.nameHistory.insert({
|
|
||||||
guild_id: this.guildId,
|
|
||||||
user_id: userId,
|
|
||||||
type,
|
|
||||||
value
|
|
||||||
});
|
|
||||||
|
|
||||||
// Cleanup (leave only the last MAX_ENTRIES_PER_USER entries)
|
|
||||||
const lastEntries = await this.getByUserId(userId);
|
|
||||||
if (lastEntries.length > MAX_ENTRIES_PER_USER) {
|
|
||||||
const earliestEntry = lastEntries[lastEntries.length - 1];
|
|
||||||
if (!earliestEntry) return;
|
|
||||||
|
|
||||||
this.nameHistory
|
|
||||||
.createQueryBuilder()
|
|
||||||
.where("guild_id = :guildId", { guildId: this.guildId })
|
|
||||||
.andWhere("user_id = :userId", { userId })
|
|
||||||
.andWhere("id < :id", { id: earliestEntry.id })
|
|
||||||
.delete()
|
|
||||||
.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
68
src/data/GuildNicknameHistory.ts
Normal file
68
src/data/GuildNicknameHistory.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import { BaseRepository } from "./BaseRepository";
|
||||||
|
import { getRepository, Repository } from "typeorm";
|
||||||
|
import { NicknameHistoryEntry } from "./entities/NicknameHistoryEntry";
|
||||||
|
import { sorter } from "../utils";
|
||||||
|
|
||||||
|
export const MAX_NICKNAME_ENTRIES_PER_USER = 10;
|
||||||
|
|
||||||
|
export class GuildNicknameHistory extends BaseRepository {
|
||||||
|
private nicknameHistory: Repository<NicknameHistoryEntry>;
|
||||||
|
|
||||||
|
constructor(guildId) {
|
||||||
|
super(guildId);
|
||||||
|
this.nicknameHistory = getRepository(NicknameHistoryEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getByUserId(userId): Promise<NicknameHistoryEntry[]> {
|
||||||
|
return this.nicknameHistory.find({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId,
|
||||||
|
user_id: userId,
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
id: "DESC",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getLastEntry(userId): Promise<NicknameHistoryEntry> {
|
||||||
|
return this.nicknameHistory.findOne({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId,
|
||||||
|
user_id: userId,
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
id: "DESC",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async addEntry(userId, nickname) {
|
||||||
|
await this.nicknameHistory.insert({
|
||||||
|
guild_id: this.guildId,
|
||||||
|
user_id: userId,
|
||||||
|
nickname,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cleanup (leave only the last MAX_NICKNAME_ENTRIES_PER_USER entries)
|
||||||
|
const lastEntries = await this.getByUserId(userId);
|
||||||
|
if (lastEntries.length > MAX_NICKNAME_ENTRIES_PER_USER) {
|
||||||
|
const earliestEntry = lastEntries
|
||||||
|
.sort(sorter("timestamp", "DESC"))
|
||||||
|
.slice(0, 10)
|
||||||
|
.reduce((earliest, entry) => {
|
||||||
|
if (earliest == null) return entry;
|
||||||
|
if (entry.id < earliest.id) return entry;
|
||||||
|
return earliest;
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
this.nicknameHistory
|
||||||
|
.createQueryBuilder()
|
||||||
|
.where("guild_id = :guildId", { guildId: this.guildId })
|
||||||
|
.andWhere("user_id = :userId", { userId })
|
||||||
|
.andWhere("id < :id", { id: earliestEntry.id })
|
||||||
|
.delete()
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +0,0 @@
|
||||||
export enum NameHistoryEntryTypes {
|
|
||||||
Username = 1,
|
|
||||||
Nickname
|
|
||||||
}
|
|
67
src/data/UsernameHistory.ts
Normal file
67
src/data/UsernameHistory.ts
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
import { BaseRepository } from "./BaseRepository";
|
||||||
|
import { getRepository, Repository } from "typeorm";
|
||||||
|
import { UsernameHistoryEntry } from "./entities/UsernameHistoryEntry";
|
||||||
|
import { sorter } from "../utils";
|
||||||
|
|
||||||
|
export const MAX_USERNAME_ENTRIES_PER_USER = 10;
|
||||||
|
|
||||||
|
export class UsernameHistory extends BaseRepository {
|
||||||
|
private usernameHistory: Repository<UsernameHistoryEntry>;
|
||||||
|
|
||||||
|
constructor(guildId) {
|
||||||
|
super(guildId);
|
||||||
|
this.usernameHistory = getRepository(UsernameHistoryEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getByUserId(userId): Promise<UsernameHistoryEntry[]> {
|
||||||
|
return this.usernameHistory.find({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId,
|
||||||
|
user_id: userId,
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
id: "DESC",
|
||||||
|
},
|
||||||
|
take: MAX_USERNAME_ENTRIES_PER_USER,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getLastEntry(userId): Promise<UsernameHistoryEntry> {
|
||||||
|
return this.usernameHistory.findOne({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId,
|
||||||
|
user_id: userId,
|
||||||
|
},
|
||||||
|
order: {
|
||||||
|
id: "DESC",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async addEntry(userId, username) {
|
||||||
|
await this.usernameHistory.insert({
|
||||||
|
user_id: userId,
|
||||||
|
username,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Cleanup (leave only the last MAX_USERNAME_ENTRIES_PER_USER entries)
|
||||||
|
const lastEntries = await this.getByUserId(userId);
|
||||||
|
if (lastEntries.length > MAX_USERNAME_ENTRIES_PER_USER) {
|
||||||
|
const earliestEntry = lastEntries
|
||||||
|
.sort(sorter("timestamp", "DESC"))
|
||||||
|
.slice(0, 10)
|
||||||
|
.reduce((earliest, entry) => {
|
||||||
|
if (earliest == null) return entry;
|
||||||
|
if (entry.id < earliest.id) return entry;
|
||||||
|
return earliest;
|
||||||
|
}, null);
|
||||||
|
|
||||||
|
this.usernameHistory
|
||||||
|
.createQueryBuilder()
|
||||||
|
.andWhere("user_id = :userId", { userId })
|
||||||
|
.andWhere("id < :id", { id: earliestEntry.id })
|
||||||
|
.delete()
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
import { Entity, Column, PrimaryColumn } from "typeorm";
|
import { Entity, Column, PrimaryColumn } from "typeorm";
|
||||||
|
|
||||||
@Entity("name_history")
|
@Entity("nickname_history")
|
||||||
export class NameHistoryEntry {
|
export class NicknameHistoryEntry {
|
||||||
@Column()
|
@Column()
|
||||||
@PrimaryColumn()
|
@PrimaryColumn()
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -10,9 +10,7 @@ export class NameHistoryEntry {
|
||||||
|
|
||||||
@Column() user_id: string;
|
@Column() user_id: string;
|
||||||
|
|
||||||
@Column() type: number;
|
@Column() nickname: string;
|
||||||
|
|
||||||
@Column() value: string;
|
|
||||||
|
|
||||||
@Column() timestamp: string;
|
@Column() timestamp: string;
|
||||||
}
|
}
|
14
src/data/entities/UsernameHistoryEntry.ts
Normal file
14
src/data/entities/UsernameHistoryEntry.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { Entity, Column, PrimaryColumn } from "typeorm";
|
||||||
|
|
||||||
|
@Entity("username_history")
|
||||||
|
export class UsernameHistoryEntry {
|
||||||
|
@Column()
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@Column() user_id: string;
|
||||||
|
|
||||||
|
@Column() username: string;
|
||||||
|
|
||||||
|
@Column() timestamp: string;
|
||||||
|
}
|
|
@ -91,11 +91,12 @@ import { errorMessage, successMessage } from "./utils";
|
||||||
import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin";
|
import { ZeppelinPlugin } from "./plugins/ZeppelinPlugin";
|
||||||
import { customArgumentTypes } from "./customArgumentTypes";
|
import { customArgumentTypes } from "./customArgumentTypes";
|
||||||
import { startUptimeCounter } from "./uptime";
|
import { startUptimeCounter } from "./uptime";
|
||||||
|
import { UsernameSaver } from "./plugins/UsernameSaver";
|
||||||
|
|
||||||
// Run latest database migrations
|
// Run latest database migrations
|
||||||
logger.info("Running database migrations");
|
logger.info("Running database migrations");
|
||||||
connect().then(async conn => {
|
connect().then(async conn => {
|
||||||
// await conn.runMigrations();
|
await conn.runMigrations();
|
||||||
|
|
||||||
const client = new Client(`Bot ${process.env.TOKEN}`, {
|
const client = new Client(`Bot ${process.env.TOKEN}`, {
|
||||||
getAllUsers: true,
|
getAllUsers: true,
|
||||||
|
@ -137,7 +138,7 @@ connect().then(async conn => {
|
||||||
RemindersPlugin,
|
RemindersPlugin,
|
||||||
],
|
],
|
||||||
|
|
||||||
globalPlugins: [BotControlPlugin, LogServerPlugin],
|
globalPlugins: [BotControlPlugin, LogServerPlugin, UsernameSaver],
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
getEnabledPlugins(guildId, guildConfig): string[] {
|
getEnabledPlugins(guildId, guildConfig): string[] {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { MigrationInterface, QueryRunner, TableColumn } from "typeorm";
|
||||||
|
|
||||||
|
export class TurnNameHistoryToNicknameHistory1556913287547 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.dropColumn("name_history", "type");
|
||||||
|
|
||||||
|
// As a raw query because of some bug with renameColumn that generated an invalid query
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE \`name_history\`
|
||||||
|
CHANGE COLUMN \`value\` \`nickname\` VARCHAR(160) NULL DEFAULT 'NULL' COLLATE 'utf8mb4_swedish_ci' AFTER \`user_id\`;
|
||||||
|
`);
|
||||||
|
|
||||||
|
// Drop unneeded timestamp column index
|
||||||
|
await queryRunner.dropIndex("name_history", "IDX_6bd0600f9d55d4e4a08b508999");
|
||||||
|
|
||||||
|
await queryRunner.renameTable("name_history", "nickname_history");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.addColumn(
|
||||||
|
"nickname_history",
|
||||||
|
new TableColumn({
|
||||||
|
name: "type",
|
||||||
|
type: "tinyint",
|
||||||
|
unsigned: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// As a raw query because of some bug with renameColumn that generated an invalid query
|
||||||
|
await queryRunner.query(`
|
||||||
|
ALTER TABLE \`nickname_history\`
|
||||||
|
CHANGE COLUMN \`nickname\` \`value\` VARCHAR(160) NULL DEFAULT 'NULL' COLLATE 'utf8mb4_swedish_ci' AFTER \`user_id\`
|
||||||
|
`);
|
||||||
|
|
||||||
|
await queryRunner.renameTable("nickname_history", "name_history");
|
||||||
|
}
|
||||||
|
}
|
|
@ -397,14 +397,13 @@ export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.event("userUpdate")
|
@d.event("userUpdate", null, false)
|
||||||
async onUserUpdate(user: User, oldUser: User) {
|
async onUserUpdate(user: User, oldUser: User) {
|
||||||
if (!oldUser) return;
|
if (!oldUser) return;
|
||||||
|
|
||||||
if (user.username !== oldUser.username || user.discriminator !== oldUser.discriminator) {
|
if (user.username !== oldUser.username || user.discriminator !== oldUser.discriminator) {
|
||||||
const member = (await this.getMember(user.id)) || { id: user.id, user };
|
|
||||||
this.guildLogs.log(LogType.MEMBER_USERNAME_CHANGE, {
|
this.guildLogs.log(LogType.MEMBER_USERNAME_CHANGE, {
|
||||||
member: stripObjectToScalars(member, ["user", "roles"]),
|
user: stripObjectToScalars(user),
|
||||||
oldName: `${oldUser.username}#${oldUser.discriminator}`,
|
oldName: `${oldUser.username}#${oldUser.discriminator}`,
|
||||||
newName: `${user.username}#${user.discriminator}`,
|
newName: `${user.username}#${user.discriminator}`,
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { decorators as d, IPluginOptions } from "knub";
|
import { decorators as d, IPluginOptions } from "knub";
|
||||||
import { GuildNameHistory } from "../data/GuildNameHistory";
|
import { GuildNicknameHistory, MAX_NICKNAME_ENTRIES_PER_USER } from "../data/GuildNicknameHistory";
|
||||||
import { Member, Message, User } from "eris";
|
import { Member, Message } from "eris";
|
||||||
import { NameHistoryEntryTypes } from "../data/NameHistoryEntryTypes";
|
import { createChunkedMessage, disableCodeBlocks } from "../utils";
|
||||||
import { createChunkedMessage, errorMessage, trimLines } from "../utils";
|
|
||||||
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
import { ZeppelinPlugin } from "./ZeppelinPlugin";
|
||||||
|
import { MAX_USERNAME_ENTRIES_PER_USER, UsernameHistory } from "../data/UsernameHistory";
|
||||||
|
|
||||||
interface INameHistoryPluginConfig {
|
interface INameHistoryPluginConfig {
|
||||||
can_view: boolean;
|
can_view: boolean;
|
||||||
|
@ -12,7 +12,8 @@ interface INameHistoryPluginConfig {
|
||||||
export class NameHistoryPlugin extends ZeppelinPlugin<INameHistoryPluginConfig> {
|
export class NameHistoryPlugin extends ZeppelinPlugin<INameHistoryPluginConfig> {
|
||||||
public static pluginName = "name_history";
|
public static pluginName = "name_history";
|
||||||
|
|
||||||
protected nameHistory: GuildNameHistory;
|
protected nicknameHistory: GuildNicknameHistory;
|
||||||
|
protected usernameHistory: UsernameHistory;
|
||||||
|
|
||||||
getDefaultOptions(): IPluginOptions<INameHistoryPluginConfig> {
|
getDefaultOptions(): IPluginOptions<INameHistoryPluginConfig> {
|
||||||
return {
|
return {
|
||||||
|
@ -32,57 +33,45 @@ export class NameHistoryPlugin extends ZeppelinPlugin<INameHistoryPluginConfig>
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
this.nameHistory = GuildNameHistory.getInstance(this.guildId);
|
this.nicknameHistory = GuildNicknameHistory.getInstance(this.guildId);
|
||||||
|
this.usernameHistory = UsernameHistory.getInstance(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@d.command("names", "<userId:userid>")
|
@d.command("names", "<userId:userid>")
|
||||||
@d.permission("can_view")
|
@d.permission("can_view")
|
||||||
async namesCmd(msg: Message, args: { userId: string }) {
|
async namesCmd(msg: Message, args: { userId: string }) {
|
||||||
const names = await this.nameHistory.getByUserId(args.userId);
|
const nicknames = await this.nicknameHistory.getByUserId(args.userId);
|
||||||
if (!names) {
|
const usernames = await this.usernameHistory.getByUserId(args.userId);
|
||||||
msg.channel.createMessage(errorMessage("No name history found for that user!"));
|
|
||||||
return;
|
if (nicknames.length === 0 && usernames.length === 0) {
|
||||||
|
return this.sendErrorMessage(msg.channel, "No name history found");
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = names.map(entry => {
|
const nicknameRows = nicknames.map(
|
||||||
const type = entry.type === NameHistoryEntryTypes.Username ? "Username" : "Nickname";
|
r => `\`[${r.timestamp}]\` ${r.nickname ? `**${disableCodeBlocks(r.nickname)}**` : "*None*"}`,
|
||||||
const value = entry.value || "<none>";
|
);
|
||||||
return `\`[${entry.timestamp}]\` ${type} **${value}**`;
|
const usernameRows = usernames.map(r => `\`[${r.timestamp}]\` **${disableCodeBlocks(r.username)}**`);
|
||||||
});
|
|
||||||
|
|
||||||
const user = this.bot.users.get(args.userId);
|
const user = this.bot.users.get(args.userId);
|
||||||
const currentUsername = user ? `${user.username}#${user.discriminator}` : args.userId;
|
const currentUsername = user ? `${user.username}#${user.discriminator}` : args.userId;
|
||||||
|
|
||||||
const message = trimLines(`
|
let message = `Name history for **${currentUsername}**:`;
|
||||||
Name history for **${currentUsername}**:
|
if (nicknameRows.length) {
|
||||||
|
message += `\n\n__Last ${MAX_NICKNAME_ENTRIES_PER_USER} nicknames:__\n${nicknameRows.join("\n")}`;
|
||||||
${rows.join("\n")}
|
}
|
||||||
`);
|
if (usernameRows.length) {
|
||||||
|
message += `\n\n__Last ${MAX_USERNAME_ENTRIES_PER_USER} usernames:__\n${usernameRows.join("\n")}`;
|
||||||
|
}
|
||||||
|
|
||||||
createChunkedMessage(msg.channel, message);
|
createChunkedMessage(msg.channel, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @d.event("userUpdate", null, false)
|
|
||||||
// async onUserUpdate(user: User, oldUser: { username: string; discriminator: string; avatar: string }) {
|
|
||||||
// if (user.username !== oldUser.username || user.discriminator !== oldUser.discriminator) {
|
|
||||||
// const newUsername = `${user.username}#${user.discriminator}`;
|
|
||||||
// await this.nameHistory.addEntry(user.id, NameHistoryEntryTypes.Username, newUsername);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@d.event("guildMemberUpdate")
|
@d.event("guildMemberUpdate")
|
||||||
async onGuildMemberUpdate(_, member: Member) {
|
async onGuildMemberUpdate(_, member: Member) {
|
||||||
const latestEntry = await this.nameHistory.getLastEntryByType(member.id, NameHistoryEntryTypes.Nickname);
|
const latestEntry = await this.nicknameHistory.getLastEntry(member.id);
|
||||||
if (!latestEntry || latestEntry.value !== member.nick) {
|
if (!latestEntry || latestEntry.nickname != member.nick) {
|
||||||
await this.nameHistory.addEntry(member.id, NameHistoryEntryTypes.Nickname, member.nick);
|
// tslint:disable-line
|
||||||
|
await this.nicknameHistory.addEntry(member.id, member.nick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @d.event("guildMemberAdd")
|
|
||||||
// async onGuildMemberAdd(_, member: Member) {
|
|
||||||
// const latestEntry = await this.nameHistory.getLastEntryByType(member.id, NameHistoryEntryTypes.Username);
|
|
||||||
// const username = `${member.user.username}#${member.user.discriminator}`;
|
|
||||||
// if (!latestEntry || latestEntry.value !== username) {
|
|
||||||
// await this.nameHistory.addEntry(member.id, NameHistoryEntryTypes.Username, username);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
31
src/plugins/UsernameSaver.ts
Normal file
31
src/plugins/UsernameSaver.ts
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
import { decorators as d, GlobalPlugin } from "knub";
|
||||||
|
import { UsernameHistory } from "../data/UsernameHistory";
|
||||||
|
import { Member, User } from "eris";
|
||||||
|
|
||||||
|
export class UsernameSaver extends GlobalPlugin {
|
||||||
|
public static pluginName = "username_saver";
|
||||||
|
|
||||||
|
protected usernameHistory: UsernameHistory;
|
||||||
|
|
||||||
|
async onLoad() {
|
||||||
|
this.usernameHistory = UsernameHistory.getInstance(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async updateUsername(user: User) {
|
||||||
|
const newUsername = `${user.username}#${user.discriminator}`;
|
||||||
|
const latestEntry = await this.usernameHistory.getLastEntry(user.id);
|
||||||
|
if (newUsername !== latestEntry.username) {
|
||||||
|
await this.usernameHistory.addEntry(user.id, newUsername);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("userUpdate", null, false)
|
||||||
|
async onUserUpdate(user: User) {
|
||||||
|
this.updateUsername(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("guildMemberAdd", null, false)
|
||||||
|
async onGuildMemberAdd(_, member: Member) {
|
||||||
|
this.updateUsername(member.user);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue