はじめに
皆様こんにちは、RevCommでソフトウェアエンジニアをしている加藤です。私は主にSaaSにおけるユーザーやテナントの管理および認証を担当しています!
今回は社内で構築したチケット作成Slackアプリについて話します!
背景
私たちのチームではユーザーの認証を管理しているので、お客様がログインできなかったりした際にサポートチームを通じて調査依頼が送られてきていました。毎週チームメンバーの1人が”オンコール”を担当し、その調査を担当していました。頻度的には1日1回の依頼がありましたが、チームの人数が少ないこともあり、調査が長期化すると、オンコールのメンバーがすぐに対応できないことが何度か発生していました。
また、全ての依頼はSlackから行われ、私たちのチームはNotionでタスクや調査チケットを管理しています。”オンコール”メンバーは調査をする際にはSlackの内容をまとめ、Notionに書き換える必要がありました。これは平均10分ぐらいかかる内容です。また、Notionへのタスク記入を忘れて、他のチームメンバーが現在調査中のチケット数を把握できないこともありました。
そのため、以下の点を解消するためにチケット作成Slack Appを作成しました。
- Slackでチームで決められたスタンプを押すとスタンプが押されたら、
- お客様で認証が失敗した時間や、ユーザー情報をスレッドから読み取る
- slackのスレッドの要約を作成する
- Notionにチケットを作成する
- Notionに設定してある”オンコール”の担当者にメンションする
アーキテクチャ

使用技術一覧
こちらに今回使ったAWSサービスやライブラリをまとめておきます。
| カテゴリ | 技術 | 用途 |
|---|---|---|
| API Gateway | AWS API Gateway | Slack Webhookエンドポイント |
| コンピューティング | AWS Lambda (Docker) | サーバーレス実行環境 |
| メッセージング | SNS FIFO + SQS FIFO | 非同期処理・順序保証 |
| AI | AWS Bedrock (Claude Sonnet 4) | スレッド要約生成 |
| ストレージ | Amazon ECR | LambdaのDockerイメージ保存 |
| 秘匿情報管理 | AWS Systems Manager Parameter Store | トークン・認証情報管理 |
| チャット | Slack Bolt for Python | Slackイベント処理 |
| データベース | Notion API | チケット管理 |
ポイント
2つのLambda関数で構成
Lambdaを選択したのはリクエストの頻度が非常に少ないからです。1日1回程度しか呼ばれないのであればサーバレス構成が非常に効果的です。リクエストにかかった時間の従量課金になります。
また、本システムは2つのLambda関数で構成されています:
Slackからのイベントに即座に応答するLambda:
- リアクションイベントの検知
- ユーザー・スレッドの確認とSNSへの送信
バックグラウンドでチケット作成を処理するLambda
- Slackスレッドの取得
- Bedrock経由でAI要約
- Notionチケット作成
- Slack通知
なぜ2つに分けたのかというと、Slackは3秒以内にレスポンスを返さないとタイムアウトエラーになります。一方、AI要約は数秒〜十数秒かかることがあります。そこで、即座に応答する部分と時間がかかる処理を分離し、SNS/SQSで非同期連携することで、ユーザー体験を損なわずに確実な処理を実現しています。また、slackのイベントから別のlambdaをトリガーさせたくなるかもしれないと考え、SNSを挟んでいます。
Bedrock構造化出力で要約生成
AWS Bedrockの構造化出力機能を使用することで、AIの出力を確実にPydanticモデルに変換できます:
スレッド内のテナント・ユーザー情報もしくは発生日時などをモデルに定義しておくことで、パースの失敗やバリデーションの自動化をすることができます。
#下記はサンプルです。 from typing import cast from pydantic import BaseModel, Field from strands import Agent from strands.models import BedrockModel logger = Logger() class BedrockService: def __init__(self, model_id: str, region: str, temperature: float = 0.3): self.model = BedrockModel( model_id=model_id, temperature=temperature, region_name=region, ) self.agent = Agent(model=self.model) def generate_structured_output(self, model_class: type[BaseModel], prompt: str) -> BaseModel: try: logger.info("Sending request to Bedrock for structured output") result = self.agent.structured_output(model_class, prompt=prompt) return result except Exception as e: logger.error(f"Error generating structured output: {e}") raise class TicketSummary(BaseModel): title: str = Field(..., description="One-line Notion ticket title without markdown headings") description: str = Field(..., description="Markdown body for Notion.") def summarize_thread(self, message: str) -> TicketSummary: summary = cast( TicketSummary, self.bedrock_service.generate_structured_output(TicketSummary, message), ) return summary
結果
導入後以下の効果がありました。
- オンコールメンバーの初回返信時間が20分以内になりました。
- 取りこぼすことなく、全ての調査チケットがNotionで一元的に管理できるようになりました。
まとめ
本記事では、Slackのリアクションで調査チケット作成を自動化するシステムを構築しました。
ポイントは以下です。
- ✅ 2つのLambda関数による非同期処理でSlackタイムアウトを回避
- AWS Bedrockを用いた構造化出力とPydanticによる型安全な実装
同様のパターンは、問い合わせ対応の自動化、レポート生成、データ分析など、様々な業務に応用できます。ぜひ皆さんの業務でも試してみてください!