greet.ts 3.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { Plugin, BotEventData, Event } from "src/model/plugin";
  2. import { GuildMember, PartialGuildMember, TextChannel } from "discord.js";
  3. import { getRepository } from "typeorm";
  4. import { eventLogger, logger } from "src/logging";
  5. import { GuildGreeting } from "@shared/db/entity/GuildGreeting";
  6. import { client } from "src/client";
  7. import { formatString } from "src/util";
  8. import { GuildVerification } from "@shared/db/entity/GuildVerification";
  9. import { tryDo } from "@shared/common/async_utils";
  10. @Plugin
  11. export class GreetPlugin {
  12. @Event("guildMemberAdd")
  13. async showGreetMessage(data: BotEventData, member: GuildMember | PartialGuildMember): Promise<void> {
  14. eventLogger.info("User %s#%s (%s) joined server %s (%s)", member.user?.username, member.user?.discriminator, member.user?.id, member.guild.name, member.guild.id);
  15. const greetInfo = await this.displayGreet(member, g => g.onJoinMessage);
  16. if (!greetInfo || !greetInfo.onJoinPrivateMessage) {
  17. return;
  18. }
  19. const verificationGuilds = getRepository(GuildVerification);
  20. const guild = await verificationGuilds.findOne(member.guild.id);
  21. if (!guild) {
  22. return;
  23. }
  24. const dmResult = await tryDo(member.createDM());
  25. if (!dmResult.ok) {
  26. logger.warn("greet: failed to create DM with user %s#%s (%s): %s", member.user?.username, member.user?.discriminator, member.id, dmResult.error);
  27. return;
  28. }
  29. const sendResult = await tryDo(dmResult.result.send(formatString(greetInfo.onJoinPrivateMessage, {
  30. memberID: member.id,
  31. memberTag: member.user?.tag ?? member.displayName,
  32. guildName: member.guild.name
  33. })));
  34. if (!sendResult.ok) {
  35. logger.warn("greet: failed to send DM greeting to %s#%s (%s): %s", member.user?.username, member.user?.discriminator, member.id, sendResult.error);
  36. }
  37. }
  38. @Event("guildMemberRemove")
  39. async showGoodbyeMessage(data: BotEventData, member: GuildMember | PartialGuildMember): Promise<void> {
  40. eventLogger.info("User %s#%s (%s) left server %s (%s)", member.user?.username, member.user?.discriminator, member.user?.id, member.guild.name, member.guild.id);
  41. await this.displayGreet(member, g => g.onLeaveMessage);
  42. }
  43. private async displayGreet(member: GuildMember | PartialGuildMember, select: (greeting: GuildGreeting) => string) {
  44. const result = await this.getGreeting(member);
  45. if (!result)
  46. return undefined;
  47. const { guildGreeting, greetingChannel } = result;
  48. await greetingChannel.send(formatString(select(guildGreeting), {
  49. memberID: member.id,
  50. memberTag: member.user?.tag ?? member.displayName,
  51. guildName: member.guild.name
  52. }));
  53. return guildGreeting;
  54. }
  55. private async getGreeting(member: GuildMember | PartialGuildMember) {
  56. const repo = getRepository(GuildGreeting);
  57. const guildGreeting = await repo.findOne(member.guild.id);
  58. if (!guildGreeting) {
  59. logger.debug("Tried to greet user %s in guild %s but no greeting is defined!", member.id, member.guild.id);
  60. return undefined;
  61. }
  62. const greetingChannel = client.bot.channels.resolve(guildGreeting.greetingChannelId);
  63. if (!greetingChannel) {
  64. logger.warn("No channel %s in guild %s, can't greet!", guildGreeting.greetingChannelId, guildGreeting.guildId);
  65. return undefined;
  66. }
  67. if (!(greetingChannel instanceof TextChannel)) {
  68. logger.warn("Channel %s is of not a text channel (got type: %s)", greetingChannel.id, greetingChannel.type);
  69. return undefined;
  70. }
  71. return { guildGreeting, greetingChannel };
  72. }
  73. }