RegisterService.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Inject, Service } from '@tsed/di';
  2. import { WebClient, LogLevel, Block } from '@slack/web-api';
  3. import { BlockKitBuilder as B, GrowiCommand } from '@growi/slack';
  4. import { AuthorizeResult } from '@slack/oauth';
  5. import { GrowiCommandProcessor } from '~/interfaces/slack-to-growi/growi-command-processor';
  6. import { OrderRepository } from '~/repositories/order';
  7. import { Installation } from '~/entities/installation';
  8. import { InvalidUrlError } from '../models/errors';
  9. const isProduction = process.env.NODE_ENV === 'production';
  10. const isOfficialMode = process.env.OFFICIAL_MODE === 'true';
  11. @Service()
  12. export class RegisterService implements GrowiCommandProcessor {
  13. @Inject()
  14. orderRepository: OrderRepository;
  15. async process(growiCommand: GrowiCommand, authorizeResult: AuthorizeResult, body: {[key:string]:string}): Promise<void> {
  16. const { botToken } = authorizeResult;
  17. const client = new WebClient(botToken, { logLevel: isProduction ? LogLevel.DEBUG : LogLevel.INFO });
  18. await client.views.open({
  19. trigger_id: body.trigger_id,
  20. view: {
  21. type: 'modal',
  22. callback_id: 'register',
  23. title: {
  24. type: 'plain_text',
  25. text: 'Register Credentials',
  26. },
  27. submit: {
  28. type: 'plain_text',
  29. text: 'Submit',
  30. },
  31. close: {
  32. type: 'plain_text',
  33. text: 'Close',
  34. },
  35. private_metadata: JSON.stringify({ channel: body.channel_name }),
  36. blocks: [
  37. B.inputSectionBlock('growiUrl', 'GROWI domain', 'contents_input', false, 'https://example.com'),
  38. B.inputSectionBlock('tokenPtoG', 'Access Token Proxy to GROWI', 'contents_input', false, 'jBMZvpk.....'),
  39. B.inputSectionBlock('tokenGtoP', 'Access Token GROWI to Proxy', 'contents_input', false, 'sdg15av.....'),
  40. ],
  41. },
  42. });
  43. }
  44. async replyToSlack(client: WebClient, channel: string, user: string, text: string, blocks: Array<Block>): Promise<void> {
  45. await client.chat.postEphemeral({
  46. channel,
  47. user,
  48. // Recommended including 'text' to provide a fallback when using blocks
  49. // refer to https://api.slack.com/methods/chat.postEphemeral#text_usage
  50. text,
  51. blocks,
  52. });
  53. return;
  54. }
  55. async insertOrderRecord(
  56. installation: Installation | undefined,
  57. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  58. botToken: string | undefined, payload: any,
  59. ): Promise<void> {
  60. const inputValues = payload.view.state.values;
  61. const growiUrl = inputValues.growiUrl.contents_input.value;
  62. const tokenPtoG = inputValues.tokenPtoG.contents_input.value;
  63. const tokenGtoP = inputValues.tokenGtoP.contents_input.value;
  64. const { channel } = JSON.parse(payload.view.private_metadata);
  65. const client = new WebClient(botToken, { logLevel: isProduction ? LogLevel.DEBUG : LogLevel.INFO });
  66. try {
  67. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  68. const url = new URL(growiUrl);
  69. }
  70. catch (error) {
  71. const invalidErrorMsg = 'Please enter a valid URL';
  72. const blocks = [
  73. B.markdownSectionBlock(invalidErrorMsg),
  74. ];
  75. await this.replyToSlack(client, channel, payload.user.id, 'Invalid URL', blocks);
  76. throw new InvalidUrlError(growiUrl);
  77. }
  78. this.orderRepository.save({
  79. installation, growiUrl, tokenPtoG, tokenGtoP,
  80. });
  81. }
  82. async notifyServerUriToSlack(
  83. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  84. botToken: string | undefined, payload: any,
  85. ): Promise<void> {
  86. const { channel } = JSON.parse(payload.view.private_metadata);
  87. const serverUri = process.env.SERVER_URI;
  88. const client = new WebClient(botToken, { logLevel: isProduction ? LogLevel.DEBUG : LogLevel.INFO });
  89. if (isOfficialMode) {
  90. const blocks = [
  91. B.markdownSectionBlock('Successfully registered with the proxy! Please check test connection in your GROWI'),
  92. ];
  93. await this.replyToSlack(client, channel, payload.user.id, 'Proxy URL', blocks);
  94. return;
  95. }
  96. const blocks = [
  97. B.markdownSectionBlock('Please enter and update the following Proxy URL to slack bot setting form in your GROWI'),
  98. B.markdownSectionBlock(`Proxy URL: ${serverUri}`),
  99. ];
  100. await this.replyToSlack(client, channel, payload.user.id, 'Proxy URL', blocks);
  101. return;
  102. }
  103. }