Browse Source

add ViewInteractionPayloadDelegator

Yuki Takei 4 years ago
parent
commit
a87cb7335b

+ 6 - 4
packages/slackbot-proxy/src/controllers/growi-to-slack.ts

@@ -20,6 +20,7 @@ import { InstallerService } from '~/services/InstallerService';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 import { findInjectorByType } from '~/services/growi-uri-injector/GrowiUriInjectorFactory';
 import { findInjectorByType } from '~/services/growi-uri-injector/GrowiUriInjectorFactory';
 import { injectGrowiUriToView } from '~/utils/injectGrowiUriToView';
 import { injectGrowiUriToView } from '~/utils/injectGrowiUriToView';
+import { ViewInteractionPayloadDelegator } from '~/services/growi-uri-injector/ViewInteractionPayloadDelegator';
 
 
 
 
 const logger = loggerFactory('slackbot-proxy:controllers:growi-to-slack');
 const logger = loggerFactory('slackbot-proxy:controllers:growi-to-slack');
@@ -173,11 +174,12 @@ export class GrowiToSlackCtrl {
 
 
   injectGrowiUri(req:GrowiReq, growiUri:string):WebAPICallOptions {
   injectGrowiUri(req:GrowiReq, growiUri:string):WebAPICallOptions {
 
 
-    if (req.body.view != null) {
-      injectGrowiUriToView(req.body, growiUri);
+    // TODO: iterate with decorator
+    const vipd = new ViewInteractionPayloadDelegator();
+    if (vipd.shouldHandleToInject(req.body)) {
+      vipd.inject(req.body, growiUri);
     }
     }
-
-    if (req.body.blocks != null) {
+    else if (req.body.blocks != null) {
       const parsedBlocks = JSON.parse(req.body.blocks as string);
       const parsedBlocks = JSON.parse(req.body.blocks as string);
 
 
       parsedBlocks.forEach((parsedBlock) => {
       parsedBlocks.forEach((parsedBlock) => {

+ 32 - 0
packages/slackbot-proxy/src/interfaces/growi-to-slack/growi-uri-injector.ts

@@ -0,0 +1,32 @@
+
+export type GrowiUriWithOriginalData = {
+  growiUri: string,
+  originalData: string,
+}
+
+/**
+ * Type guard for GrowiUriWithOriginalData
+ * @param data
+ * @returns
+ */
+// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+export const isGrowiUriWithOriginalData = (data: any): data is GrowiUriWithOriginalData => {
+  return data.growiUri != null && data.originalData != null;
+};
+
+export interface GrowiUriInjector<IB, EP> {
+
+  shouldHandleToInject(body: any): boolean;
+  inject(body: IB, growiUri:string): void;
+
+  shouldHandleToExtract(body: any): boolean;
+  extract(payload: EP): GrowiUriWithOriginalData;
+
+}
+
+export interface ObsoleteGrowiUriInjector {
+
+  inject(body: any, growiUri:string): void;
+
+  extract(body: any):any;
+}

+ 19 - 19
packages/slackbot-proxy/src/middlewares/slack-to-growi/extract-growi-uri-from-req.ts

@@ -3,7 +3,7 @@ import {
 } from '@tsed/common';
 } from '@tsed/common';
 import { SlackOauthReq } from '~/interfaces/slack-to-growi/slack-oauth-req';
 import { SlackOauthReq } from '~/interfaces/slack-to-growi/slack-oauth-req';
 import { growiUriInjectorFactory } from '~/services/growi-uri-injector/GrowiUriInjectorFactory';
 import { growiUriInjectorFactory } from '~/services/growi-uri-injector/GrowiUriInjectorFactory';
-import { extractGrowiUriFromView } from '~/utils/extractGrowiUriFromView';
+import { ViewInteractionPayloadDelegator } from '~/services/growi-uri-injector/ViewInteractionPayloadDelegator';
 
 
 @Middleware()
 @Middleware()
 export class ExtractGrowiUriFromReq implements IMiddleware {
 export class ExtractGrowiUriFromReq implements IMiddleware {
@@ -17,25 +17,25 @@ export class ExtractGrowiUriFromReq implements IMiddleware {
 
 
     const payload = JSON.parse(req.body.payload);
     const payload = JSON.parse(req.body.payload);
 
 
-    // extract for modal
-    if (payload.view != null) {
-      const extractedValues = extractGrowiUriFromView(payload.view);
-      req.growiUri = extractedValues.growiUri;
-      payload.view.private_metadata = extractedValues.originalData;
-    }
-    else {
-      // break when uri is found
-      for (const type of Object.keys(growiUriInjectorFactory)) {
-        const growiUriInjector = growiUriInjectorFactory[type]();
-        const extractedValues = growiUriInjector.extract(payload.actions[0]);
-
-        if (extractedValues.growiUri != null) {
-          req.growiUri = extractedValues.growiUri;
-          payload.actions[0].value = JSON.stringify(extractedValues.originalData);
-          break;
-        }
-      }
+    // TODO: iterate with decorator
+    const vipd = new ViewInteractionPayloadDelegator();
+    if (vipd.shouldHandleToExtract(payload)) {
+      const data = vipd.extract(payload);
+      req.growiUri = data.growiUri;
     }
     }
+    // else {
+    //   // break when uri is found
+    //   for (const type of Object.keys(growiUriInjectorFactory)) {
+    //     const growiUriInjector = growiUriInjectorFactory[type]();
+    //     const extractedValues = growiUriInjector.extract(payload.actions[0]);
+
+    //     if (extractedValues.growiUri != null) {
+    //       req.growiUri = extractedValues.growiUri;
+    //       payload.actions[0].value = JSON.stringify(extractedValues.originalData);
+    //       break;
+    //     }
+    //   }
+    // }
 
 
     req.body.payload = JSON.stringify(payload);
     req.body.payload = JSON.stringify(payload);
 
 

+ 2 - 2
packages/slackbot-proxy/src/services/growi-uri-injector/GrowiUriInjectionButtonDelegator.ts

@@ -1,6 +1,6 @@
-import { GrowiUriInjector } from './GrowiUriInjector';
+import { ObsoleteGrowiUriInjector } from '~/interfaces/growi-to-slack/growi-uri-injector';
 
 
-export class GrowiUriInjectionButtonDelegator implements GrowiUriInjector {
+export class GrowiUriInjectionButtonDelegator implements ObsoleteGrowiUriInjector {
 
 
   inject(element: {value:string}, growiUri:string): void {
   inject(element: {value:string}, growiUri:string): void {
     const parsedValue = JSON.parse(element.value);
     const parsedValue = JSON.parse(element.value);

+ 0 - 7
packages/slackbot-proxy/src/services/growi-uri-injector/GrowiUriInjector.ts

@@ -1,7 +0,0 @@
-
-export interface GrowiUriInjector {
-
-  inject(body: any, growiUri:string): void;
-
-  extract(body: any):any;
-}

+ 3 - 3
packages/slackbot-proxy/src/services/growi-uri-injector/GrowiUriInjectorFactory.ts

@@ -1,16 +1,16 @@
-import { GrowiUriInjector } from './GrowiUriInjector';
+import { ObsoleteGrowiUriInjector } from '~/interfaces/growi-to-slack/growi-uri-injector';
 import { GrowiUriInjectionButtonDelegator } from './GrowiUriInjectionButtonDelegator';
 import { GrowiUriInjectionButtonDelegator } from './GrowiUriInjectionButtonDelegator';
 
 
 /**
 /**
  * Instanciate GrowiUriInjector
  * Instanciate GrowiUriInjector
  */
  */
 export const growiUriInjectorFactory = {
 export const growiUriInjectorFactory = {
-  button: (): GrowiUriInjector => {
+  button: (): ObsoleteGrowiUriInjector => {
     return new GrowiUriInjectionButtonDelegator();
     return new GrowiUriInjectionButtonDelegator();
   },
   },
 };
 };
 
 
-export const findInjectorByType = (type:string): null|GrowiUriInjector => {
+export const findInjectorByType = (type:string): null|ObsoleteGrowiUriInjector => {
   if (!Object.keys(growiUriInjectorFactory).includes(type)) {
   if (!Object.keys(growiUriInjectorFactory).includes(type)) {
     return null;
     return null;
   }
   }

+ 45 - 0
packages/slackbot-proxy/src/services/growi-uri-injector/ViewInteractionPayloadDelegator.ts

@@ -0,0 +1,45 @@
+import { GrowiUriInjector, GrowiUriWithOriginalData, isGrowiUriWithOriginalData } from '~/interfaces/growi-to-slack/growi-uri-injector';
+
+export class ViewInteractionPayloadDelegator implements GrowiUriInjector<{view: string}, {view: {'private_metadata': string}}> {
+
+  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+  shouldHandleToInject(body: any): boolean {
+    return body.view != null;
+  }
+
+  inject(body: {view: string}, growiUri:string): void {
+    const parsedView = JSON.parse(body.view);
+    const originalData = JSON.stringify(parsedView.private_metadata);
+
+    const data: GrowiUriWithOriginalData = { growiUri, originalData };
+
+    parsedView.private_metadata = JSON.stringify(data);
+    body.view = JSON.stringify(parsedView);
+  }
+
+  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+  shouldHandleToExtract(payload: {type: string, view?: any}): boolean {
+    const { type, view } = payload;
+    if (type !== 'view_submission') {
+      return false;
+    }
+
+    try {
+      const data: any = JSON.parse(view.private_metadata);
+      return isGrowiUriWithOriginalData(data);
+    }
+    // when parsing failed
+    catch (err) {
+      return false;
+    }
+  }
+
+  extract(payload: {view: {'private_metadata': string}}): GrowiUriWithOriginalData {
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const data: GrowiUriWithOriginalData = JSON.parse(payload.view.private_metadata!); // private_metadata must not be null at this moment
+    payload.view.private_metadata = JSON.parse(data.originalData);
+
+    return data;
+  }
+
+}

+ 0 - 10
packages/slackbot-proxy/src/utils/extractGrowiUriFromView.ts

@@ -1,10 +0,0 @@
-export const extractGrowiUriFromView = (view:{'private_metadata': string}): {growiUri?:string, originalData:{[key:string]:any}} => {
-  const parsedValues = JSON.parse(view.private_metadata);
-  if (parsedValues.originalData != null) {
-    parsedValues.originalData = JSON.parse(parsedValues.originalData);
-  }
-  else {
-    parsedValues.originalData = view.private_metadata;
-  }
-  return parsedValues;
-};

+ 0 - 7
packages/slackbot-proxy/src/utils/injectGrowiUriToView.ts

@@ -1,7 +0,0 @@
-export const injectGrowiUriToView = (body: {view:string}, growiUri:string): void => {
-  const parsedView = JSON.parse(body.view);
-  const originalData = JSON.stringify(parsedView.private_metadata);
-
-  parsedView.private_metadata = JSON.stringify({ growiUri, originalData });
-  body.view = JSON.stringify(parsedView);
-};