Slackの投稿に含まれる社内Notion記事をSlack上でプレビューする

2023/02/15に公開

まえおき

昨年末、Notion公式Slackアプリがアップデートされました。
https://twitter.com/NotionJP/status/1603312342250684418

これまではSlack上で組織内のNotion記事をOGPのようにプレビューするための公式手段が用意されていなかったため、このアップデートは多くの人にとって朗報だったのではないでしょうか。
このアップデートがある前は、自前でプレビューする機能を実装する必要があったため(少なくとも自分は公式のNotionAPIに対応する良さそうなアプリを見つけられず😞)、弊社でも自前で実装して1年弱ほど運用を続けていました。
https://twitter.com/preface/status/1504762890041331714

この機会に公式アプリへ乗り換えることを検討したのですが、検討の結果、自前のSlackアプリを運用し続けることにしました。

今回は、弊社で利用しているSlackアプリがどのような仕様で実装・構築されているのか紹介したいと思います。

公式と弊社でのプレビュー表示の違い

Notion公式アプリのプレビューがこちらです。

弊社で実装しているプレビューがこちらです。

大きな違いとして挙げられるのは

  1. コンテンツ内容をできるだけプレビュー内に含めている
  2. Databaseプロパティをカスタマイズして表示している

の2点です。
自前実装を始めたときになぜこの仕様が必要だったのか、順番に説明します。

可能な限りSlack上だけで記事閲覧が完結するようにしている

もちろんプレビューが何も無い状態と比較すると、タイトルや序文が表示されるだけでも、クリックすべきか圧倒的に判断しやすいです。
ですが、コンテンツ内容をできるだけ正確にプレビューに含める事により、Notionに遷移しなくてもざっと内容がわかるなら、それに越したことはないと考えて仕様を作っていきました。
もちろんSlack上での表現の限界があるため、すべてというわけにはいきません。このあたりを実装する上でのポイントは別途Podcastなどで話せればなと思います。

Databaseプロパティが記事のスコープを絞る手がかりを与える

弊社では、NotionのDatabaseを活用して、ページ同士にタグ付けし合うような構成にしています。どのチームの話なのか、誰が関係しているのかという情報がDatabaseプロパティに保存されています。
https://timetreeapp.com/intl/ja/newsroom/blog/2022-02-07/notion

そのため Databaseプロパティがないとタイトルからだけでは判断が難しい というケースがよく見られました。これは、運用していく中でわかったことです。
例えば「開発フローについて」という記事タイトルだったとして、それが特定のチームの話なのか、全体に関わることなのか、スコープがパッと見てわかりづらいという感じです。

Notionいいねの利用を促進する

弊社ではNotion記事にいいねボタンを付ける機能を独自で作って運用しています。
https://zenn.dev/fujikky/articles/4e1471cd79ded9
https://zenn.dev/lazy/articles/notion-like-slack-notifier

いいね が多くされている記事は読んでみようかなと思いますよね。これも、プレビュー表示に必要な要素だと考え実装しています。

実装の仕組み

Slackには、投稿にリンクが含まれる場合にそれをプレビューするための仕組みがあります。(unfurlという単語の意味はこれを見て初めて知りました)
https://api.slack.com/reference/messaging/link-unfurling

記事内より引用

図を簡単に説明すると、左上のような投稿があったらSlackは link_shared イベントを発生させます。そのイベントを、右下の自前処理で受け取ってプレビュー情報を整形し、Slack APIの chat.unfurl メソッドによりSlackへ情報を送信すると、左上の投稿が上書きされて、プレビューを出すことができるというものです。

システム構成

実装上こちらで用意するのは図でいう右下の処理だけになります。

弊社では、AWS Lambda上にServerless Framework で構築しています。

最初はGoogle App Scriptという選択肢を考えましたが、Bolt SDKを使いたかったということと、上述の通り表示にこだわっていた関係でNotion APIの処理が少し煩雑になりそうだったため、nodeで実装することにしました。

設定関連

  • Notion Integration
    • プレビューしたい記事にConnectionを設定しておく必要があります。
    • 記事をまとめたDatabaseがあれば、そこに一括で設定すると良いと思います。
  • Slackアプリ
    • Event Subscriptions > Subscribe to bot eventslink_shared を設定します。
    • Event Subscriptions > App unfurl domainsnotion.so を指定します。
    • OAuth & Permissions > Scopes > Bot Token Scopes で以下を設定します。
      • channels:read, groups:read, mpim:read
        • publicチャンネル、privateチャンネル、DMのいずれでも動作するよう3つとも許可します。
      • links:read, links:write
        • unfurlのために必要です。

まとめ

弊社では、Notion公式が提供するアプリとはまた違った形で、Slack上でのプレビュー機能を運用しています。
ソースコード自体はどこのドメインでも使えるように汎用化してあるのですが、TypeScript初心者の初学習用に作ったものだったので公開できるレベルない状態です・・・要望等が多ければ、多少リファクタして公開することも検討したいと思います。

Podcast

準備中・・・実装上のポイントなどを含めた解説を配信する予定です。

TimeTree Tech Blog

Discussion