Notion へ瞬時にメモできるLINEbotをつくってみた

# はじめに
スマホから瞬時にメモをしてNotionでも確認できるbotを作りました。参考にしたソースコード、サイトを部分的に紹介します。

# 作ったもの
できることはシンプルで2つだけです。
### 1. LINEのトークルームで入力した内容をNotionテーブルにも記録する。
<img src="https://storage.googleapis.com/zenn-user-upload/a954ab5fbf38-20221011.gif" width=80%>


### 2. webページもコメント付きで記録できる。

<img src="https://storage.googleapis.com/zenn-user-upload/0f09554d5bbe-20221011.png" width=80%>
<img src="https://storage.googleapis.com/zenn-user-upload/3b8824d87b82-20221011.png" width=80%>


<a href="https://lin.ee/wAZitF9" alt="友だち" width="100" height="60" border="0">
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921076/4a703250-2cce-c21f-e83a-0d3e047295f0.png" width=20%>
</a>
<a href="https://lin.ee/wAZitF9"><img src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" width="150" height="120" border="0"></a>

# 作った背景
- スマホからNotionへメモする速度を上げてストレスを減らしたい。
- メモした履歴も見返したい。
- 新たにアプリはインストールしたくない。


# システム構成

Ruby
MySQL
Notion API
LINE API
Lambda

# 仕組み

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921076/e557519b-76e6-eb8e-1cc4-5a0aa70ed760.png" width=110%>


## LINE API
Messaging APIのwebhookイベントを取得しています。

```rb:line_bot_function.rb
require 'line/bot'
require_relative '../modules/reply.rb'

def client
  @client ||= Line::Bot::Client.new { |config|
    config.channel_secret = ENV['LINE_CHANNEL_SECRET']
    config.channel_token = ENV['LINE_CHANNEL_TOKEN']
  }
end

def webhook(event:, context:)
  unless client.validate_signature(event['body'], event['headers']['x-line-signature'])
    error 400 do 'Bad Request' end
  end

  client.parse_events_from(body).each do |event|
    case event
    when Line::Bot::Event::Message
      # トークルームでメモが投稿された時、ページの追加（Notion API）
      result = notion.create_page(parent: { database_id: user.database_id}, properties: page_properties)
      client.reply_message(event['replyToken'], post_page(result, user))
    when Line::Bot::Event::Postback
      # 削除ボタンを押された時
      # クイックリプライで選択された時
    when Line::Bot::Event::Follow
      # フォローされた時
    end
  end

  # 省略

  # Don't forget to return a successful response
  "OK"
end

```

メッセージの応答では以下のAPIを利用しました。
- Flex Message（挨拶メッセージ、応答メッセージで使用）
- アイコン、表示名の変更
- クイックリプライ

```rb

  def post_page(result, user)
    {
      type: "flex",
      altText: "ページを追加しました",
      contents:{
        "type": "bubble",
        "body": {
          "type": "box",
          "layout": "vertical",
          "contents": [
            {
              "type": "text",
              "text": "#{result.properties.Name.title.first["text"]["content"]}",
              "weight": "bold",
              "size": "md"
            }
          ]
        },
        "footer": {
          "type": "box",
          "layout": "horizontal",
          "spacing": "sm",
          "contents": [
            {
              "type": "button",
              "height": "sm",
              "action": {
                "type": "postback",
                "label": "削除",
                "data": { :page_id => result.id, :kind => 'page_destroy' }.to_s
              }
            }
          ],
          "flex": 0
        }
      },
      "sender": {
        "name": '名称未設定',
        "iconUrl": "https://line.me/conyprof"
      },
      "quickReply": quick_reply(user)
    }
  end
```

```rb
  def quick_reply(user)
    reply_json = { "items": [] }
    user.integrations.each do |integration|
      reply_json[:items].push({
                                "action": {
                                  "type": "postback",
                                  "label": "#{integration.title.presence || "未設定"}",
                                  "data": { :integration_id => integration.id, :kind => integration.kind }.to_s
                                }
                              })
    end
    reply_json[:items].push({
                              "action": {
                                "type": "uri",
                                "label": "設定",
                                "uri": "#{ENV['LIFF_URL']}"
                              }
                            })
    reply_json
  end
```


## Notion API
sdkを使っています。

https://github.com/orbit-love/notion-ruby-client

https://www.postman.com/notionhq/workspace/notion-s-api-workspace/overview


```rb
# ユーザごとにクライアントを設定
notion = Notion::Client.new(token: user.notion_secret_token)
# ページの追加
notion.create_page(parent: { database_id: user.database_id}, properties: page_properties)
# ページの詳細（Block）も一緒に作成
notion.create_page(parent: { database_id: user.database_id}, properties: page_properties, children: page_children)
# ページの削除
notion.update_page(page_id: data[:page_id], archived: true)

page_properties = {
"Name": {
    "id": "title",
    "type": "title",
    "title": [
      {
        "type": "text",
        "text": {
            "content": "#{title_text}"
        },
        "annotations": {
            "bold": false,
            "italic": false,
            "strikethrough": false,
            "underline": false,
            "code": false,
            "color": "default"
        },
        "plain_text": "#{title_text}"
      }
    ]
}
page_children = [
 {
    "object": "block",
    "type": "paragraph",
    "paragraph": {
       "rich_text": [
          {
            "type": "text",
            "text": {
              "content": "#{child_text}"
            }
          }
       ]
    }
  }
]

```



# サービスの使用例を紹介
簡単なメモに加えて、「テキスト + 数値」プロパティを有効にすれば、家計簿などもできると思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921076/376594e0-a0a6-7bb8-9ade-191f0cdc0356.png" width=39%> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2921076/7bd1477e-00f1-c432-0128-b8a94a2323e7.png" width=60%>






# さいごに
特に複雑なことはなくスマホからNotionへのメモがすぐできるようシンプルにしました。
LINE APIを調べる中でできることが多いと感じましたので、リッチメニュー、ミニアプリなども試してみたいと思いました。
開発に至った経緯などは[こちら](https://note.com/hal_shu1626/n/n72e47588dcda)でまとめています。


https://lin.ee/wAZitF9