🗂

【個人開発】言いにくいことを代わりに言ってもらうSlackのスラッシュコマンド作りました

2023/05/24に公開

なんだか初歩的な気がするから気が引ける質問とか、いまさら聞きづらいこととか、ありますよね?また、コミュニティに入ったばかりだから発言しづらいみたいなこともあると思います。
しかもSlackだと匿名での投稿ができないからなおさら投稿しづらい。

そんな課題を解決するコマンドを作りました!!(めんどくさくてハードコードしている部分が多いので配布までこぎつけてません)

※このプロダクトは、株式会社mofmofの「水曜日の個人開発」にサポートされています。
https://indie-dev.mof-mof.co.jp

利用イメージ

入力した内容を、mofmofのマスコットであるどんうさぎが代わりに発言してくれるというものになっています。

うわあ、聞きづらい!社長が誰かも知らないで入社しちゃうなんてことよくありますよね。

代わりに聞いてくれました!ふてぶてしい!
「何だっけ」はないだろう…と思いますがどんうさぎなので許されます。

以上だぞ。

技術的な話

Slackで入力した内容をLambdaで処理してます。SAMのtemplate.yamlはこんな感じ。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: compress
Parameters:
  SlackApiToken:
    Type: String
    Description: メッセージを送るSlackのAPIトークン
  GPTApiToken:
    Type: String
    Description: GPTのAPIキー

Resources:
  SlackFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: slack/
      Handler: app.lambda_handler
      Runtime: python3.9
      Timeout: 10
      Role: !GetAtt LambdaExecutionRole.Arn
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /slack
            Method: POST
      Layers:
        - !Ref LibraryLayer
      Environment:
        Variables:
          MAIN_LAMBDA_ARN: !GetAtt MainFunction.Arn

  LibraryLayer:
    Type: "AWS::Serverless::LayerVersion"
    Properties:
      LayerName: PythonLibraryLayer
      ContentUri: python/
      CompatibleRuntimes:
        - python3.9
      RetentionPolicy: Delete

  MainFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: main/
      Handler: app.lambda_handler
      Runtime: python3.9
      Timeout: 60
      Layers:
        - !Ref LibraryLayer
      Environment:
        Variables:
          SLACK_API_TOKEN: !Ref SlackApiToken
          OPENAI_API_KEY: !Ref GPTApiToken

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: lambda-execution-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource: !GetAtt MainFunction.Arn
        - PolicyName: lambda-cloudwatch-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: 'arn:aws:logs:*:*:*'

何も考えずに実装するとタイムアウトになってしまうので、Slackからのリクエストを受ける関数とGPTとやりとりをしてメッセージを投稿する関数を分けています。
template.yamlでいうところの SlackFunctionMainFunction ですね。

SlackFunctionはMainFunctionを呼び出しつつSlackに「処理を受け付けた」旨を返すだけの処理です。
MainFunctionは入力内容をGPTに投げて返ってきたらSlackのAPIでメッセージを投稿します。GPTは投稿内容をどんうさぎ口調に変換するためだけに使ってます。

スラッシュコマンドは実行後3秒以内にレスポンスが返ってこないとタイムアウトになってしまうので、その対策のためこのような構成にしています。

まとめ

匿名で投稿できるとか、発言するのはどんうさぎだから何言っても許されるという利点があります。
GPTへの投げ方次第で無限の可能性を秘めているので、ぜひぜひ作ってみてください。

Discussion