Posted at

Action on Google 用リマインダーアプリケーション


概要

Action on Google で日時・件名・所要時間を話しかけるとgoogleカレンダーに登録してくれるアプリケーションを作成しました。


実行の様子

アプリを呼び出すと、何を言って欲しいか誘導してくれます。

会話は友達とするようにフランクな感じを目指しました。

誘導通りに日付・時間・予定の名前・かかる時間を言うとgoogleカレンダーにその通りに記入を行ってくれます。

aaa.JPG

iii.JPG

a.JPG

もしユーザーが予想外の発言をした場合は、言い直すように誘導します。例えば日付を言って欲しいのに全く別の発言がなされた場合は、画像のように分からなかった事をユーザーに伝えて言い直してもらいます。

uuu.JPG


DialogFlowのソースコード

googleカレンダーへの認証と登録、その他ユーザーへの返信などの処理は以下のコードで行っています。

ユーザーからカレンダー予約名、開始時刻、経過時間を取得しているので、開始時間から経過時間を足したものを終了時間としてgoogleカレンダーに登録しています。

'use strict';

require('date-utils');
const functions = require('firebase-functions');
const { dialogflow } = require('actions-on-google');

const app = dialogflow({debug: true});

const HEARING_INTENT = 'Hearing Intent';
const ARGUMENT_DATE = 'date';
//const ARGUMENT_STARTTIME = 'start-time';
const ARGUMENT_USETIME = 'use-time';
const ARGUMENT_STARTTIME= 'start-time';
const ARGUMENT_STARTTIME_PARM= {
AMOUNT: 'amount',
UNIT: 'unit',
}
const ARGUMENT_USETIME_PARM = { //{"usage-time":{"amount":2,"unit":"時"}}
AMOUNT: 'amount',
UNIT: 'unit',
};
const ARGUMENT_EVENTNAME='event-title';
const calendar = 'tktkmy@gmail.com';
let eventTitle; //カレンダー予約タイトル
let eventStartTime; //カレンダー予約開始時間
let eventEndTime; //カレンダー予約終了時間

const {google} = require('googleapis');
const SCOPES = ['https://www.googleapis.com/auth/calendar'];
//credentials.jsonの文字列データ
const CRIENT_SECRET = ['ここにはcredentials.jsonのデータを記入しています'];
//secret.jsonの文字列データ
const CREDENTIAL ='ここにはsecret.jsonの文字列データを記入しています';

//認証
function authorize(credentials, callback) {
const {client_secret, client_id, redirect_uris} = credentials.installed;
let token = {};
const oAuth2Client = new google.auth.OAuth2(
client_id, client_secret, redirect_uris[0]);

try {
token = CREDENTIAL;
} catch (err) {
console.log('oAuth error occurred');
return;
}
oAuth2Client.setCredentials(JSON.parse(token));
callback(oAuth2Client);
}

//カレンダーイベント登録

function CreateEvents(auth) {
const calendar = google.calendar({version: 'v3', auth});
var event = {
'summary': eventTitle,
'location': '',
'description': '音声アシスタントからの予約投稿です',
'start': {
'dateTime': eventStartTime,
'timeZone': 'Asia/Tokyo',
},
'end': {
'dateTime': eventEndTime,
'timeZone': 'Asia/Tokyo',
},
'attendees': [
{'email': 'tktkmy@gmail.com'},
],
'reminders': {
'useDefault': false,
'overrides': [
{'method': 'popup', 'minutes': 10},
],
},
};
console.log(event);
calendar.events.insert({
auth: auth,
calendarId: 'primary',
resource: event,
}, function(err, event) {
if (err) {
console.log('There was an error contacting the Calendar service: ' + err);
return;
}
console.log('Event created: %s', event.htmlLink);
});
}

app.intent('Hearing Intent', (conv, params) => {
console.log('Hearing Intent');

//予約日
let dDate = new Date(params[ARGUMENT_DATE]);
let reserveDate = dDate.toFormat('YYYY年MM月DD日');
let startTimeAmount = params[ARGUMENT_STARTTIME][ARGUMENT_STARTTIME_PARM.AMOUNT];
let startTime = new Date(dDate.setHours(startTimeAmount));
eventStartTime = new Date(dDate.setHours(startTime.getHours()));
eventStartTime.setTime(eventStartTime.getTime() - 1000*60*60*9);
dDate.setHours(eventStartTime.getHours()+9);
let reserveBeginTime = dDate.toFormat('HH24時MI分');

//利用時間
let useTimeAmount = params[ARGUMENT_USETIME][ARGUMENT_USETIME_PARM.AMOUNT];
let useTimeUnit = params[ARGUMENT_USETIME][ARGUMENT_USETIME_PARM.UNIT];
let useTime = useTimeAmount + useTimeUnit;

//予約終了時間
let endTime = dDate;

switch (useTimeUnit) {//@sys.durationのunitに応じて処理をわける。日は無視して時と分のみだけの対応にしておく
case '':
endTime.setHours(dDate.getHours() + Number(useTimeAmount));
break;
case '':
endTime.setMinutes(dDate.getMinutes() + Number(useTimeAmount));
break;
default:
endTime.setHours(dDate.getHours() + Number(useTimeAmount));
break;
}

let reserveEndTime = endTime.toFormat('HH24時MI分');
eventEndTime = new Date(endTime.setHours(endTime.getHours())); //カレンダー登録用
eventEndTime.setTime(eventEndTime.getTime() - 1000*60*60*9);
//予約タイトル
eventTitle = params[ARGUMENT_EVENTNAME];
//認証とカレンダーイベント登録
try {
const content = CRIENT_SECRET;
authorize(JSON.parse(CRIENT_SECRET), CreateEvents);
} catch (err) {
return console.log('Authorize error occurred');
}
conv.close(`${reserveDate}${reserveBeginTime} から ${reserveEndTime} までの ${useTime}間、カレンダーに追加したッす!`);
});

exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);