diff --git a/commands/TimeOffCommand.ts b/commands/TimeOffCommand.ts index e975605..79cdd48 100644 --- a/commands/TimeOffCommand.ts +++ b/commands/TimeOffCommand.ts @@ -9,8 +9,8 @@ import { statusCommand } from './subcommands/Status'; export class TimeOffCommand implements ISlashCommand { public command = 'time-off'; - public i18nParamsExample = ''; - public i18nDescription = ''; + public i18nParamsExample = 'Time_Off_Command_Params_Example'; + public i18nDescription = 'Time_Off_Command_Description'; public providesPreview = false; constructor(private readonly app: TimeOffApp) {} diff --git a/commands/subcommands/Help.ts b/commands/subcommands/Help.ts index 90a625b..30b8b97 100644 --- a/commands/subcommands/Help.ts +++ b/commands/subcommands/Help.ts @@ -8,12 +8,13 @@ export async function helpCommand(app: TimeOffApp, context: SlashCommandContext, const room = context.getRoom(); const message = - `*Time Off App Help*\n\n` + + `*Time-off Help*\n\n` + `*Commands*\n` + - `• \`/time-off start\` - Start a new time off\n` + - `• \`/time-off end\` - End an existing time off\n` + - `• \`/time-off status\` - Check the current time off status\n` + - `• \`/time-off help\` - Display this help message\n`; + `• \`/time-off start\` starts new time off period\n` + + `• \`/time-off start [message]\` start a new time off period with a custom message\n` + + `• \`/time-off end\` ends current time off period\n` + + `• \`/time-off status\` shows current time off status\n` + + `• \`/time-off help\` shows this list\n`; const notifier = new AppNotifier(app, read); await notifier.notifyUser(room, sender, message); diff --git a/commands/subcommands/Start.ts b/commands/subcommands/Start.ts index 5d3d395..c12e2ae 100644 --- a/commands/subcommands/Start.ts +++ b/commands/subcommands/Start.ts @@ -19,16 +19,13 @@ export async function startCommand( const room = context.getRoom(); const notifier = new AppNotifier(app, read); - let message = context.getArguments().join(' ').replace(CommandEnum.START, ''); - if (!message) { - message = NOTIFICATION_MESSAGES.default_reply_message; - } + const customMessage = context.getArguments().join(' ').replace(CommandEnum.START, '').trim(); const timeOffEntry: ITimeOff = { coreUserId: currentUser.id, username: currentUser.username, status: TimeOffStatus.ON_TIME_OFF, - message: message, + message: customMessage || undefined, lastNotifiedAtBySenderId: {}, }; @@ -36,6 +33,8 @@ export async function startCommand( const timeOffService = new TimeOffService(timeOffRepository); const savedTimeOff = await timeOffService.saveTimeOff(timeOffEntry); - const notificationMessage = !savedTimeOff ? NOTIFICATION_MESSAGES.error : NOTIFICATION_MESSAGES.started; + const notificationMessage = !savedTimeOff + ? NOTIFICATION_MESSAGES.error + : NOTIFICATION_MESSAGES.started(customMessage || undefined); await notifier.notifyUser(room, currentUser, notificationMessage); } diff --git a/commands/subcommands/Status.ts b/commands/subcommands/Status.ts index 6355143..9e8518f 100644 --- a/commands/subcommands/Status.ts +++ b/commands/subcommands/Status.ts @@ -30,7 +30,9 @@ export async function statusCommand( } if (timeOffEntry.status === TimeOffStatus.ON_TIME_OFF) { - notificationMessage = `${NOTIFICATION_MESSAGES.status_in}${timeOffEntry.message}`; + notificationMessage = timeOffEntry.message + ? `${NOTIFICATION_MESSAGES.status_in}${timeOffEntry.message}` + : NOTIFICATION_MESSAGES.status_in_no_message; } else { notificationMessage = `${NOTIFICATION_MESSAGES.status_out}`; } diff --git a/handlers/PostMessageSentHandler.ts b/handlers/PostMessageSentHandler.ts index 58680f6..11be2c6 100644 --- a/handlers/PostMessageSentHandler.ts +++ b/handlers/PostMessageSentHandler.ts @@ -58,10 +58,13 @@ export class PostMessageSentHandler { message: IMessage, sender: IUser, receiver: IUser, - timeOffMessage: string, + timeOffMessage?: string, ): Promise { const formattedMessage = TimeOffMessageFormatter.format(receiver.username, timeOffMessage); - await this.notifier.notifyUser(message.room, sender, timeOffMessage, formattedMessage); + const fallbackText = timeOffMessage + ? `${receiver.username} is currently on time off. They left the following message: ${timeOffMessage}` + : `${receiver.username} is currently on time off.`; + await this.notifier.notifyUser(message.room, sender, fallbackText, formattedMessage); } private shouldSendNotification(timeOffEntry: ITimeOff | undefined, senderId: string): timeOffEntry is ITimeOff { diff --git a/helpers/NotificationMessage.ts b/helpers/NotificationMessage.ts index 4f1bee9..89828ee 100644 --- a/helpers/NotificationMessage.ts +++ b/helpers/NotificationMessage.ts @@ -1,9 +1,22 @@ export const NOTIFICATION_MESSAGES = { - started: `You are marked as Time Off, we will see you when you get back. Use \`/time-off end\` to end your time off.`, - default_reply_message: `I am out of office, I will get back to you soon.`, + started: (customMessage?: string): string => { + const intro = `*Time off on*\nI will automatically reply to any direct messages you receive to let the sender know you're on time off.`; + const reminder = `Remember to use the \`/time-off end\` command when you get back.`; + + if (customMessage) { + const quoted = customMessage + .split('\n') + .map((line) => `> ${line}`) + .join('\n'); + return `${intro}\n\nI will also include the following custom message:\n${quoted}\n\n${reminder}`; + } + + return `${intro}\n\nYou have not set a custom reply message.\n\n${reminder}`; + }, ended: `Welcome back! You are no longer marked as Time Off.`, - not_started: `You are not marked as Time Off. Use \`/time-off start\` to start your time off.`, + not_started: `*Time-off off*\nI will not automatically reply to any direct messages you receive.`, status_in: `You are currently marked as Time Off. Your message is: `, - status_out: `You are \`not\` marked as Time Off.`, + status_in_no_message: `You are currently marked as Time Off. You have not set a custom reply message.`, + status_out: `*Time-off off*\nI will not automatically reply to any direct messages you receive.`, error: `An error occurred while updating your Time Off status. Please try again later.`, }; diff --git a/helpers/TimeOffMessageFormatter.ts b/helpers/TimeOffMessageFormatter.ts index 3f26e3f..3912be2 100644 --- a/helpers/TimeOffMessageFormatter.ts +++ b/helpers/TimeOffMessageFormatter.ts @@ -1,25 +1,36 @@ import { LayoutBlock } from '@rocket.chat/ui-kit'; export class TimeOffMessageFormatter { - public static format(username: string, message: string): LayoutBlock[] { - return [ + public static format(username: string, message?: string): LayoutBlock[] { + const headerText = message + ? `${username} is currently on time off. They left the following message:` + : `${username} is currently on time off.`; + + const blocks: LayoutBlock[] = [ { type: 'section', text: { type: 'mrkdwn', - text: `${username} is currently *unavailable* to answer your message, however they left the following message:\n\n`, + text: headerText, }, }, - { - type: 'preview', - title: [], - description: [ - { - type: 'mrkdwn', - text: message, - }, - ], - }, ]; + + if (message) { + const quoted = message + .split('\n') + .map((line) => `> ${line}`) + .join('\n'); + + blocks.push({ + type: 'section', + text: { + type: 'mrkdwn', + text: quoted, + }, + }); + } + + return blocks; } } diff --git a/i18n/en.json b/i18n/en.json new file mode 100644 index 0000000..bb7eb0d --- /dev/null +++ b/i18n/en.json @@ -0,0 +1,4 @@ +{ + "Time_Off_Command_Description": "Manage your time off — start, end, or check your status", + "Time_Off_Command_Params_Example": "start | end | status | help" +} diff --git a/interfaces/ITimeOff.ts b/interfaces/ITimeOff.ts index 974dfc6..db8fcec 100644 --- a/interfaces/ITimeOff.ts +++ b/interfaces/ITimeOff.ts @@ -3,7 +3,7 @@ import { TimeOffStatus } from '../enums/Status'; export interface ITimeOff { coreUserId: string; username: string; - message: string; + message?: string; status: TimeOffStatus; lastNotifiedAtBySenderId?: Record; } diff --git a/notifiers/AppNotifier.ts b/notifiers/AppNotifier.ts index 8321cbc..b77e8c4 100644 --- a/notifiers/AppNotifier.ts +++ b/notifiers/AppNotifier.ts @@ -6,7 +6,7 @@ import { LayoutBlock } from '@rocket.chat/ui-kit'; import { TimeOffApp } from '../TimeOffApp'; export class AppNotifier implements IAppNotifier { - private readonly TimeOffName: string = 'TimeOff Bot'; + private readonly TimeOffName: string = 'Time-off'; constructor(private readonly app: TimeOffApp, private readonly read: IRead) {}