interaction-payload-accessor.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import assert from 'assert';
  2. import type { IChannel } from '../interfaces/channel';
  3. import type { IInteractionPayloadAccessor } from '../interfaces/request-from-slack';
  4. import loggerFactory from './logger';
  5. const logger = loggerFactory('@growi/slack:utils:interaction-payload-accessor');
  6. export class InteractionPayloadAccessor implements IInteractionPayloadAccessor {
  7. private payload: any;
  8. // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
  9. constructor(payload: any) {
  10. this.payload = payload;
  11. }
  12. firstAction(): any | null {
  13. const actions = this.payload.actions;
  14. if (actions != null && actions[0] != null) {
  15. return actions[0];
  16. }
  17. return null;
  18. }
  19. getResponseUrl(): string {
  20. const responseUrl = this.payload.response_url;
  21. if (responseUrl != null) {
  22. return responseUrl;
  23. }
  24. const responseUrls = this.payload.response_urls;
  25. assert(responseUrls != null);
  26. assert(responseUrls[0] != null);
  27. return responseUrls[0].response_url;
  28. }
  29. getStateValues(): any | null {
  30. const state = this.payload.state;
  31. if (state != null && state.values != null) {
  32. return state.values;
  33. }
  34. const view = this.payload.view;
  35. if (view != null && view.state != null && view.state.values != null) {
  36. return view.state.values;
  37. }
  38. return null;
  39. }
  40. getViewPrivateMetaData(): any | null {
  41. const view = this.payload.view;
  42. if (view != null && view.private_metadata) {
  43. return JSON.parse(view.private_metadata);
  44. }
  45. return null;
  46. }
  47. getActionIdAndCallbackIdFromPayLoad(): {[key: string]: string} {
  48. const actionId = this.firstAction()?.action_id || '';
  49. const callbackId = this.payload.view?.callback_id || '';
  50. return { actionId, callbackId };
  51. }
  52. getChannel(): IChannel | null {
  53. // private_metadata should have the channelName parameter when view_submission
  54. const privateMetadata = this.getViewPrivateMetaData();
  55. if (privateMetadata != null && privateMetadata.channelName != null) {
  56. throw new Error('PrivateMetaDatas are not implemented after removal of modal from slash commands. Use payload instead.');
  57. }
  58. const channel = this.payload.channel;
  59. if (channel != null) {
  60. return channel;
  61. }
  62. return null;
  63. }
  64. getOriginalData(): any | null {
  65. const value = this.firstAction()?.value;
  66. if (value == null) return null;
  67. const { originalData } = JSON.parse(value);
  68. if (originalData == null) return JSON.parse(value);
  69. let parsedOriginalData;
  70. try {
  71. parsedOriginalData = JSON.parse(originalData);
  72. }
  73. catch (err) {
  74. logger.error('Failed to parse original data:\n', err);
  75. return null;
  76. }
  77. return parsedOriginalData;
  78. }
  79. }