InstallerService.ts 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import {
  2. InstallationQuery,
  3. InstallProvider,
  4. Installation as SlackInstallation,
  5. } from '@slack/oauth';
  6. import { Inject, Service } from '@tsed/di';
  7. import { Installation } from '~/entities/installation';
  8. import { InstallationRepository } from '~/repositories/installation';
  9. @Service()
  10. export class InstallerService {
  11. installer: InstallProvider;
  12. @Inject()
  13. private readonly repository: InstallationRepository;
  14. $onInit(): Promise<any> | void {
  15. const clientId = process.env.SLACK_CLIENT_ID;
  16. const clientSecret = process.env.SLACK_CLIENT_SECRET;
  17. const stateSecret = process.env.SLACK_INSTALLPROVIDER_STATE_SECRET;
  18. if (clientId === undefined) {
  19. throw new Error(
  20. "The environment variable 'SLACK_CLIENT_ID' must be defined.",
  21. );
  22. }
  23. if (clientSecret === undefined) {
  24. throw new Error(
  25. "The environment variable 'SLACK_CLIENT_SECRET' must be defined.",
  26. );
  27. }
  28. const { repository } = this;
  29. this.installer = new InstallProvider({
  30. clientId,
  31. clientSecret,
  32. stateSecret,
  33. legacyStateVerification: true,
  34. installationStore: {
  35. // upsert
  36. storeInstallation: async (
  37. slackInstallation: SlackInstallation<'v1' | 'v2', boolean>,
  38. ) => {
  39. const teamIdOrEnterpriseId =
  40. slackInstallation.team?.id || slackInstallation.enterprise?.id;
  41. if (teamIdOrEnterpriseId == null) {
  42. throw new Error('teamId or enterpriseId is required.');
  43. }
  44. const existedInstallation =
  45. await repository.findByTeamIdOrEnterpriseId(teamIdOrEnterpriseId);
  46. if (existedInstallation != null) {
  47. existedInstallation.setData(slackInstallation);
  48. await repository.save(existedInstallation);
  49. return;
  50. }
  51. const installation = new Installation();
  52. installation.setData(slackInstallation);
  53. await repository.save(installation);
  54. return;
  55. },
  56. fetchInstallation: async (installQuery: InstallationQuery<boolean>) => {
  57. const id = installQuery.enterpriseId || installQuery.teamId;
  58. // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  59. const installation = await repository.findByTeamIdOrEnterpriseId(id!);
  60. if (installation == null) {
  61. throw new Error('Failed fetching installation');
  62. }
  63. return installation.data;
  64. },
  65. },
  66. });
  67. }
  68. }