Airtable でデータを記録して前のコメントを返事するシンプルな LINE BOT をつくったメモです。
LINE BOT の基礎
1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest – Qiita
こちらを参考に LINE BOT の基礎 ができている前提で進めます。
2022 年 7 月の情報で進めます。
Airtable の API Key を控えておく
Airtable のアカウントページ で API Key をテキストエディタにメモしておきます。これはこの後の Node.js のソースコードで使います。
今回用の Airtable の Base を作成
Airtable のダッシュボードで今回用の Base を作成します。
今回は名前を LINE BOT Sample としました。
今回用の Airtable の Table を作成
Table を一つ作成します。名前は Record とします。
フィールドの名前とフィールドタイプは以下のようにします。
- UserID
- フィールドタイプ
- Single line text
- フィールドタイプ
- Message
- フィールドタイプ
- Long text
- フィールドタイプ
- CreatedAt
- フィールドタイプ
- Created time
- フィールドタイプ
これで準備完了です。
今回用の Airtable の Base の ID を取得
今回用の Airtable の Base の ID を取得します。
Airtable の API ページ から今回の Base をクリックします。
今回の Base の API ページに移動すると、こちらで app ではじまる Base ID が取得できるのでテキストエディタにメモしておきます。
プロジェクトフォルダで Node.js のパッケージ準備
Visual Studio Code で今回作業するプロジェクトフォルダを開きます。
npm init -y
プロジェクトフォルダ直下で npm の初期化をします。
npm i @line/bot-sdk express
LINE BOT 関連のパッケージのインストールをします。
npm i airtable
Airtable のパッケージのインストールをします。
Node.js のプログラム準備
プロジェクトフォルダ直下に app.js のファイルを作成して以下のプログラムをコピーペーストします。
'use strict'; // Airtable ///////////////////////////////// const Airtable = require("airtable"); // 今回使う Base の Base ID const BASE_ID = 'BASE_ID'; // Airtable の API Key const AIRTABLE_API_KEY = 'AIRTABLE_API_KEY'; // Airtable 今回使うの Base を取得 const base = new Airtable({apiKey: AIRTABLE_API_KEY}).base(BASE_ID); // 今回使う Table を取得(テーブル名:Record) const table = base('Record'); // LINE ///////////////////////////////////// const express = require('express'); const line = require('@line/bot-sdk'); const PORT = process.env.PORT || 3000; const config = { channelSecret: 'channelSecret', channelAccessToken: 'channelAccessToken' }; const app = express(); app.post('/webhook', line.middleware(config), (req, res) => { console.log(req.body.events); Promise .all(req.body.events.map(handleEvent)) .then((result) => res.json(result)); }); const client = new line.Client(config); async function handleEvent(event) { if (event.type !== 'message' || event.message.type !== 'text') { return Promise.resolve(null); } // Airtable から一つ前の投稿を取得 let records; try { records = await base('Record').select({ view: 'Grid view', maxRecords: 1, sort:[ { field: "CreatedAt", direction: "desc" } ], fields: ["UserID", "Message","CreatedAt"] }).all(); } catch (e){ console.log(e); } let message = ''; if(records.length == 0){ // まだ一つ前の投稿がないとき(はじめての投稿) message = `今回のメッセージは\n「${event.message.text}」\nです。はじめての投稿です。`; } else { const previousMessage = records[0].get('Message'); message = `今回のメッセージは\n「${event.message.text}」\nです。\n一つ前の投稿は\n「${previousMessage}」\nです。`; } // Airtable に今回のメッセージを記録 await table.create([{ "fields": { "UserID": event.source.userId, "Message": event.message.text } }]); return client.replyMessage(event.replyToken, { type: 'text', text: message }); } app.listen(PORT); console.log(`Server running at ${PORT}`);
コピーアンドペーストできたら、設定をします。
// 今回使う Base の Base ID const BASE_ID = 'BASE_ID'; // Airtable の API Key const AIRTABLE_API_KEY = 'AIRTABLE_API_KEY';
今回使う Base の Base ID と Airtable の API Key を反映します。
const config = { channelSecret: 'channelSecret', channelAccessToken: 'channelAccessToken' };
今回使う LINE の channelSecret と channelAccessToken を反映します。
設定できたら LINE BOT を動かしてみます。
動かしてみる
Airtable の Base が空の状態で「やほー」とメッセージしたあと、「こんにちは!」とメッセージします。
Base にはこのように情報が貯まります。
そして、このようにやりとりされます。「やほー」を送ったときは、はじめての投稿なので今回のメッセージのみで前のメッセージはなし、それ以降は、今回のメッセージと一つ前のメッセージを返答します。
Airtable から一つ前の投稿を取得する処理
一つ前の投稿を取得する、大事な部分はここです。
// Airtable に今回のメッセージを記録 await table.create([{ "fields": { "UserID": event.source.userId, "Message": event.message.text } }]);
まず、Airtable にデータが登録されるときに CreatedAt で自動的に作成日時が登録されます。UserID と Message しか登録していないんのですが、CreatedAt で自動的に作成日時が登録されます。
そして、データの取得です。
// Airtable から一つ前の投稿を取得 let records; try { records = await base('Record').select({ view: 'Grid view', maxRecords: 1, sort:[ { field: "CreatedAt", direction: "desc" } ], fields: ["UserID", "Message","CreatedAt"] }).all(); } catch (e){ console.log(e); }
こちらのコードで sort パラメータで CreatedAt を狙ってソートをかけます。その上で maxRecords 1 によって 1 件だけ取得することで最新のデータ取得を実現しています。