Cloud FunctionとCloud Schedulerで読書ログをリマインドする

背景

色々試して行き着いた読書方法

まとめたメモは、Notionのリマインド機能を使って、1か月後に「自分にメモを読み返すように通知」を飛ばしています

こちらのブログに刺激を受け、

自分も読書ログを書いているが、完全に書きっぱなしになっているのをなんとかしたい!からはじまった。

各種リマインドツールを使うのでもよかったが、つくりたくなってしまったので、しょうがない。

読書ログ

読書ログはパーソナルなKibelaに書き溜めてある。

>引用

一言コメント

の形でまとめてある。

読書ログ例

リマインド通知の全体像

Cloud Schedulerから定期的にHTTPリクエストをCloud Functionに送り、

Cloud Functionはリクエストをトリガーにスプレッドシートにまとめてある読書ログをSlackに通知する。

Kibelaからスプレッドシート

KibelaのWeb APIについて

Kibela APIを直接利用してもよいが、ちょっと自分のKibelaが整理できておらず、ゴミが混じってしまうので、

  1. APIでリストを取得
  2. スプレッドシートで整理整頓

というステップを挟むことにした。

query {
  search(query: "読書ログ", first: 100, sortBy: RECENT) {
    edges {
      node {
        title,
        url,
      }
    }
  }
}

上記のクエリをKibela APIで実行、結果を整形して、下記のようなスプレッドシートをつくる。

スプレッドシート

スプレッドシートの内容を取得

GitHub - googleapis/google-api-php-client: A PHP client library for accessing Google APIs

GoogleAPI Clientを利用して、取得する。

// スプレッドシートからデータ取得
$client = new Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Sheets::SPREADSHEETS);
$service = new Sheets($client);
$ssId = 'シートID';
$range = 'シート名!範囲';
$result = $service->spreadsheets_values->get($ssId, $range);
$books = $result->getValues();

Slackへ通知

// Slackに通知する
$logger = new Logger('slack');
$logger->pushHandler(
    new SlackWebhookHandler(
        $_ENV['SLACK_WEBHOOK_URL'],
        null,
        null,
        true,
        '',
        true,
        true,
        Level::Info
    )
);
$logger->info("<@gamu1012>\n 読書ログを読み返してみよう!\n <{$book[1]} | {$book[0]}>\n");

Slack通知はmonologのHandlerを利用してしまうのが楽なので、上記のように実装した。

Slackへ通知

charlie1012.hatenablog.jp

Cloud Function

GitHub - GoogleCloudPlatform/functions-framework-php: FaaS (Function as a service) framework for writing portable PHP functions

依存関係の指定  |  Google App Engine スタンダード環境のドキュメント  |  Google Cloud

上記の公式を参考に、スプレッドシートからの取得とSlack通知を組み合わせる。

<?php

require_once __DIR__ . '/vendor/autoload.php';

use Google\Client;
use Google\Service\Sheets;
use GuzzleHttp\Psr7\Response;
use Monolog\Handler\SlackWebhookHandler;
use Monolog\Level;
use Monolog\Logger;
use Psr\Http\Message\ServerRequestInterface;

function execute(ServerRequestInterface $request)
{
    // HeaderのAPIキーのチェック
    略

    // スプレッドシートからデータ取得する
    略
    // 通知する本を抽選する
    略

    // Slackに通知する
    略

    // レスポンス
    $now = new DateTimeImmutable();
    $response = ['book' => $book[0], 'url' => $book[1], 'send_at' => "{$now->format('Y-m-d H:i:s')}"];

    return json_encode($response) . PHP_EOL;
}

下記のようなコマンドでデプロイする。

gcloud functions deploy my-function \
--gen2 \
--region=asia-northeast1 \
--runtime=php81 \
--source=. \
--entry-point=execute \
--trigger-http \
--allow-unauthenticated \
--env-vars-file .env.yaml

Cloud Schedulerで定期実行

Cloud Schedulerはcronのように設定できるので、上記のように設定する。

最初は週1で設定していたが、物足りなかったため、今は月水金と土日の朝10時にSlackに通知している。

HTTPリクエストの実行も簡単で、下記のように設定する。

サービス名

完全にプライベートなツールだが「Blueberry」と読んでいる。*1

*1:個人サービスはAからアルファベット順で始まる食べ物としている。AはAsparagus