Help us understand the problem. What is going on with this article?

Google Homeを使用してTrelloにタスクを登録する

More than 1 year has passed since last update.

この記事で説明すること

  • Google Homeでアプリを作る方法
  • Node.js(Express.js)でTrelloのAPIをたたいてカードを追加、削除する方法

やりたいこと

冷蔵庫の中身と賞味期限が把握できないため、Trelloでリスト化したい。
冷蔵庫にしまうときにGoogle Homeに話しかけてリスト化したら良さそう。
食べ終わったらリストから消して、買い物リストに入れたい。
WS000007.JPG
WS000008.JPG
システム的には以下の手順になる。
1. Google Homeに話しかけてタスク登録したい内容を教える
2. 1のデータをサーバーに送信する
3. サーバーでTrelloのAPIを叩く
4. Trelloに登録される

Google Homeの設定

ここではタスク追加のために必要なデータを集めるための会話を作れる。

Actions on Googleにプロジェクトを作成する

Actions on Googleにアクセスする。
Add/import projectをクリックする。
以下の画像のようにプロジェクト名と言語を設定して「CREATE PROJECT」をクリック。
Add/import project

左側のメニューから「BUILD」>「Actions」を選択。
「ADD YOUR FIRST ACTION」をクリック。
「Custom intent」を選択して「BUILD」をクリック。
Dialogflowが起動する。
起動した画面でLanguageを日本語にして「SAVE」をクリック。
日本語に設定しそびれたら、左側のメニューの歯車アイコンをクリックして開いた画面で、上部のメニューの「Languages」から設定できる。

Entitiesの設定

左メニューからEntitiesを選択。
ここで列挙型みたいなものが作れる。
以下を作成。

  • 買い物リストに入れる/入れないのフラグ
  • 冷蔵庫に入れる/取り出すのフラグ entity.png

「CREATE ENTITY」をクリックして登録画面を開く。
以下のように設定する。
buy.png
左側がパラメーターとして渡される値、右側が音声入力で認識する値。

冷蔵庫出し入れフラグは以下。
inout.png

Intentsの設定

左メニューからIntentsを選択。
ここでは会話パターンが作れる。
デフォルトに以下の2つが用意されている。

  • Default Fallback Intent(聞き取れなかった場合の返事)
  • Default Welcome Intent(起動フレーズと返事)

今回は以下2つの会話パターンを作成する。

  • 冷蔵庫に入れる
  • 冷蔵庫から取り出す

冷蔵庫に入れるパターンは以下のように設定する。
addtask.png

Training phrasesにユーザーが言う言葉のパターンを書く。
賞味期限までの食品を登録
「賞味期限」の部分をドラッグするとEntityの一覧が出てくるので@sys.dateを選択する。
同じく「食品」は@sys.any、「登録」は@in-outにする。
ここで選択した部分がwebサーバーに送信されるパラメーターになる。

そのパラメーターを設定するのがAction and parameters。
param.png

  • REQUIRED:ONにすると必須入力になる。分かるまで聞いてくれる。
  • PARAMATER NAME:サーバーに送信するときのパラメーターのキーになる。
  • ENTITY:型。
  • VALUE:自動で$パラメーター名になるので変更しない。
  • IS LIST:ONにするとパラメーターとしてサーバーに送信してくれる。
  • PROMPTS:必須にするとリンクが出てくるので、聞き返すときのメッセージを入力できる。
  • Default value:カーソルを当てると右側に出てくる設定のアイコンをクリックすると入力できる。
    この会話パターンではin-outはinだけ入るので、デフォルトに設定する。

FulfillmentをONにする。
2つあるが、とりあえず上の方だけで大丈夫。

Fulfillmentの設定

左メニューからFulfillmentを選択。
WebhookをEnabledにする。
URLにwebサーバーのアドレスを入力する。
そうすると先ほどの会話パターンからURLに会話で得たデータを送信してくれる。
※Inline Editorだとサーバーを立てなくていいが、外部のAPIを叩けない。

Trelloの情報を取得する

APIキーとトークンを取得する

Trelloにログインして以下にアクセスする。
https://trello.com/app-key
trello.png
APIキーは黒塗りにしているところに表示される。
文字リンクの「トークン」をクリックするとトークンが発行される。

リストのIDを取得する

ブラウザ確認できないので、直接APIを叩いて調べる。
ユーザー名はTrelloのプロフィールから見れる。

以下のコマンドでボードIDを取得する。

$ curl "https://trello.com/1/members/ユーザー名/boards?key=キー&token=トークン&fields=name"

[{"name":"冷蔵庫","id":"XXXXXXXXXXXXXXXX"}]

ボードIDが分かったので、次はリストIDを取得する

$ curl "https://trello.com/1/boards/ボードID/lists?key=キー&token=トークン&fields=name"

[{"id":"XXXXXXXXXXXXXXXX","name":"冷蔵庫"},{"id":"XXXXXXXXXXXXXXXX","name":"買い物リスト"}

タスク追加処理の実装

コードを全部載せると長くなるので、こちらに上げてあるので適宜見てほしい。
以下、各処理のポイントだけ載せておく。
node.jsとexpressを使用して実装している。
※Node.jsの初心者なのでおかしなところがあればマサカリ投げていただけると助かります!

Google Homeのパラメータを取り出す処理

index.js
// 食品を取得する
var reqParam = req.body.queryResult.parameters;
var content= reqParam['content'].toString();

Google Homeにしゃべらせたいメッセージを返却する

index.js
// Googleアシスタントにメッセージを返却する
res.json({
  fulfillmentText: '登録しました。'
});

Trelloのリストからタスクを取得

index.js
/**
 * リストからカードを探す
 * @param {string} list_id リストID
 * @param {string} card_name カード名
 * @return {string} カードID
 */
function get_card_id (list_id, card_name) {
  return new Promise((resolve, reject) => {
    console.log('=====[get_card_id]====');

    //取得するURL
    var options = {
      uri: 'https://api.trello.com/1/lists/' + list_id + '/cards?key=' + key + '&token=' + token + '&fields=id,name',
    };

    // GETする
    request.get(options, function (error, response, body) {
      if (error) {
        console.log('=====[ERROR]====');
        console.log(error);
      } else {
        console.log('=====[BODY]====');
        var info = JSON.parse(body);
        for (var i in info) {
          //取得したカードリストから探す
          if (info[i].name.toString() === card_name) {
            var card_id = info[i].id.toString();
            console.log(card_id);
            resolve(card_id);
            return;
          }
        }
        // 見つからなかった場合は空文字を返す
        resolve('');
      }
    });
  });
}

Trelloのリストにタスクを追加

index.js
/**
 * リストにカードを追加する
 * @param {string} list_id リストID
 * @param {string} card_name カード名
 * @param {string} due 期限(yyyy-mm-dd)
 * @return {bool} resolve レスポンスメッセージ
 */
function add_card (list_id, card_name, due) {
  return new Promise((resolve, reject) => {
    console.log('=====[add_card]====');

    var listName = list_id === list_fridge ? '冷蔵庫' : '買い物リスト';
    //リストに追加するURLとデータ
    var options = {
      uri: 'https://api.trello.com/1/cards',
      json: {
        'key' : key,
        'token' : token,
        'idList': list_id,
        'name': card_name,
        'due': due,
        'keepFromSource': 'all',
      }
    };

    // POSTする
    request.post(options, function (error, response, body) {
      // 返答内容
      if (error) {
        console.log('=====[ERROR]====');
        console.log(error);
        resolve(listName + 'に登録できませんでした。');
      } else {
        console.log('=====[BODY]====');
        console.log(body);
        resolve(listName + '' + card_name + 'を登録しました。期限は' + due + 'です。');
      }
    });
  });
}

Trelloのタスクを削除

index.js
/**
 * カードを削除する
 * @param {string} card_id カードID
 * @return {bool} resolve レスポンスメッセージ
 */
function delete_card (card_id) {
  return new Promise((resolve, reject) => {
    console.log('=====[delete_card]====');
    if (!card_id) {
      resolve('見つかりませんでした。');
      return;
    }

    //削除URL
    var options = {
      uri: 'https://api.trello.com/1/cards/' + card_id +'?key=' + key + '&token=' + token,
    };

    // DELETEする
    request.delete(options, function (error, response, body) {
      // 返答内容
      if (error) {
        console.log('=====[ERROR]====');
        console.log(error);
        resolve('削除できませんでした。');
      } else {
        console.log('=====[BODY]====');
        resolve('削除しました。');
      }
    });
  });
}

動作確認

動作確認はActions on GoogleのTESTのところからできる。
Google Homeに「テスト用アプリにつないで」と言ったり、Intentsで設定した起動フレーズからでも使える。

参考文献

Google Home

GoogleHomeからTodoistにタスクを追加する

Trello

Trello APIを利用してスクリプトからタスクを管理する
Trello API を叩いてカードを作成する方法(curl利用)

Javascript関連

ゼロからはじめるExpress + Node.jsを使ったアプリ開発
Promiseと仲良くなって気持ち良く非同期処理を書こう
とにかくJavascriptで同期処理

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away