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

refactor generateWebClient and WebClientRes

Yuki Takei 4 лет назад
Родитель
Сommit
f684a03bb3

+ 21 - 6
packages/slack/src/utils/webclient-factory.ts

@@ -1,12 +1,27 @@
-import { LogLevel, WebClient } from '@slack/web-api';
+import { LogLevel, WebClient, WebClientOptions } from '@slack/web-api';
 
 const isProduction = process.env.NODE_ENV === 'production';
+const logLevel: LogLevel = isProduction ? LogLevel.DEBUG : LogLevel.INFO;
 
 /**
  * Generate WebClilent instance
- * @param token Slack Bot Token or Proxy Server URI
- * @returns
+ * @param token
+ * @param serverUri Slack Bot Token or Proxy Server URI
+ * @param headers
  */
-export const generateWebClient = (token?: string, serverUri?: string, headers?:{[key:string]:string}): WebClient => {
-  return new WebClient(token, { slackApiUrl: serverUri, logLevel: isProduction ? LogLevel.DEBUG : LogLevel.INFO, headers });
-};
+export function generateWebClient(token?: string, serverUri?: string, headers?:{[key:string]:string}): WebClient;
+
+/**
+ * Generate WebClilent instance
+ * @param token
+ * @param opts
+ */
+export function generateWebClient(token?: string, opts?: WebClientOptions): WebClient;
+
+export function generateWebClient(token?: string, ...args: any[]): WebClient {
+  if (typeof args[0] === 'string') {
+    return new WebClient(token, { logLevel, slackApiUrl: args[0], headers: args[1] });
+  }
+
+  return new WebClient(token, { logLevel, ...args });
+}

+ 19 - 9
packages/slackbot-proxy/src/controllers/growi-to-slack.ts

@@ -5,10 +5,10 @@ import axios from 'axios';
 import createError from 'http-errors';
 import { addHours } from 'date-fns';
 
-import { WebAPICallResult } from '@slack/web-api';
+import { ErrorCode, WebAPICallResult } from '@slack/web-api';
 
 import {
-  verifyGrowiToSlackRequest, getConnectionStatuses, getConnectionStatus, generateWebClient, REQUEST_TIMEOUT_FOR_PTOG,
+  verifyGrowiToSlackRequest, getConnectionStatuses, getConnectionStatus, REQUEST_TIMEOUT_FOR_PTOG, generateWebClient,
 } from '@growi/slack';
 
 import { WebclientRes, AddWebclientResponseToRes } from '~/middlewares/growi-to-slack/add-webclient-response-to-res';
@@ -246,13 +246,13 @@ export class GrowiToSlackCtrl {
   @UseBefore(AddWebclientResponseToRes, verifyGrowiToSlackRequest)
   async callSlackApi(
     @PathParams('method') method: string, @Req() req: GrowiReq, @Res() res: WebclientRes,
-  ): Promise<void|WebAPICallResult> {
+  ): Promise<WebclientRes> {
     const { tokenGtoPs } = req;
 
     logger.debug('Slack API called: ', { method });
 
     if (tokenGtoPs.length !== 1) {
-      return res.webClientErr('tokenGtoPs is invalid', 'invalid_tokenGtoP');
+      return res.simulateWebAPIPlatformError('tokenGtoPs is invalid', 'invalid_tokenGtoP');
     }
 
     const tokenGtoP = tokenGtoPs[0];
@@ -264,15 +264,18 @@ export class GrowiToSlackCtrl {
       .getOne();
 
     if (relation == null) {
-      return res.webClientErr('relation is invalid', 'invalid_relation');
+      return res.simulateWebAPIPlatformError('relation is invalid', 'invalid_relation');
     }
 
     const token = relation.installation.data.bot?.token;
     if (token == null) {
-      return res.webClientErr('installation is invalid', 'invalid_installation');
+      return res.simulateWebAPIPlatformError('installation is invalid', 'invalid_installation');
     }
 
-    const client = generateWebClient(token);
+    // generate WebClient with no retry because GROWI main side will do
+    const client = generateWebClient(token, {
+      retryConfig: { retries: 0 },
+    });
 
     try {
       this.injectGrowiUri(req, relation.growiUri);
@@ -282,11 +285,18 @@ export class GrowiToSlackCtrl {
 
       logger.debug({ method, opt });
       // !! DO NOT REMOVE `await ` or it does not enter catch block even when error occured !! -- 2021.08.22 Yuki Takei
-      return await client.apiCall(method, opt);
+      const result = await client.apiCall(method, opt);
+
+      return res.send(result);
     }
     catch (err) {
       logger.error(err);
-      return res.webClientErr(`failed to send to slack. err: ${err.message}`, 'fail_api_call');
+
+      if (err.code === ErrorCode.PlatformError) {
+        return res.simulateWebAPIPlatformError(err.message, err.code);
+      }
+
+      return res.simulateWebAPIRequestError(err.message, err.response?.status);
     }
   }
 

+ 9 - 2
packages/slackbot-proxy/src/middlewares/growi-to-slack/add-webclient-response-to-res.ts

@@ -1,10 +1,12 @@
+import { ErrorCode } from '@slack/web-api';
 import {
   IMiddleware, Middleware, Next, Req, Res,
 } from '@tsed/common';
 
 
 export type WebclientRes = Res & {
-  webClientErr: (message?:string, errorCode?:string) => void
+  simulateWebAPIRequestError: (error: string, statusCode: number) => WebclientRes
+  simulateWebAPIPlatformError: (error: string, errorCode?:string) => WebclientRes
 };
 
 
@@ -13,7 +15,12 @@ export class AddWebclientResponseToRes implements IMiddleware {
 
   use(@Req() req: Req, @Res() res: WebclientRes, @Next() next: Next): void {
 
-    res.webClientErr = (error?:string, errorCode?:string) => {
+    // https://github.com/slackapi/node-slack-sdk/blob/7b95663a9ef31036367c066ccbf0021423278f40/packages/web-api/src/WebClient.ts#L356-L358
+    res.simulateWebAPIRequestError = (error: string, statusCode?: number) => {
+      return res.status(statusCode || 500).send({ error, errorCode: ErrorCode.RequestError });
+    };
+    // https://github.com/slackapi/node-slack-sdk/blob/7b95663a9ef31036367c066ccbf0021423278f40/packages/web-api/src/WebClient.ts#L197-L199
+    res.simulateWebAPIPlatformError = (error: string, errorCode?: string) => {
       return res.send({ ok: false, error, errorCode });
     };