Просмотр исходного кода

Merge pull request #4175 from weseek/fix/respone-slack-reviews

Fix/respone slack reviews
Yuki Takei 4 лет назад
Родитель
Сommit
683de36f70

+ 13 - 9
packages/slackbot-proxy/src/controllers/slack.ts

@@ -1,5 +1,5 @@
 import {
-  BodyParams, Controller, Get, Inject, PlatformResponse, Post, Req, Res, UseBefore,
+  Controller, Get, Inject, PlatformResponse, Post, Req, Res, UseBefore,
 } from '@tsed/common';
 
 import axios from 'axios';
@@ -19,7 +19,10 @@ import { InstallationRepository } from '~/repositories/installation';
 import { RelationRepository } from '~/repositories/relation';
 import { OrderRepository } from '~/repositories/order';
 import { AddSigningSecretToReq } from '~/middlewares/slack-to-growi/add-signing-secret-to-req';
-import { AuthorizeCommandMiddleware, AuthorizeInteractionMiddleware } from '~/middlewares/slack-to-growi/authorizer';
+import {
+  AuthorizeCommandMiddleware, AuthorizeInteractionMiddleware, AuthorizeEventsMiddleware,
+} from '~/middlewares/slack-to-growi/authorizer';
+import { UrlVerificationMiddleware } from '~/middlewares/slack-to-growi/url-verification';
 import { ExtractGrowiUriFromReq } from '~/middlewares/slack-to-growi/extract-growi-uri-from-req';
 import { InstallerService } from '~/services/InstallerService';
 import { SelectGrowiService } from '~/services/SelectGrowiService';
@@ -331,14 +334,15 @@ export class SlackCtrl {
   }
 
   @Post('/events')
-  async handleEvent(@BodyParams() body:{[key:string]:string} /* , @Res() res: Res */): Promise<void|string> {
-    // eslint-disable-next-line max-len
-    // see: https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls__request-url-configuration--verification
-    if (body.type === 'url_verification') {
-      return body.challenge;
-    }
+  @UseBefore(UrlVerificationMiddleware, AuthorizeEventsMiddleware)
+  async handleEvent(@Req() req: SlackOauthReq): Promise<void> {
 
-    logger.info('receive event', body);
+    const { authorizeResult } = req;
+    const client = generateWebClient(authorizeResult.botToken);
+
+    if (req.body.event.type === 'app_home_opened') {
+      await postWelcomeMessage(client, req.body.event.channel);
+    }
 
     return;
   }

+ 75 - 73
packages/slackbot-proxy/src/middlewares/slack-to-growi/authorizer.ts

@@ -6,56 +6,29 @@ import {
 import Logger from 'bunyan';
 
 import { SlackOauthReq } from '~/interfaces/slack-to-growi/slack-oauth-req';
-import { InstallationRepository } from '~/repositories/installation';
 import { InstallerService } from '~/services/InstallerService';
 import loggerFactory from '~/utils/logger';
 
-@Middleware()
-export class AuthorizeCommandMiddleware implements IMiddleware {
-
-  @Inject()
-  installerService: InstallerService;
-
-  @Inject()
-  installationRepository: InstallationRepository;
-
-  private logger: Logger;
 
-  constructor() {
-    this.logger = loggerFactory('slackbot-proxy:middlewares:AuthorizeCommandMiddleware');
-  }
+const getCommonMiddleware = (query:InstallationQuery<boolean>, installerService:InstallerService, logger:Logger) => {
+  return async(req: SlackOauthReq, res: Res): Promise<void|Res> => {
 
-  async use(@Req() req: SlackOauthReq, @Res() res: Res): Promise<void> {
-    const { body } = req;
-
-    // extract id from body
-    const teamId = body.team_id;
-    const enterpriseId = body.enterprise_id;
-    const isEnterpriseInstall = body.is_enterprise_install === 'true';
-
-    if (teamId == null && enterpriseId == null) {
+    if (query.teamId == null && query.enterpriseId == null) {
       res.writeHead(400, 'No installation found');
       return res.end();
     }
 
-    // create query from body
-    const query: InstallationQuery<boolean> = {
-      teamId,
-      enterpriseId,
-      isEnterpriseInstall,
-    };
-
     let result: AuthorizeResult;
     try {
-      result = await this.installerService.installer.authorize(query);
+      result = await installerService.installer.authorize(query);
 
       if (result.botToken == null) {
-        res.writeHead(403, `The installation for the team(${teamId || enterpriseId}) has no botToken`);
+        res.writeHead(403, `The installation for the team(${query.teamId || query.enterpriseId}) has no botToken`);
         return res.end();
       }
     }
     catch (e) {
-      this.logger.error(e.message);
+      logger.error(e.message);
 
       res.writeHead(500, e.message);
       return res.end();
@@ -63,19 +36,39 @@ export class AuthorizeCommandMiddleware implements IMiddleware {
 
     // set authorized data
     req.authorizeResult = result;
-  }
-
-}
+  };
+};
+@Middleware()
+export class AuthorizeCommandMiddleware implements IMiddleware {
 
+  private logger: Logger;
 
-@Middleware()
-export class AuthorizeInteractionMiddleware implements IMiddleware {
+  constructor() {
+    this.logger = loggerFactory('slackbot-proxy:middlewares:AuthorizeCommandMiddleware');
+  }
 
   @Inject()
   installerService: InstallerService;
 
-  @Inject()
-  installationRepository: InstallationRepository;
+  async use(@Req() req: SlackOauthReq, @Res() res: Res): Promise<void|Res> {
+    const { body } = req;
+    const teamId = body.team_id;
+    const enterpriseId = body.enterprise_id;
+    const isEnterpriseInstall = body.is_enterprise_install === 'true';
+    const query: InstallationQuery<boolean> = {
+      teamId,
+      enterpriseId,
+      isEnterpriseInstall,
+    };
+
+    const commonMiddleware = getCommonMiddleware(query, this.installerService, this.logger);
+    await commonMiddleware(req, res);
+  }
+
+}
+
+@Middleware()
+export class AuthorizeInteractionMiddleware implements IMiddleware {
 
   private logger: Logger;
 
@@ -83,52 +76,61 @@ export class AuthorizeInteractionMiddleware implements IMiddleware {
     this.logger = loggerFactory('slackbot-proxy:middlewares:AuthorizeInteractionMiddleware');
   }
 
-  async use(@Req() req: SlackOauthReq, @Res() res: Res): Promise<void> {
-    const { body } = req;
+    @Inject()
+    installerService: InstallerService;
+
+    async use(@Req() req: SlackOauthReq, @Res() res:Res): Promise<void|Res> {
+      const { body } = req;
+
+      const payload = JSON.parse(body.payload);
+
+      // extract id from body.payload
+      const teamId = payload.team?.id;
+      const enterpriseId = payload.enterprise?.id;
+      const isEnterpriseInstall = payload.is_enterprise_install === 'true';
 
-    if (body.payload == null) {
+      if (body.payload == null) {
       // do nothing
-      this.logger.info('body does not have payload');
-      return;
+        this.logger.info('body does not have payload');
+        return;
+      }
+
+      const query: InstallationQuery<boolean> = {
+        teamId,
+        enterpriseId,
+        isEnterpriseInstall,
+      };
+
+      const commonMiddleware = getCommonMiddleware(query, this.installerService, this.logger);
+      await commonMiddleware(req, res);
     }
 
-    const payload = JSON.parse(body.payload);
+}
+@Middleware()
+export class AuthorizeEventsMiddleware implements IMiddleware {
 
-    // extract id from body
-    const teamId = payload.team?.id;
-    const enterpriseId = payload.enterprise?.id;
-    const isEnterpriseInstall = payload.is_enterprise_install === 'true';
+  private logger: Logger;
 
-    if (teamId == null && enterpriseId == null) {
-      res.writeHead(400, 'No installation found');
-      return res.end();
-    }
+  constructor() {
+    this.logger = loggerFactory('slackbot-proxy:middlewares:AuthorizeEventsMiddleware');
+  }
 
-    // create query from body
+  @Inject()
+  installerService: InstallerService;
+
+  async use(@Req() req: SlackOauthReq, @Res() res: Res): Promise<void|Res> {
+    const { body } = req;
+    const teamId = body.team_id;
+    const enterpriseId = body.enterprise_id;
+    const isEnterpriseInstall = body.is_enterprise_install === 'true';
     const query: InstallationQuery<boolean> = {
       teamId,
       enterpriseId,
       isEnterpriseInstall,
     };
 
-    let result: AuthorizeResult;
-    try {
-      result = await this.installerService.installer.authorize(query);
-
-      if (result.botToken == null) {
-        res.writeHead(403, `The installation for the team(${teamId || enterpriseId}) has no botToken`);
-        return res.end();
-      }
-    }
-    catch (e) {
-      this.logger.error(e.message);
-
-      res.writeHead(500, e.message);
-      return res.end();
-    }
-
-    // set authorized data
-    req.authorizeResult = result;
+    const commonMiddleware = getCommonMiddleware(query, this.installerService, this.logger);
+    await commonMiddleware(req, res);
   }
 
 }

+ 20 - 0
packages/slackbot-proxy/src/middlewares/slack-to-growi/url-verification.ts

@@ -0,0 +1,20 @@
+import {
+  IMiddleware, Middleware, Req, Res,
+} from '@tsed/common';
+import { SlackOauthReq } from '~/interfaces/slack-to-growi/slack-oauth-req';
+
+
+@Middleware()
+export class UrlVerificationMiddleware implements IMiddleware {
+
+  async use(@Req() req: SlackOauthReq, @Res() res: Res): Promise<void> {
+
+    // eslint-disable-next-line max-len
+    // see: https://api.slack.com/apis/connections/events-api#the-events-api__subscribing-to-event-types__events-api-request-urls__request-url-configuration--verification
+    if (req.body.type === 'url_verification') {
+      res.send(req.body.challenge);
+      return;
+    }
+  }
+
+}