@int31302/nestjs-slack-listener
TypeScript icon, indicating that this package has built-in type declarations

1.1.0 • Public • Published

NestJS Slack Listeners and Handlers

🥰 Any kinds of contributions are welcome! 🥰

Installation

yarn add nestjs-slack-listener

Usage

Please refer to the example for more details.

Settings

Import SlackModule

Import the module at your app module.

@Module({
  imports: [
    ConfigModule.forRoot({ isGlobal: true }),
    SlackModule.forRootAsync({
      useFactory: async (config: ConfigService<EnvVars>) => ({
        botToken: config.get('SLACK_BOT_TOKEN'),
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [],
})
export class AppModule {}

Event and Interactivity Subscription

You need to set event and interactivity subscriptions URL of your slack app so that the app can receive events and interactivity from slack.

Decorators

Slack Event

Decorate the controller to use it as slack event listener.

@Controller('on-boarding')
@SlackEventListener()
export class OnBoardingController {}

Decorate the method of the controller to use it as slack event handler.

@Controller('on-boarding')
@SlackEventListener()
export class OnBoardingController {
  constructor(private readonly onboardingService: OnBoardingService) {}

  @SlackEventHandler('team_join')
  async onTeamJoin({ event: { user } }: IncomingSlackEvent<TeamJoinEvent>) {
    this.onboardingService.startOnBoarding({ user });
  }
}

Slack Interactivity

You can also decorate the listeners and handlers for slack-interactivity.

@Controller('on-boarding')
@SlackEventListener()
@SlackInteractivityListener()
export class OnBoardingController {
  constructor(private readonly onboardingService: OnBoardingService) {}

  @SlackEventHandler('team_join')
  async onTeamJoin({ event: { user } }: IncomingSlackEvent<TeamJoinEvent>) {
    this.onboardingService.startOnBoarding({ user });
  }

  @SlackInteractivityHandler(ACTION_ID.COMPLETE_QUEST)
  async completeOnBoarding({
    user: { id: userSlackId },
    actions: [{ value }],
  }: IncomingSlackInteractivity) {
    return this.onboardingService.completeOnBoarding({ userSlackId, value });
  }
}

Filters

Filter the events with function argument filter and string argument eventType of the decorator SlackEventHandler.

@Controller('memo')
@SlackEventListener()
export class MemoController {
  constructor(private readonly memoService: MemoService) {}

  @SlackEventHandler({
    eventType: 'message',
    filter: ({ event }) => event.text.includes('write this down!'),
  })
  async takeMemo({ event: { message } }: IncomingSlackEvent<MessageEvent>) {
    this.memoService.takeMemo({ message });
  }
}

You can also filter the events at the decorator SlackEventListener

@Controller('memo')
@SlackEventListener(({ event }) => event.channel === MEMO_CHANNEL)
export class OnBoardingController {
  constructor(private readonly memoService: MemoService) {}

  @SlackEventHandler({
    eventType: 'message',
    filter: ({ event }) => event.text.includes('write this down!'),
  })
  async onTeamJoin({ event: { user } }: IncomingSlackEvent<MessageEvent>) {
    this.memoService.takeMemo({ message });
  }
}

Slack Client

Use InjectSlackClient to use the slack web api client.

@Injectable()
export class OnBoardingService {
  constructor(
    private readonly userRepository: UserRepository,
    @InjectSlackClient()
    private readonly slack: SlackClient,
  ) {}
  ...
}

The injected SlackClient is identical to the official Slack Web API Client

await this.slack.chat.postMessage({
  channel: user.id,
  text: 'Hi there! 👋🏻',
  blocks: [
    {
      type: 'header',
      text: {
        type: 'plain_text',
        text: 'Hi there! 👋🏻',
      },
    },
    {
      type: 'section',
      text: {
        type: 'mrkdwn',
        text: `Hello! Nice to meet you, ${user.name}! I'm *hanch*, a slack bot that helps you with onboarding process.`,
      },
    },
  ],
});

Package Sidebar

Install

npm i @int31302/nestjs-slack-listener

Weekly Downloads

3

Version

1.1.0

License

MIT

Unpacked Size

57.3 kB

Total Files

43

Last publish

Collaborators

  • int31302