Ver Fonte

refactor generateClient

Yuki Takei há 4 anos atrás
pai
commit
95700be49b

+ 14 - 13
packages/app/src/server/routes/apiv3/slack-integration.js

@@ -98,7 +98,7 @@ module.exports = (crowi) => {
     return next();
     return next();
   };
   };
 
 
-  async function handleCommands(req, res) {
+  async function handleCommands(req, res, client) {
     const { body } = req;
     const { body } = req;
 
 
     if (body.text == null) {
     if (body.text == null) {
@@ -113,9 +113,6 @@ module.exports = (crowi) => {
     // 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();
 
 
-    const tokenPtoG = req.headers['x-growi-ptog-tokens'];
-    const client = await slackIntegrationService.generateClient(tokenPtoG);
-
     const args = body.text.split(' ');
     const args = body.text.split(' ');
     const command = args[0];
     const command = args[0];
 
 
@@ -129,7 +126,8 @@ module.exports = (crowi) => {
   }
   }
 
 
   router.post('/commands', addSigningSecretToReq, verifySlackRequest, async(req, res) => {
   router.post('/commands', addSigningSecretToReq, verifySlackRequest, async(req, res) => {
-    return handleCommands(req, res);
+    const client = await slackIntegrationService.generateClientForCustomBotWithoutProxy();
+    return handleCommands(req, res, client);
   });
   });
 
 
   router.post('/proxied/commands', verifyAccessTokenFromProxy, checkCommandPermission, async(req, res) => {
   router.post('/proxied/commands', verifyAccessTokenFromProxy, checkCommandPermission, async(req, res) => {
@@ -141,19 +139,18 @@ module.exports = (crowi) => {
       return res.send({ challenge: body.challenge });
       return res.send({ challenge: body.challenge });
     }
     }
 
 
-    return handleCommands(req, res);
+    const tokenPtoG = req.headers['x-growi-ptog-tokens'];
+    const client = await slackIntegrationService.generateClientByTokenPtoG(tokenPtoG);
+
+    return handleCommands(req, res, client);
   });
   });
 
 
-  async function handleInteractions(req, res) {
+  async function handleInteractions(req, res, client) {
 
 
     // Send response immediately to avoid opelation_timeout error
     // Send response immediately to avoid opelation_timeout error
     // 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();
 
 
-
-    const tokenPtoG = req.headers['x-growi-ptog-tokens'];
-    const client = await slackIntegrationService.generateClient(tokenPtoG);
-
     const payload = JSON.parse(req.body.payload);
     const payload = JSON.parse(req.body.payload);
     const { type } = payload;
     const { type } = payload;
 
 
@@ -186,11 +183,15 @@ module.exports = (crowi) => {
   }
   }
 
 
   router.post('/interactions', addSigningSecretToReq, verifySlackRequest, async(req, res) => {
   router.post('/interactions', addSigningSecretToReq, verifySlackRequest, async(req, res) => {
-    return handleInteractions(req, res);
+    const client = await slackIntegrationService.generateClientForCustomBotWithoutProxy();
+    return handleInteractions(req, res, client);
   });
   });
 
 
   router.post('/proxied/interactions', verifyAccessTokenFromProxy, checkCommandPermission, async(req, res) => {
   router.post('/proxied/interactions', verifyAccessTokenFromProxy, checkCommandPermission, async(req, res) => {
-    return handleInteractions(req, res);
+    const tokenPtoG = req.headers['x-growi-ptog-tokens'];
+    const client = await slackIntegrationService.generateClientByTokenPtoG(tokenPtoG);
+
+    return handleInteractions(req, res, client);
   });
   });
 
 
   router.get('/supported-commands', verifyAccessTokenFromProxy, async(req, res) => {
   router.get('/supported-commands', verifyAccessTokenFromProxy, async(req, res) => {

+ 56 - 32
packages/app/src/server/service/slack-integration.ts

@@ -96,55 +96,79 @@ export class SlackIntegrationService implements S2sMessageHandlable {
     return hasSlackToken || hasSlackIwhUrl;
     return hasSlackToken || hasSlackIwhUrl;
   }
   }
 
 
+  private isCheckTypeValid(): boolean {
+    const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    if (currentBotType == null) {
+      throw new Error('The config \'SLACK_BOT_TYPE\'(ns: \'crowi\', key: \'slackbot:currentBotType\') must be set.');
+    }
+
+    return true;
+  }
+
   /**
   /**
    * generate WebClient instance for 'customBotWithoutProxy' type
    * generate WebClient instance for 'customBotWithoutProxy' type
    */
    */
-  async generateClient(): Promise<WebClient>;
+  async generateClientForCustomBotWithoutProxy(): Promise<WebClient> {
+    this.isCheckTypeValid();
+
+    const token = this.configManager.getConfig('crowi', 'slackbot:token');
+
+    if (token == null) {
+      throw new Error('The config \'SLACK_BOT_TOKEN\'(ns: \'crowi\', key: \'slackbot:token\') must be set.');
+    }
+
+    return generateWebClient(token);
+  }
 
 
   /**
   /**
    * generate WebClient instance by tokenPtoG
    * generate WebClient instance by tokenPtoG
    * @param tokenPtoG
    * @param tokenPtoG
    */
    */
-  async generateClient(tokenPtoG: string): Promise<WebClient>;
-
-  /**
-   * generate WebClient instance by SlackAppIntegration
-   * @param slackAppIntegration
-   */
-  async generateClient(slackAppIntegration?: { tokenGtoP: string }): Promise<WebClient>;
+  async generateClientByTokenPtoG(tokenPtoG: string): Promise<WebClient> {
+    this.isCheckTypeValid();
 
 
-  async generateClient(arg?: string | { tokenGtoP: string }): Promise<WebClient> {
     const SlackAppIntegration = mongoose.model('SlackAppIntegration');
     const SlackAppIntegration = mongoose.model('SlackAppIntegration');
 
 
-    const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
+    const slackAppIntegration = await SlackAppIntegration.findOne({ tokenPtoG });
 
 
-    if (currentBotType == null) {
-      throw new Error('The config \'SLACK_BOT_TYPE\'(ns: \'crowi\', key: \'slackbot:currentBotType\') must be set.');
+    if (slackAppIntegration == null) {
+      throw new Error('No SlackAppIntegration exists that corresponds to the tokenPtoG specified.');
     }
     }
 
 
-    // connect directly
-    if (currentBotType === 'customBotWithoutProxy') {
-      if (arg != null) {
-        throw new Error('This method cannot be used with non-null argument under \'customBotWithoutProxy\' type.');
-      }
+    return this.generateClientBySlackAppIntegration(slackAppIntegration as unknown as { tokenGtoP: string; });
+  }
 
 
-      const token = this.configManager.getConfig('crowi', 'slackbot:token');
-      return generateWebClient(token);
-    }
+  /**
+   * generate WebClient instance by tokenPtoG
+   * @param tokenPtoG
+   */
+  async generateClientForPrimaryWorkspace(): Promise<WebClient> {
+    this.isCheckTypeValid();
+
+    const currentBotType = this.configManager.getConfig('crowi', 'slackbot:currentBotType');
 
 
-    if (arg == null) {
-      throw new Error('This method cannot be used with null argument under \'officialBot / customBotWithProxy\' type.');
+    if (currentBotType === 'customBotWithoutProxy') {
+      return this.generateClientForCustomBotWithoutProxy();
     }
     }
 
 
+    // retrieve primary SlackAppIntegration
+    const SlackAppIntegration = mongoose.model('SlackAppIntegration');
+    const slackAppIntegration = await SlackAppIntegration.findOne({ isPrimary: true });
 
 
-    let slackAppIntegration;
-    if (typeof arg === 'string') {
-      slackAppIntegration = await SlackAppIntegration.findOne({ tokenPtoG: arg });
-    }
-    else {
-      slackAppIntegration = arg;
+    if (slackAppIntegration == null) {
+      throw new Error('None of the primary SlackAppIntegration exists.');
     }
     }
 
 
+    return this.generateClientBySlackAppIntegration(slackAppIntegration as unknown as { tokenGtoP: string; });
+  }
+
+  /**
+   * generate WebClient instance by SlackAppIntegration
+   * @param slackAppIntegration
+   */
+  async generateClientBySlackAppIntegration(slackAppIntegration: { tokenGtoP: string }): Promise<WebClient> {
+    this.isCheckTypeValid();
+
     // connect to proxy
     // connect to proxy
     const proxyServerUri = this.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
     const proxyServerUri = this.configManager.getConfig('crowi', 'slackbot:proxyServerUri');
     const serverUri = new URL('/g2s', proxyServerUri);
     const serverUri = new URL('/g2s', proxyServerUri);
@@ -155,15 +179,15 @@ export class SlackIntegrationService implements S2sMessageHandlable {
     return generateWebClient(undefined, serverUri.toString(), headers);
     return generateWebClient(undefined, serverUri.toString(), headers);
   }
   }
 
 
-  async postMessage(messageArgs: ChatPostMessageArguments): Promise<void> {
+  async postMessage(messageArgs: ChatPostMessageArguments, slackAppIntegration?: { tokenGtoP: string; }): Promise<void> {
     // use legacy slack configuration
     // use legacy slack configuration
     if (this.isSlackLegacyConfigured && !this.isSlackbotConfigured) {
     if (this.isSlackLegacyConfigured && !this.isSlackbotConfigured) {
       return this.postMessageWithLegacyUtil(messageArgs);
       return this.postMessageWithLegacyUtil(messageArgs);
     }
     }
 
 
-    // TODO: determine target slack workspace
-    const tokenPtoG = '...';
-    const client = await this.generateClient(tokenPtoG);
+    const client = slackAppIntegration == null
+      ? await this.generateClientForPrimaryWorkspace()
+      : await this.generateClientBySlackAppIntegration(slackAppIntegration);
 
 
     try {
     try {
       await client.chat.postMessage(messageArgs);
       await client.chat.postMessage(messageArgs);