mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-03-15 05:41:51 +00:00
Add support for pingable roles
This commit is contained in:
parent
d3a4989dc0
commit
3efd64c489
5 changed files with 257 additions and 1 deletions
55
src/data/GuildPingableRoles.ts
Normal file
55
src/data/GuildPingableRoles.ts
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
import { BaseRepository } from "./BaseRepository";
|
||||||
|
import { getRepository, Repository } from "typeorm";
|
||||||
|
import { PingableRole } from "./entities/PingableRole";
|
||||||
|
|
||||||
|
export class GuildPingableRoles extends BaseRepository {
|
||||||
|
private pingableRoles: Repository<PingableRole>;
|
||||||
|
|
||||||
|
constructor(guildId) {
|
||||||
|
super(guildId);
|
||||||
|
this.pingableRoles = getRepository(PingableRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
async all(): Promise<PingableRole[]> {
|
||||||
|
return this.pingableRoles.find({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getForChannel(channelId: string): Promise<PingableRole[]> {
|
||||||
|
return this.pingableRoles.find({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId,
|
||||||
|
channel_id: channelId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getByChannelAndRoleId(channelId: string, roleId: string): Promise<PingableRole> {
|
||||||
|
return this.pingableRoles.findOne({
|
||||||
|
where: {
|
||||||
|
guild_id: this.guildId,
|
||||||
|
channel_id: channelId,
|
||||||
|
role_id: roleId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(channelId: string, roleId: string) {
|
||||||
|
await this.pingableRoles.delete({
|
||||||
|
guild_id: this.guildId,
|
||||||
|
channel_id: channelId,
|
||||||
|
role_id: roleId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async add(channelId: string, roleId: string) {
|
||||||
|
await this.pingableRoles.insert({
|
||||||
|
guild_id: this.guildId,
|
||||||
|
channel_id: channelId,
|
||||||
|
role_id: roleId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
15
src/data/entities/PingableRole.ts
Normal file
15
src/data/entities/PingableRole.ts
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
import { Entity, Column, PrimaryColumn } from "typeorm";
|
||||||
|
import { ISavedMessageData } from "./SavedMessage";
|
||||||
|
|
||||||
|
@Entity("pingable_roles")
|
||||||
|
export class PingableRole {
|
||||||
|
@Column()
|
||||||
|
@PrimaryColumn()
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
@Column() guild_id: string;
|
||||||
|
|
||||||
|
@Column() channel_id: string;
|
||||||
|
|
||||||
|
@Column() role_id: string;
|
||||||
|
}
|
|
@ -63,6 +63,7 @@ import { SlowmodePlugin } from "./plugins/Slowmode";
|
||||||
import { StarboardPlugin } from "./plugins/Starboard";
|
import { StarboardPlugin } from "./plugins/Starboard";
|
||||||
import { NameHistoryPlugin } from "./plugins/NameHistory";
|
import { NameHistoryPlugin } from "./plugins/NameHistory";
|
||||||
import { AutoReactions } from "./plugins/AutoReactions";
|
import { AutoReactions } from "./plugins/AutoReactions";
|
||||||
|
import { PingableRoles } from "./plugins/PingableRoles";
|
||||||
|
|
||||||
// Run latest database migrations
|
// Run latest database migrations
|
||||||
logger.info("Running database migrations");
|
logger.info("Running database migrations");
|
||||||
|
@ -96,7 +97,8 @@ connect().then(async conn => {
|
||||||
TagsPlugin,
|
TagsPlugin,
|
||||||
SlowmodePlugin,
|
SlowmodePlugin,
|
||||||
StarboardPlugin,
|
StarboardPlugin,
|
||||||
AutoReactions
|
AutoReactions,
|
||||||
|
PingableRoles
|
||||||
],
|
],
|
||||||
|
|
||||||
globalPlugins: [BotControlPlugin, LogServerPlugin],
|
globalPlugins: [BotControlPlugin, LogServerPlugin],
|
||||||
|
|
49
src/migrations/1547293464842-CreatePingableRolesTable.ts
Normal file
49
src/migrations/1547293464842-CreatePingableRolesTable.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import { MigrationInterface, QueryRunner, Table } from "typeorm";
|
||||||
|
|
||||||
|
export class CreatePingableRolesTable1547293464842 implements MigrationInterface {
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.createTable(
|
||||||
|
new Table({
|
||||||
|
name: "pingable_roles",
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: "id",
|
||||||
|
type: "int",
|
||||||
|
unsigned: true,
|
||||||
|
isGenerated: true,
|
||||||
|
generationStrategy: "increment",
|
||||||
|
isPrimary: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "guild_id",
|
||||||
|
type: "bigint",
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "channel_id",
|
||||||
|
type: "bigint",
|
||||||
|
unsigned: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "role_id",
|
||||||
|
type: "bigint",
|
||||||
|
unsigned: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
indices: [
|
||||||
|
{
|
||||||
|
columnNames: ["guild_id", "channel_id"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
columnNames: ["guild_id", "channel_id", "role_id"],
|
||||||
|
isUnique: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<any> {
|
||||||
|
await queryRunner.dropTable("pingable_roles", true);
|
||||||
|
}
|
||||||
|
}
|
135
src/plugins/PingableRoles.ts
Normal file
135
src/plugins/PingableRoles.ts
Normal file
|
@ -0,0 +1,135 @@
|
||||||
|
import { Plugin, decorators as d } from "knub";
|
||||||
|
import { SavedMessage } from "../data/entities/SavedMessage";
|
||||||
|
import { Message, Role, TextableChannel, User } from "eris";
|
||||||
|
import { GuildPingableRoles } from "../data/GuildPingableRoles";
|
||||||
|
import { PingableRole } from "../data/entities/PingableRole";
|
||||||
|
import { errorMessage, successMessage } from "../utils";
|
||||||
|
|
||||||
|
const TIMEOUT = 10 * 1000;
|
||||||
|
|
||||||
|
export class PingableRoles extends Plugin {
|
||||||
|
public static pluginName = "pingable_roles";
|
||||||
|
|
||||||
|
protected pingableRoles: GuildPingableRoles;
|
||||||
|
protected cache: Map<string, PingableRole[]>;
|
||||||
|
protected timeouts: Map<string, any>;
|
||||||
|
|
||||||
|
getDefaultOptions() {
|
||||||
|
return {
|
||||||
|
permissions: {
|
||||||
|
use: false
|
||||||
|
},
|
||||||
|
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
level: ">=100",
|
||||||
|
permissions: {
|
||||||
|
use: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad() {
|
||||||
|
this.pingableRoles = GuildPingableRoles.getInstance(this.guildId);
|
||||||
|
|
||||||
|
this.cache = new Map();
|
||||||
|
this.timeouts = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async getPingableRolesForChannel(channelId: string): Promise<PingableRole[]> {
|
||||||
|
if (!this.cache.has(channelId)) {
|
||||||
|
this.cache.set(channelId, await this.pingableRoles.getForChannel(channelId));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.cache.get(channelId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.command("pingable_role disable", "<channelId:channelId> <role:role>")
|
||||||
|
@d.permission("use")
|
||||||
|
async disablePingableRoleCmd(msg: Message, args: { channelId: string; role: Role }) {
|
||||||
|
const pingableRole = await this.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id);
|
||||||
|
if (!pingableRole) {
|
||||||
|
msg.channel.createMessage(errorMessage(`**${args.role.name}** is not set as pingable in <#${args.channelId}>`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.pingableRoles.delete(args.channelId, args.role.id);
|
||||||
|
msg.channel.createMessage(
|
||||||
|
successMessage(`**${args.role.name}** is no longer set as pingable in <#${args.channelId}>`)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.command("pingable_role", "<channelId:channelId> <role:role>")
|
||||||
|
@d.permission("use")
|
||||||
|
async setPingableRoleCmd(msg: Message, args: { channelId: string; role: Role }) {
|
||||||
|
const existingPingableRole = await this.pingableRoles.getByChannelAndRoleId(args.channelId, args.role.id);
|
||||||
|
if (existingPingableRole) {
|
||||||
|
msg.channel.createMessage(
|
||||||
|
errorMessage(`**${args.role.name}** is already set as pingable in <#${args.channelId}>`)
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.pingableRoles.add(args.channelId, args.role.id);
|
||||||
|
msg.channel.createMessage(successMessage(`**${args.role.name}** has been set as pingable in <#${args.channelId}>`));
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("typingStart")
|
||||||
|
async onTypingStart(channel: TextableChannel, user: User) {
|
||||||
|
const pingableRoles = await this.getPingableRolesForChannel(channel.id);
|
||||||
|
if (pingableRoles.length === 0) return;
|
||||||
|
|
||||||
|
if (this.timeouts.has(channel.id)) {
|
||||||
|
clearTimeout(this.timeouts.get(channel.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.enablePingableRoles(pingableRoles);
|
||||||
|
|
||||||
|
const timeout = setTimeout(() => {
|
||||||
|
this.disablePingableRoles(pingableRoles);
|
||||||
|
}, TIMEOUT);
|
||||||
|
this.timeouts.set(channel.id, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
@d.event("messageCreate")
|
||||||
|
async onMessageCreate(msg: Message) {
|
||||||
|
const pingableRoles = await this.getPingableRolesForChannel(msg.channel.id);
|
||||||
|
if (pingableRoles.length === 0) return;
|
||||||
|
|
||||||
|
if (this.timeouts.has(msg.channel.id)) {
|
||||||
|
clearTimeout(this.timeouts.get(msg.channel.id));
|
||||||
|
}
|
||||||
|
|
||||||
|
this.disablePingableRoles(pingableRoles);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected enablePingableRoles(pingableRoles: PingableRole[]) {
|
||||||
|
for (const pingableRole of pingableRoles) {
|
||||||
|
const role = this.guild.roles.get(pingableRole.role_id);
|
||||||
|
if (!role) continue;
|
||||||
|
|
||||||
|
role.edit(
|
||||||
|
{
|
||||||
|
mentionable: true
|
||||||
|
},
|
||||||
|
"Enable pingable role"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected disablePingableRoles(pingableRoles: PingableRole[]) {
|
||||||
|
for (const pingableRole of pingableRoles) {
|
||||||
|
const role = this.guild.roles.get(pingableRole.role_id);
|
||||||
|
if (!role) continue;
|
||||||
|
|
||||||
|
role.edit(
|
||||||
|
{
|
||||||
|
mentionable: false
|
||||||
|
},
|
||||||
|
"Disable pingable role"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue