概要
読書での学びを簡単に記録でき、記録内容を自動でslackに送信するシステムを作成しました!!!
お気に入りポイント
- 日々の読書体験からの学びを手間なく記録できます。
- 単に読むだけでなく、本のハイライト箇所をslackで復習できます。
- 自分がどれだけ本に触れているかを確認できます。
読書は好きだけど、記録するのが面倒な方は必見です!!!
内容
本システムは2つのパートに分かれています。
- 読書の記録
- 記録内容をslackに自動送信
読書の記録
読書の記録ではBookNotionを用います。
BookNotionとは、KindleのハイライトをNotionに自動保存するアプリケーションであり、読書の記録を簡単に保存できる点が非常に優れています。
BookNotionを用いるための詳細な手順は以下です。(全てリンクが付与されています。)
ここでは、Notionのデータベースを作成し、Notion APIでデータベースにアクセスできるように設定しています。BookNotionはNotionAPIを用いて、Notionデータベースにアクセスします。
手順2のインテグレーションの取得と設定で取得した「Secretsからインテグレーショントークン」(後のAPIトークン)と手順4のページIDの取得と設定で取得した「PAGE ID」(後にデータベースID。)は、以降で用いるのでメモしておいてください!!
BookNotionの使い方は簡単で、Kindleでメモしたい文章を長押しで選択し(ハイライトし)、シェア->テキストの引用でBookNotionを選択し、保存します。今回は触れませんが、ハイライトにタグをつけたり、コメントをつけたりもできます。
BookNotionでは保存の際に、自動で著者名と本のタイトルを保存してくれます。本当に便利です!
記録内容をslackに自動送信
BookNotionで記録した内容をスラックに自動送信するためには、以下の3つの流れが必要です。
- NotionAPIを用いてNotionデータベースから情報を取得する
- SlackAPIを用いてslackにデータを送信する
- 1と2を記述したプログラムを定期実行する
1と2を記述したプログラムの完成版をまずご覧になりたい方はこちらへ
NotionAPI
まずプログラムでNotionAPIと使うためにAPIトークン、Notionのデータベースに接続するためにデータベースのIDを環境変数に設定します。APIトークンはインテグレーショントークンであり、データベースのIDは控えておいたPAGE IDです。
環境変数は以下のようにターミナルで設定します。
% export NOTION_API_TOKEN="{インテグレーショントークン}"
% export NOTION_DATABASE_ID="{PAGE ID}"
Notionのデータベースにアクセスするためには以下のようにプログラムを記述します。
import os
import requests
API_TOKEN = os.environ["NOTION_API_TOKEN"]
DATABASE_ID = os.environ["NOTION_DATABASE_ID"]
headers = {
"Authorization": "Bearer " + API_TOKEN,
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
}
url = f"https://api.notion.com/v1/databases/{DATABASE_ID}/query"
response = requests.post(url, headers=headers)
headers
のAuthorization
にはNotionのAPIトークンが記述されており、requests
の際のURLにデータベースIDが記述されています。
上記で得られたresponse
はそのままでは使えないので、以下のように情報を取り出せる形にします。
data = response.json()
results = data["results"] #データベースの行1つ1つが入っている
こうして取り出したresult
にはデータベースの行1つ1つが入っています。
BookNotionで自動生成したデータベースのカラム(本のタイトル、ハイライト箇所、登録日時)にアクセスするには以下のように記述します。
page = results[0]
props = page['properties']
title = props['📙 Book Title']['select']['name']
memo = props['📝 Highlight']['title'][0]['text']['content'] # ハイライトの箇所
raw_created_time = props['Created At']['created_time']
for文を用いることで全てのデータにアクセスできます。
SlackAPI
SlackAPIの使い方は以下の記事で解説しております。
SlackAPIを用いるための設定と使い方について記述されています。
SlackAPIを用いてslackを送信するプログラムは以下です。
import os
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
def send_slack_message(text = "Hello from your app! :tada:", channel = "random"):
slack_token = os.environ["SLACK_API_TOKEN"]
client = WebClient(token=slack_token)
try:
response = client.chat_postMessage(
channel=channel,
text=text
)
except SlackApiError as e:
# You will get a SlackApiError if "ok" is False
assert e.response["error"]
NotionAPIとSlackAPIを用いたslackの送信
NotionAPIとSlackAPIの設定ができたので、次にslackに送信するメッセージを決めます。
(1)週、月、年あたりにどのくらいの本に触れたか、(2)毎週の気づき(本のハイライト)の2点を振り返りたいため、以下のようなメッセージが送られて欲しいです。
あなたの読書記録は以下です。
今週: 2冊
今月: 10冊
今年: 30冊
あなたの今週の気づきは以下です。
1: 気づき1
2: 気づき2
NotionAPIを用いてNotionデータベースから情報を取得し、SlackAPIを用いて上記のようなslackを送信するプログラムは以下です。
完成版(コピペ用)
import os
from datetime import datetime
import requests
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
def send_slack_message(text = "Hello from your app! :tada:", channel = "random"):
slack_token = os.environ["SLACK_API_TOKEN"]
client = WebClient(token=slack_token)
try:
response = client.chat_postMessage(
channel=channel,
text=text
)
except SlackApiError as e:
# You will get a SlackApiError if "ok" is False
assert e.response["error"]
def get_pages(DATABASE_ID, headers):
url = f"https://api.notion.com/v1/databases/{DATABASE_ID}/query"
response = requests.post(url, json=payload, headers=headers)
data = response.json()
results = data["results"]
return results
API_TOKEN = os.environ["NOTION_API_TOKEN"]
DATABASE_ID = os.environ["NOTION_DATABASE_ID"]
headers = {
"Authorization": "Bearer " + API_TOKEN,
"Content-Type": "application/json",
"Notion-Version": "2022-06-28",
}
pages = get_pages(DATABASE_ID=DATABASE_ID, headers=headers )
today = datetime.now()
weekly_count = 0
weekly_memos = ""
weekly_titles, monthly_titles, yearly_titles = [],[],[]
for i,page in enumerate(pages):
props = page['properties']
title = props['📙 Book Title']['select']['name']
memo = props['📝 Highlight']['title'][0]['text']['content']
raw_created_time = props['Created At']['created_time']
datetime_object = datetime.strptime(raw_created_time , "%Y-%m-%dT%H:%M:%S.%fZ")
day_diff = (today - datetime_object).days
if day_diff <= 7:
weekly_count += 1
weekly_memos += f"{weekly_count}: {memo}\n"
weekly_titles.append(title)
if day_diff <= 31:
monthly_titles.append(title)
if day_diff <= 365:
yearly_titles.append(title)
weekly_memos = weekly_memos[:-1] #文末の\nを削除
message = f"""あなたの読書記録は以下です。
今週: {len(set(weekly_titles))}冊
今月: {len(set(monthly_titles))}冊
今年: {len(set(yearly_titles))}冊
あなたの今週の気づきは以下です。
{weekly_memos}
"""
print(message) #ターミナルでも確認するため
send_slack_message(text=message)
print("Success!!")
このプログラムを実行すると、slackに以下のようなメッセージが送られてきます。
バッチリです!!
自動実行
最後にこれらのプログラムを自動実行させます。
自動実行させるには、(1)ローカルPCで自動実行(2)サーバーで自動実行の2通りが考えられます。
今回は(1)のローカルPCで自動実行させます。
私はMacユーザーなのでAutomatorを用いて自動実行させます。(Windowsの方はタスクスケジューラで代替できます。)
一点注意点があって、今回は環境変数を事前に設定しているため、pythonファイルの定期実行はうまくいきません。
Automatorやcronなどで自動実行する際は、ローカルPCの環境とは異なる環境でプログラムが実行されるので、プログラムを実行する前に環境変数を設定するシェルスクリプトを書き、そのシェルスクリプトを自動実行させます。
シェルスクリプトの例はこちらです。
export NOTION_API_TOKEN="{インテグレーショントークン}"
export NOTION_DATABASE_ID="{PAGE ID}"
export SLACK_API_TOKEN="{設定したslackのAPIトークン}"
source {仮想環境の名前(SlackAPIを用いるために設定)}
cd {プログラムの絶対パス}
python {ファイル名}
まとめ
このように、NotionとSlackを組み合わせたこのシステムを用いれば、読書の学びを簡単に振り返ることが可能になります!
最後に、このシステムがあなたの読書体験をより豊かなものにできれば幸いです!!