Browse Source

Merge pull request #3910 from weseek/feat/6285-6287-display-modal-for-select-growi

Feat/6285 6287 display modal for select growi
Yuki Takei 4 years ago
parent
commit
e0cffa8977

+ 7 - 1
packages/slackbot-proxy/src/controllers/growi-to-slack.ts

@@ -24,6 +24,8 @@ import { injectGrowiUriToView } from '~/utils/injectGrowiUriToView';
 
 
 const logger = loggerFactory('slackbot-proxy:controllers:growi-to-slack');
 const logger = loggerFactory('slackbot-proxy:controllers:growi-to-slack');
 
 
+// temporarily save for selection to growi
+const temporarySinglePostCommands = ['create'];
 
 
 @Controller('/g2s')
 @Controller('/g2s')
 export class GrowiToSlackCtrl {
 export class GrowiToSlackCtrl {
@@ -159,7 +161,11 @@ export class GrowiToSlackCtrl {
 
 
     // Transaction is not considered because it is used infrequently,
     // Transaction is not considered because it is used infrequently,
     const createdRelation = await this.relationRepository.save({
     const createdRelation = await this.relationRepository.save({
-      installation: order.installation, tokenGtoP: order.tokenGtoP, tokenPtoG: order.tokenPtoG, growiUri: order.growiUrl,
+      installation: order.installation,
+      tokenGtoP: order.tokenGtoP,
+      tokenPtoG: order.tokenPtoG,
+      growiUri: order.growiUrl,
+      siglePostCommands: temporarySinglePostCommands,
     });
     });
 
 
     return res.send({ relation: createdRelation, slackBotToken: token });
     return res.send({ relation: createdRelation, slackBotToken: token });

+ 21 - 0
packages/slackbot-proxy/src/controllers/slack.ts

@@ -19,6 +19,7 @@ import { AddSigningSecretToReq } from '~/middlewares/slack-to-growi/add-signing-
 import { AuthorizeCommandMiddleware, AuthorizeInteractionMiddleware } from '~/middlewares/slack-to-growi/authorizer';
 import { AuthorizeCommandMiddleware, AuthorizeInteractionMiddleware } from '~/middlewares/slack-to-growi/authorizer';
 import { ExtractGrowiUriFromReq } from '~/middlewares/slack-to-growi/extract-growi-uri-from-req';
 import { ExtractGrowiUriFromReq } from '~/middlewares/slack-to-growi/extract-growi-uri-from-req';
 import { InstallerService } from '~/services/InstallerService';
 import { InstallerService } from '~/services/InstallerService';
+import { SelectRequestService } from '~/services/SelectRequestService';
 import { RegisterService } from '~/services/RegisterService';
 import { RegisterService } from '~/services/RegisterService';
 import { UnregisterService } from '~/services/UnregisterService';
 import { UnregisterService } from '~/services/UnregisterService';
 import { InvalidUrlError } from '../models/errors';
 import { InvalidUrlError } from '../models/errors';
@@ -43,6 +44,9 @@ export class SlackCtrl {
   @Inject()
   @Inject()
   orderRepository: OrderRepository;
   orderRepository: OrderRepository;
 
 
+  @Inject()
+  selectRequestService: SelectRequestService;
+
   @Inject()
   @Inject()
   registerService: RegisterService;
   registerService: RegisterService;
 
 
@@ -134,6 +138,17 @@ export class SlackCtrl {
     // See https://api.slack.com/apis/connections/events-api#the-events-api__responding-to-events
     // See https://api.slack.com/apis/connections/events-api#the-events-api__responding-to-events
     res.send();
     res.send();
 
 
+    body.growiUris = [];
+    relations.forEach((relation) => {
+      if (relation.siglePostCommands.includes(growiCommand.growiCommandType)) {
+        body.growiUris.push(relation.growiUri);
+      }
+    });
+
+    if (body.growiUris != null && body.growiUris.length > 0) {
+      return this.selectRequestService.process(growiCommand, authorizeResult, body);
+    }
+
     /*
     /*
      * forward to GROWI server
      * forward to GROWI server
      */
      */
@@ -211,6 +226,12 @@ export class SlackCtrl {
       return;
       return;
     }
     }
 
 
+    // forward to GROWI server
+    if (callBackId === 'select_growi') {
+      await this.selectRequestService.forwardRequest(this.relationRepository, installation, payload);
+      return;
+    }
+
     /*
     /*
     * forward to GROWI server
     * forward to GROWI server
     */
     */

+ 3 - 0
packages/slackbot-proxy/src/entities/relation.ts

@@ -30,4 +30,7 @@ export class Relation {
   @Column()
   @Column()
   growiUri: string;
   growiUri: string;
 
 
+  @Column('simple-array')
+  siglePostCommands: string[];
+
 }
 }

+ 107 - 0
packages/slackbot-proxy/src/services/SelectRequestService.ts

@@ -0,0 +1,107 @@
+import { Service } from '@tsed/di';
+import axios from 'axios';
+
+import { GrowiCommand, generateWebClient } from '@growi/slack';
+import { AuthorizeResult } from '@slack/oauth';
+
+import { GrowiCommandProcessor } from '~/interfaces/slack-to-growi/growi-command-processor';
+import { RelationRepository } from '~/repositories/relation';
+import { Installation } from '~/entities/installation';
+
+
+@Service()
+export class SelectRequestService implements GrowiCommandProcessor {
+
+  async process(growiCommand: GrowiCommand, authorizeResult: AuthorizeResult, body: {[key:string]:string } & {growiUris:string[]}): Promise<void> {
+    const { botToken } = authorizeResult;
+
+    if (botToken == null) {
+      throw new Error('botToken is required.');
+    }
+
+    const client = generateWebClient(botToken);
+
+    await client.views.open({
+      trigger_id: body.trigger_id,
+      view: {
+        type: 'modal',
+        callback_id: 'select_growi',
+        title: {
+          type: 'plain_text',
+          text: 'Slect Growi url',
+        },
+        submit: {
+          type: 'plain_text',
+          text: 'Submit',
+        },
+        close: {
+          type: 'plain_text',
+          text: 'Close',
+        },
+        private_metadata: JSON.stringify({ body, growiCommand }),
+
+        blocks: [
+          {
+            type: 'input',
+            block_id: 'select_growi',
+            label: {
+              type: 'plain_text',
+              text: 'GROWI App',
+            },
+            element: {
+              type: 'static_select',
+              action_id: 'growi_app',
+              options: body.growiUris.map((growiUri) => {
+                return ({
+                  text: {
+                    type: 'plain_text',
+                    text: growiUri,
+                  },
+                  value: growiUri,
+                });
+              }),
+            },
+          },
+        ],
+      },
+    });
+  }
+
+  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+  async forwardRequest(relationRepository:RelationRepository, installation:Installation | undefined, payload:any):Promise<void> {
+    const { trigger_id: triggerId } = payload;
+    const { state, private_metadata: privateMetadata } = payload?.view;
+    const { value: growiUri } = state?.values?.select_growi?.growi_app?.selected_option;
+
+    const parsedPrivateMetadata = JSON.parse(privateMetadata);
+    const { growiCommand, body } = parsedPrivateMetadata;
+
+    if (growiCommand == null || body == null) {
+      throw new Error('growiCommand and body are required.');
+    }
+
+    // ovverride trigger_id
+    body.trigger_id = triggerId;
+
+    const relation = await relationRepository.findOne({ installation, growiUri });
+
+    if (relation == null) {
+      throw new Error('No relation found.');
+    }
+
+    /*
+     * forward to GROWI server
+     */
+    // generate API URL
+    const url = new URL('/_api/v3/slack-integration/proxied/commands', relation.growiUri);
+    await axios.post(url.toString(), {
+      ...body,
+      growiCommand,
+    }, {
+      headers: {
+        'x-growi-ptog-tokens': relation.tokenPtoG,
+      },
+    });
+  }
+
+}

+ 1 - 1
src/server/service/slackbot.js

@@ -321,7 +321,7 @@ class SlackBotService extends S2sMessageHandlable {
       await client.chat.postEphemeral({
       await client.chat.postEphemeral({
         channel: channelId,
         channel: channelId,
         user: payload.user.id,
         user: payload.user.id,
-        text: `The page <${decodeURI(growiUri + path)} | ${decodeURI(`${growiUri}/${page._id}`)}> has been created.`,
+        text: `The page <${decodeURI(`${growiUri}/${page._id} | ${decodeURI(growiUri + path)}`)}> has been created.`,
       });
       });
     }
     }
     catch (err) {
     catch (err) {