|
@@ -7,7 +7,7 @@ const {
|
|
|
} = require('@growi/slack');
|
|
} = require('@growi/slack');
|
|
|
const { parse, format } = require('date-fns');
|
|
const { parse, format } = require('date-fns');
|
|
|
const axios = require('axios');
|
|
const axios = require('axios');
|
|
|
-const SlackbotError = require('../../models/vo/slackbot-error');
|
|
|
|
|
|
|
+const { SlackCommandHandlerError } = require('../../models/vo/slack-command-handler-error');
|
|
|
|
|
|
|
|
module.exports = (crowi) => {
|
|
module.exports = (crowi) => {
|
|
|
const CreatePageService = require('./create-page-service');
|
|
const CreatePageService = require('./create-page-service');
|
|
@@ -37,22 +37,17 @@ module.exports = (crowi) => {
|
|
|
let result = [];
|
|
let result = [];
|
|
|
const channelId = payload.channel.id; // this must exist since the type is always block_actions
|
|
const channelId = payload.channel.id; // this must exist since the type is always block_actions
|
|
|
const userChannelId = payload.user.id;
|
|
const userChannelId = payload.user.id;
|
|
|
- try {
|
|
|
|
|
- // validate form
|
|
|
|
|
- const { path, oldest, newest } = await this.togetterValidateForm(client, payload, interactionPayloadAccessor);
|
|
|
|
|
- // get messages
|
|
|
|
|
- result = await this.togetterGetMessages(client, channelId, newest, oldest);
|
|
|
|
|
- // clean messages
|
|
|
|
|
- const cleanedContents = await this.togetterCleanMessages(result.messages);
|
|
|
|
|
-
|
|
|
|
|
- const contentsBody = cleanedContents.join('');
|
|
|
|
|
- // create and send url message
|
|
|
|
|
- await this.togetterCreatePageAndSendPreview(client, interactionPayloadAccessor, path, userChannelId, contentsBody);
|
|
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
- logger.error('Error occured by togetter.');
|
|
|
|
|
- throw err;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // validate form
|
|
|
|
|
+ const { path, oldest, newest } = await this.togetterValidateForm(client, payload, interactionPayloadAccessor);
|
|
|
|
|
+ // get messages
|
|
|
|
|
+ result = await this.togetterGetMessages(client, channelId, newest, oldest);
|
|
|
|
|
+ // clean messages
|
|
|
|
|
+ const cleanedContents = await this.togetterCleanMessages(result.messages);
|
|
|
|
|
+
|
|
|
|
|
+ const contentsBody = cleanedContents.join('');
|
|
|
|
|
+ // create and send url message
|
|
|
|
|
+ await this.togetterCreatePageAndSendPreview(client, interactionPayloadAccessor, path, userChannelId, contentsBody);
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
handler.togetterValidateForm = async function(client, payload, interactionPayloadAccessor) {
|
|
handler.togetterValidateForm = async function(client, payload, interactionPayloadAccessor) {
|
|
@@ -60,71 +55,88 @@ module.exports = (crowi) => {
|
|
|
const path = interactionPayloadAccessor.getStateValues()?.page_path.page_path.value;
|
|
const path = interactionPayloadAccessor.getStateValues()?.page_path.page_path.value;
|
|
|
let oldest = interactionPayloadAccessor.getStateValues()?.oldest.oldest.value;
|
|
let oldest = interactionPayloadAccessor.getStateValues()?.oldest.oldest.value;
|
|
|
let newest = interactionPayloadAccessor.getStateValues()?.newest.newest.value;
|
|
let newest = interactionPayloadAccessor.getStateValues()?.newest.newest.value;
|
|
|
- oldest = oldest.trim();
|
|
|
|
|
- newest = newest.trim();
|
|
|
|
|
- if (path == null) {
|
|
|
|
|
- throw new SlackbotError({
|
|
|
|
|
- method: 'postMessage',
|
|
|
|
|
- to: 'dm',
|
|
|
|
|
- popupMessage: 'Page path is required.',
|
|
|
|
|
- mainMessage: 'Page path is required.',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (oldest == null || newest == null || path == null) {
|
|
|
|
|
+ throw new SlackCommandHandlerError('All parameters are required. (Oldest datetime, Newst datetime and Page path)');
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* RegExp for datetime yyyy/MM/dd-HH:mm
|
|
* RegExp for datetime yyyy/MM/dd-HH:mm
|
|
|
* @see https://regex101.com/r/XbxdNo/1
|
|
* @see https://regex101.com/r/XbxdNo/1
|
|
|
*/
|
|
*/
|
|
|
const regexpDatetime = new RegExp(/^[12]\d\d\d\/(0[1-9]|1[012])\/(0[1-9]|[12][0-9]|3[01])-([01][0-9]|2[0123]):[0-5][0-9]$/);
|
|
const regexpDatetime = new RegExp(/^[12]\d\d\d\/(0[1-9]|1[012])\/(0[1-9]|[12][0-9]|3[01])-([01][0-9]|2[0123]):[0-5][0-9]$/);
|
|
|
|
|
|
|
|
- if (!regexpDatetime.test(oldest)) {
|
|
|
|
|
- throw new SlackbotError({
|
|
|
|
|
- method: 'postMessage',
|
|
|
|
|
- to: 'dm',
|
|
|
|
|
- popupMessage: 'Datetime format for oldest must be yyyy/MM/dd-HH:mm',
|
|
|
|
|
- mainMessage: 'Datetime format for oldest must be yyyy/MM/dd-HH:mm',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ if (!regexpDatetime.test(oldest.trim())) {
|
|
|
|
|
+ throw new SlackCommandHandlerError('Datetime format for oldest must be yyyy/MM/dd-HH:mm');
|
|
|
}
|
|
}
|
|
|
- if (!regexpDatetime.test(newest)) {
|
|
|
|
|
- throw new SlackbotError({
|
|
|
|
|
- method: 'postMessage',
|
|
|
|
|
- to: 'dm',
|
|
|
|
|
- popupMessage: 'Datetime format for newest must be yyyy/MM/dd-HH:mm',
|
|
|
|
|
- mainMessage: 'Datetime format for newest must be yyyy/MM/dd-HH:mm',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ if (!regexpDatetime.test(newest.trim())) {
|
|
|
|
|
+ throw new SlackCommandHandlerError('Datetime format for newest must be yyyy/MM/dd-HH:mm');
|
|
|
}
|
|
}
|
|
|
oldest = parse(oldest, 'yyyy/MM/dd-HH:mm', new Date()).getTime() / 1000 + grwTzoffset;
|
|
oldest = parse(oldest, 'yyyy/MM/dd-HH:mm', new Date()).getTime() / 1000 + grwTzoffset;
|
|
|
// + 60s in order to include messages between hh:mm.00s and hh:mm.59s
|
|
// + 60s in order to include messages between hh:mm.00s and hh:mm.59s
|
|
|
newest = parse(newest, 'yyyy/MM/dd-HH:mm', new Date()).getTime() / 1000 + grwTzoffset + 60;
|
|
newest = parse(newest, 'yyyy/MM/dd-HH:mm', new Date()).getTime() / 1000 + grwTzoffset + 60;
|
|
|
|
|
|
|
|
if (oldest > newest) {
|
|
if (oldest > newest) {
|
|
|
- throw new SlackbotError({
|
|
|
|
|
- method: 'postMessage',
|
|
|
|
|
- to: 'dm',
|
|
|
|
|
- popupMessage: 'Oldest datetime must be older than the newest date time.',
|
|
|
|
|
- mainMessage: 'Oldest datetime must be older than the newest date time.',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ throw new SlackCommandHandlerError('Oldest datetime must be older than the newest date time.');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return { path, oldest, newest };
|
|
return { path, oldest, newest };
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
- handler.togetterGetMessages = async function(client, channelId, newest, oldest) {
|
|
|
|
|
- const result = await client.conversations.history({
|
|
|
|
|
|
|
+ async function retrieveHistory(client, channelId, newest, oldest) {
|
|
|
|
|
+ return client.conversations.history({
|
|
|
channel: channelId,
|
|
channel: channelId,
|
|
|
newest,
|
|
newest,
|
|
|
oldest,
|
|
oldest,
|
|
|
limit: 100,
|
|
limit: 100,
|
|
|
inclusive: true,
|
|
inclusive: true,
|
|
|
});
|
|
});
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ handler.togetterGetMessages = async function(client, channelId, newest, oldest) {
|
|
|
|
|
+ let result;
|
|
|
|
|
+
|
|
|
|
|
+ // first attempt
|
|
|
|
|
+ try {
|
|
|
|
|
+ result = await retrieveHistory(client, channelId, newest, oldest);
|
|
|
|
|
+ }
|
|
|
|
|
+ catch (err) {
|
|
|
|
|
+ const errorCode = err.data?.errorCode;
|
|
|
|
|
+
|
|
|
|
|
+ if (errorCode === 'not_in_channel') {
|
|
|
|
|
+ // join and retry
|
|
|
|
|
+ await client.conversations.join({
|
|
|
|
|
+ channel: channelId,
|
|
|
|
|
+ });
|
|
|
|
|
+ result = await retrieveHistory(client, channelId, newest, oldest);
|
|
|
|
|
+ }
|
|
|
|
|
+ else if (errorCode === 'channel_not_found') {
|
|
|
|
|
+
|
|
|
|
|
+ const message = ':cry: GROWI Bot couldn\'t get history data because *this channel was private*.'
|
|
|
|
|
+ + '\nPlease add GROWI bot to this channel.'
|
|
|
|
|
+ + '\n';
|
|
|
|
|
+ throw new SlackCommandHandlerError(message, {
|
|
|
|
|
+ respondBody: {
|
|
|
|
|
+ text: message,
|
|
|
|
|
+ blocks: [
|
|
|
|
|
+ markdownSectionBlock(message),
|
|
|
|
|
+ {
|
|
|
|
|
+ type: 'image',
|
|
|
|
|
+ image_url: 'https://user-images.githubusercontent.com/1638767/135658794-a8d2dbc8-580f-4203-b368-e74e2f3c7b3a.png',
|
|
|
|
|
+ alt_text: 'Add app to this channel',
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ else {
|
|
|
|
|
+ throw err;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
// return if no message found
|
|
// return if no message found
|
|
|
if (result.messages.length === 0) {
|
|
if (result.messages.length === 0) {
|
|
|
- throw new SlackbotError({
|
|
|
|
|
- method: 'postMessage',
|
|
|
|
|
- to: 'dm',
|
|
|
|
|
- popupMessage: 'No message found from togetter command. Try different datetime.',
|
|
|
|
|
- mainMessage: 'No message found from togetter command. Try different datetime.',
|
|
|
|
|
- });
|
|
|
|
|
|
|
+ throw new SlackCommandHandlerError('No message found from togetter command. Try different datetime.');
|
|
|
}
|
|
}
|
|
|
return result;
|
|
return result;
|
|
|
};
|
|
};
|
|
@@ -157,40 +169,23 @@ module.exports = (crowi) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
handler.togetterCreatePageAndSendPreview = async function(client, interactionPayloadAccessor, path, userChannelId, contentsBody) {
|
|
handler.togetterCreatePageAndSendPreview = async function(client, interactionPayloadAccessor, path, userChannelId, contentsBody) {
|
|
|
- try {
|
|
|
|
|
- await createPageService.createPageInGrowi(interactionPayloadAccessor, path, contentsBody);
|
|
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
- logger.error('Error occurred while creating a page.');
|
|
|
|
|
- throw err;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- try {
|
|
|
|
|
- // send preview to dm
|
|
|
|
|
- await client.chat.postMessage({
|
|
|
|
|
- channel: userChannelId,
|
|
|
|
|
- text: 'Preview from togetter command',
|
|
|
|
|
- blocks: [
|
|
|
|
|
- markdownSectionBlock('*Preview*'),
|
|
|
|
|
- divider(),
|
|
|
|
|
- markdownSectionBlock(contentsBody),
|
|
|
|
|
- divider(),
|
|
|
|
|
- ],
|
|
|
|
|
- });
|
|
|
|
|
- // dismiss
|
|
|
|
|
- await deleteOriginal(interactionPayloadAccessor.getResponseUrl(), {
|
|
|
|
|
- delete_original: true,
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- catch (err) {
|
|
|
|
|
- logger.error('Error occurred while creating a page.', err);
|
|
|
|
|
- throw new SlackbotError({
|
|
|
|
|
- method: 'postMessage',
|
|
|
|
|
- to: 'dm',
|
|
|
|
|
- popupMessage: 'Error occurred while creating a page.',
|
|
|
|
|
- mainMessage: 'Error occurred while creating a page.',
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await createPageService.createPageInGrowi(interactionPayloadAccessor, path, contentsBody);
|
|
|
|
|
+
|
|
|
|
|
+ // send preview to dm
|
|
|
|
|
+ await client.chat.postMessage({
|
|
|
|
|
+ channel: userChannelId,
|
|
|
|
|
+ text: 'Preview from togetter command',
|
|
|
|
|
+ blocks: [
|
|
|
|
|
+ markdownSectionBlock('*Preview*'),
|
|
|
|
|
+ divider(),
|
|
|
|
|
+ markdownSectionBlock(contentsBody),
|
|
|
|
|
+ divider(),
|
|
|
|
|
+ ],
|
|
|
|
|
+ });
|
|
|
|
|
+ // dismiss
|
|
|
|
|
+ await deleteOriginal(interactionPayloadAccessor.getResponseUrl(), {
|
|
|
|
|
+ delete_original: true,
|
|
|
|
|
+ });
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
handler.togetterMessageBlocks = function() {
|
|
handler.togetterMessageBlocks = function() {
|