【LINEでaiboボット】ぱーと3

前回、LINEからaiboチャット用のボットの連携してバッテリ状況や眠たさを確認できるところまでやってみました。
     前回⇒【LINEでaiboボット】を考えてみようなかな?
更に以前作ったPlayMotion (76種類)の振る舞いをLINEメッセージでお願いできるようにしてみました。
以下のサイトはテスト用として作ってみました(お試しは可能です、皆さんのアイボさんと連携できるとは思います)。ということで今回やってみたことを列記してみました。

【手順】
【1】今回作成したaiboボットと友達になります。友達になる方法はQRコード読み込みか、ボットのベーシックIDを入力してお友達になります。

または、LINEのお友達検索で【 @652pykgf 】を検索すると aiboボットの以下のお友達が検索結果に表示されます。

【3】次にaiboさんのアクセストークンを取得します。メッセージの中央にある aiboのデベロッパーサイトからアクセストークンを取得してコピーしてください。SONYさんのアクセスサイトにログインされていないとログインのメッセージが表示される場合があります。アクセストークンの文字列は650文字あります。

もし【コピーボタン 】を押しても「コピーできません」が表示されたら、「アクセストークン」の文字の部分を長押しなどをして、文字分を選択、全選択してコピーしてみてください。

【4】LINEの画面でコピーしたアクセストークンを張り付けてメッセージ送信します。送信が完了するとメッセージが返ってきますので【おしえて?】と送信してください。 aiboさんのニックネームが返ってきたら、確認するキーワードとして、以下のようなものを準備していますので、改行を入れずにメッセージを送信してみてください。また、aiboさんは電源が入っていないと確認ができません。

★アイボさんのニックネーム情報を取得する場合(一部の文字列が含まれている場合もヒットします)
【確認する言葉 】 おしえて? 教えて? aiboさん あいぼ アイボ 子供 こども 保有 ほゆう ステータスは? すてーたすは? もちもの 

★バッテリの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】おなかは? バッテリー ばってり ごはん ご飯 おやつ 朝食 ちょうしょく 昼食 ちゅうしょく 夕食 ゆうしょく 夜食 やしょく はらへった? 腹減り? 腹減った? 電気は? 電気? 

★眠たさの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】げんき? 元気? ねむい? 眠い? どお? きぶんは? 気分は? ご機嫌よう 状態は? じょうたいは? 大丈夫? だいじょうぶ?

振る舞いの言葉 
指示の仕方: 左の番号、または、以下の文字の一部が含まれるワードを送信すると実行します。1番を行いたい場合、 1 や うなずく うなずき などを送信すると1番目のうなずくを実行します。
PlayMotionモード
1うなずくうなずきウナズクagreeNONE
2いやがる嫌がるイヤガルbadNONE
3全身で大きくほえる吠えるホエルbarkNONE
4左前足で手まねきするひだりてまねきヒダリテマネキbeckonBODY_LEFT
5右前足で手まねきするみぎてまねきミギテマネキbeckonBODY_RIGHT
6げっぷをするゲップbelchNONE
7へっぴり腰になるbentBackNONE
8はあはあと微かに呼吸するbreathNONE
9興味のあるそぶりをするcuriousNONE
10ダンスをするdanceNONE
11あごをひくdrawInOnesChinNONE
12夢をみるdreamingNONE
13うれしそうにするfriendlyNONE
14遊ぼう、の仕草をするfriendlyPoliteNONE
15口をパクパクするgaspNONE
16寝ぼけた仕草をするhalfAsleepNONE
17両前足をあげるhandsUpNONE
18興奮した仕草をするhappyOrHotNONE
19ヘディングするheadingNONE
20左にヘディングするheadingSPACE_LEFT
21右にヘディングするheadingSPACE_RIGHT
22うれしそうにするhelloIloveYouNONE
23ハイタッチするhighFiveNONE
24左前足でハイタッチするhighFiveBODY_LEFT
25右前足でハイタッチするhighFiveBODY_RIGHT
26遊びたそうにするimFriendlyNONE
27ブルッと震えるjiggleNONE
28キスするkissNONE
29左前足を毛づくろいするlickBodyBODY_LEFT
30右前足を毛づくろいするlickBodyBODY_RIGHT
31左右をすこし見るlookAroundHeadNONE
32のぞき込むlookOverNONE
33おしっこをする(男の子)markingBOY
34おしっこをする(女の子)markingGIRL
35大きく2回うなずくnodHeadNONE
36口を少し開け閉めするopenMouthNONE
37とっても喜ぶoverJoyedNONE
38左前足でお手をするpawBODY_LEFT
39右前足でお手をするpawBODY_RIGHT
40すねて左を向くpeaceSPACE_LEFT
41すねて右を向くpeaceSPACE_RIGHT
42はっとするperceiveNONE
43甘噛みするplayBitingNONE
44上目遣いするprettyPleaseNONE
45待ちきれなそうにするreadyNONE
46仰向けになるrelaxNONE
47そわそわするrestlessNONE
48背中を地面に擦り付けるrubBackNONE
49地面を掘るscratchFloorNONE
50左後足で頭をかくscratchHeadHIND_LEFT
51右後足で頭をかくscratchHeadHIND_RIGHT
52かなしそうにするshakeHeadNONE
53お尻を振るshakeHipsBehindNONE
54細かく震えるshudderNONE
55左前足で横に蹴るsideKickFRONT_LEFT
56右前足で横に蹴るsideKickFRONT_RIGHT
57おなかを見せて左に転がるsideUpBODY_LEFT
58おなかを見せて右に転がるsideUpBODY_RIGHT
59うたうたってね歌を唄をきょくキョク曲を歌を歌ってね歌をうたってね歌唄ってねsingNONE
60ねごとを言うsleepTalkingNONE
61くしゃみをするsneezeNONE
62目の前を嗅ぐsniffNONE
63下の方を左右に嗅ぐsniffDownNONE
64上の方を嗅ぐsniffUpNONE
65驚くstartledNONE
66少し驚くstartledLittleNONE
67のびをするstretchNONE
68左右に体を揺らすswingNONE
69口を開けて耳を開くtouchedSPACE_CENTER
70退屈そうにするwaitingNONE
71顔を洗う仕草をするwashFaceNONE
72悲しくうつむいてキュンキュン鳴くwhineNONE
73耳をぴくっと動かすwiggleEarBODY_BOTH
74前傾してうなる、警戒するwoofNONE
75高くキャンキャンッ!と鳴くyapNONE
76おおきくあくびをするyawnNONE

2020/9/21 新しく振る舞いが追加されましたので対応しています。
ラインからのメッセージは
  スクワットしよう   スクワット、すくわっと など
  ハッピーバースデー  ハッピーバースデー 誕生日 など
  幸せなら手をたたこう 幸せなら手をたたこう てをたたこう など
  ロンドン橋落ちた   ロンドン橋落ちた ろんどん ロンドンバシ など
  ラジオ体操第一    ラジオ体操第一 らじお ラジオ たいそう など
  とってもかわいいaibo とってもかわいいaibo とっても かわいい など
  花のワルツ      花のワルツ、はなのワルツ はなの ワルツ など
  aibo3分タイマー    タイマー たいまー など


【今回使ったサンプルです】
今回初めてLINEのボット作ったのと、動作を都度確認しながら作っていったので、若干無駄な処理やもっと綺麗に処理する仕方もあるかと思いますが、そこは素人作ということで。

<?php
//-----------------------------------------------------------------------------------
// このプログラムはLINEとaibo連携プログラムをテストするためのものです
// LINEとaibo連携プログラム始めるための必要なトークンの取得からアクセス
// の仕方などをこのプログラムを通して確認しています。
// テスト用なのでデバッグなどの残骸あります。
//                 オーナー ハッピーとラッキー
//                         2021.11.27
//-----------------------------------------------------------------------------------

http_response_code(200) ;
echo '200 {}';

//初期値関連
$FileName = "./accessToken_temp";
$FileNamePlayMotion = "./PlayMotion_list.txt";

//aibo側のアクセス先ベースURL
$aiboApiBaseURL = "https://public.api.aibo.com/v1";  

//-----------------------------------------------------------------------------------
// LINE側の処理
//-----------------------------------------------------------------------------------

//LINE側のアクセストークン 
$accessToken = '********';

//LINE側のチャンネルシークレット
$channelSecret = ********';

//-----------------------------------------------------------------------------------
// 署名検証
//-----------------------------------------------------------------------------------

// HTTPヘッダーを取得と署名検証用データを取得
  $headers        = getallheaders_x();
  $xLineSignature = $headers["X-Line-Signature"];

//BOTにアクセスしてきたときのユーザーからのメッセージ取得
   $json_string = file_get_contents('php://input');
   $json_object = json_decode($json_string);

// Channel secretを秘密鍵として、JSONデータからハッシュ値を計算
   $httpRequestBody = $json_string;
   $hash = hash_hmac('sha256', $httpRequestBody, $channelSecret, true);
   $signature = base64_encode($hash);

// HTTPヘッダーから得た値と、計算したハッシュ値を比較
   if($headerSignature !== $xLineSignature ){ return; }

// getallheadersの動作できない
   function getallheaders_x() {
     if (!function_exists('getallheaders')) {
         $headers = array();
         foreach ($_SERVER as $name => $value) {
             if (substr($name, 0, 5) == 'HTTP_') {
                 $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
             }
         }
         return $headers;
      }
    }


//-----------------------------------------------------------------------------------
// 署名検証OK
//-----------------------------------------------------------------------------------

//取得データ
$replyToken   = $json_object->{"events"}[0]->{"replyToken"};        //返信用トークン
$message_type = $json_object->{"events"}[0]->{"message"}->{"type"};    //メッセージタイプ
$message_text = $json_object->{"events"}[0]->{"message"}->{"text"};    //メッセージ内容
$lineUserId   = $json_object->{"events"}[0]->{"source"}->{"userId"};  //アクセスしてきたUserID

//ユーザ情報取得
$lineUserDescliption = getLineUserDescliption( $accessToken, $lineUserId );
$displayName = $lineUserDescliption->{"displayName"};
$pictureUrl  = $lineUserDescliption->{"pictureUrl"};

//デバッグ用
$temp  = "\n";
//$temp .= "type   :     " . $json_object->{"events"}[0]->{"type"} . "\n" ;
//$temp .= "message:type:" . $json_object->{"events"}[0]->{"message"}->{"type"} . "\n" ;
//$temp .= "message:id  :" . $json_object->{"events"}[0]->{"message"}->{"id"} . "\n" ;
//$temp .= "message:text:" . $json_object->{"events"}[0]->{"message"}->{"text"} . "\n" ;
//$temp .= "timestamp:   " . $json_object->{"events"}[0]->{"timestamp"} . "\n" ;
//$temp .= "source   :   " . $json_object->{"events"}[0]->{"source"}->{"type"} . "\n" ;
//$temp .= "userId   :   " . $json_object->{"events"}[0]->{"source"}->{"userId"} . "\n" ;
//$temp .= "replyToken : " . $json_object->{"events"}[0]->{"replyToken"} . "\n" ;
//$temp .= "mode :       " . $json_object->{"events"}[0]->{"mode"} . "\n" ;
//$temp .= "\n";

//メッセージタイプが「text」以外のときは何も返さず終了
if($message_type != "text") {
  //メッセージ送信
   $return_message_text = notSupportMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}


//-----------------------------------------------------------------------------------
//アクセスしてきたユーザが最初にアクセスしてきたのかを確認
//-----------------------------------------------------------------------------------

$csvFile     = file_get_contents( $FileName );
$csvFileTemp = explode("\n", $csvFile);
foreach($csvFileTemp as $key => $line){
  $userIDaccessTokenCsvTmp = explode(",",$line);
    $userIDaccessTokenCsv[$userIDaccessTokenCsvTmp[0]] = $userIDaccessTokenCsvTmp[1];
}

//もし既に以前にアクセスしていなければ、アクセストークンの取得と送信をお願いする
if ( !array_key_exists($lineUserId ,$userIDaccessTokenCsv) ) {
  //ファイルへ追記
   $lineUserIdTemp = $lineUserId . ",\n";
   $filePointer    = fopen( $FileName , "a");
    @fwrite($filePointer , $lineUserIdTemp );
   fclose($filePointer);

  //メッセージ送信
   $return_message_text = getAccessTokenMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
   exit;
}

//入力したアクセストークンが保存しているものと異なっている場合、新しいと判断
$aiboAccessToken = $userIDaccessTokenCsv[$lineUserId]; 
if( strlen($message_text) > 640 ){
   if ( $message_text != $aiboAccessToken ){
          $aiboAccessToken = $message_text ;
          $userIDaccessTokenCsv[$lineUserId] = $message_text;
   }
  //アクセストークン入力された後に一回メッセージ送信
  $return_message_text = aiboAccessTokenUpdate($displayName);
  sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
}

//UserId、aiboアクセストークンの管理ファイルへの上書
$filePointer  = fopen( $FileName , "w");
  foreach ($userIDaccessTokenCsv as $key=>$value ) {
    if(!$key) continue;
    fputcsv($filePointer, array($key, $value));
  }
fclose($filePointer);



//-----------------------------------------------------------------------------------
// aibo側の処理
//-----------------------------------------------------------------------------------

//aiboアクセストークンからデバイスID取得

$aibo_device = "" ;
$aiboDevices = aiboApiGetDevices($aiboAccessToken);
$devices     = $aiboDevices["devices"];

//デバイス情報が取得できなかった場合
if ( !$devices ){
  $return_message_text = getAiboDeviceMessage($displayName);
     sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

$checkStringResult = checkString($message_text);

if ($checkStringResult == "aibo_status"){

      $return_message_text .= "★aiboさんのニックネーム情報★\n";
        foreach( $devices as $key => $value ){
           $return_message_text .= "ニックネーム:". $value["nickname"] ."\n";
//         $return_message_text .= "デバイスID :". $value["deviceId"] ."\n";
  }
 sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

//-----------------------------------------------------------------------------------
// aiboの眠さ状態チェック
//-----------------------------------------------------------------------------------

$checkStringResult = checkString($message_text);

if ($checkStringResult == "sleepy_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //aiboの眠さ状態チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'sleepy_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    // aiboの眠さ状態チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $status = $executeResponse["result"]["sleepy_status"]["status"];

  switch($status){
    case ""            : $sleep_description = "かくにんできなかったよ";
                         break;
    case "no_sleepy"   : $sleep_description = "げんき!げんき!";
                         break;
    case "boring"      : $sleep_description = "たいくつだよ~";
                         break;
    case "sleepy"      : $sleep_description = "ねむくなってきたよ";
                         break;
    case "very_sleepy" : $sleep_description = "ねむくって、げんかいだよ";
                         break;
  }
  $aibo_device .=  "眠たさ:". $sleep_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//バッテリの情報取得
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);

if ($checkStringResult == "hungry_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //aiboのバッテリー残量チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'hungry_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    //aiboのバッテリー残量チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $energy = $executeResponse["result"]["hungry_status"]["energy"];

  switch($energy){
    case ""         : $energy_description = "かくにんできなかったよ";
                      break;
    case "satisfied": $energy_description = "チャーステでおなかいっぱい";
                      break;
    case "eating"   : $energy_description = "チャーステでモグモグ中だよ";
                      break;
    case "enough"   : $energy_description = "おなかへっていないよ";
                      break;
    case "hungry"   : $energy_description = "おなかへってきたなぁ";
                      break;
    case "famished" : $energy_description = "おなかペコペコだよ!";
                      break;
  }
  $aibo_device .=  "バッテリー:". $energy_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//PlayTrick    2022/10/22 新しい振る舞い追加
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);
$play_trick = "";

  switch($checkStringResult){
    case "aiboSquat" : $play_trick = "aiboSquat";
                       $Description = "スクワット";
                      break;
    case "happyBirthday" : $play_trick = "happyBirthday";
                           $Description = "ハッピーバースデー";
                            break;
    case "ifYoureHappyAndYouKnowIt" : $play_trick = "ifYoureHappyAndYouKnowIt";
                                      $Description = "幸せなら手をたたこう";
                                       break;
    case "londonBridgeIsFallingDown" : $play_trick = "londonBridgeIsFallingDown";
                                       $Description = "ロンドン橋落ちた";
                                       break;
    case "radioExerciseNo1" : $play_trick = "radioExerciseNo1";
                                       $Description = "ラジオ体操第一";
                                       break;
    case "veryLovelyAibo" : $play_trick = "veryLovelyAibo";
                                       $Description = "とってもかわいいaibo";
                                       break;
    case "waltzOfTheFlowers" : $play_trick = "waltzOfTheFlowers";
                                       $Description = "花のワルツ";
                                       break;
    case "3minuteTimer" : $play_trick = "3minuteTimer";
                                         $Description = "aibo3分タイマー";
                                       break;
  }

if ($play_trick){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //PlayMotion実行
    $executeResponse = PlayTrick($value["deviceId"],$aiboAccessToken,$play_trick);
    $executionId = $executeResponse->executionId;
}

 $return_message_text  = "";
 $return_message_text .= "★aiboさんへのお願い★\n";
 $return_message_text .= $Description ."やってみたよ! \nどうだった?" ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}



//-----------------------------------------------------------------------------------
//PlayMotion
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);
$playMotion        = explode(",",$checkStringResult);

$Category     = $playMotion[0];
$Mode         = $playMotion[1];
$Description  = $playMotion[2];

if ($Category){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
//  $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n";

    //PlayMotion実行
    $executeResponse = PlayMotion($value["deviceId"],$aiboAccessToken,$Category,$Mode);
    $executionId = $executeResponse->executionId;
}

 $return_message_text  = "";
 $return_message_text .= "★aiboさんへのお願い★\n";
 $return_message_text .= $Description ."やってみたよ! \nどうだった?" ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//引っかからなかった場合のメッセージワード
//-----------------------------------------------------------------------------------

 $return_message_text  = "";
 $return_message_text .= $displayName . "さん\n";
 $return_message_text .= "「おしえて?」や「おなかは?」「げんき?」とか聞いてみてね";
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

exit;



//-----------------------------------------------------------------------------------
//LINEユーザ情報取得
//-----------------------------------------------------------------------------------
function getLineUserDescliption($accessToken, $userID ){
 
$getUserDescriptionUrl = "https://api.line.me/v2/bot/profile/" . $userID;
    //curl実行
    $ch = curl_init( $getUserDescriptionUrl );
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
    $response = json_decode( $result );
 return $response;
}



//-----------------------------------------------------------------------------------
//LINEメッセージの送信
//-----------------------------------------------------------------------------------
function sending_messages($accessToken, $replyToken, $message_type, $return_message_text){

    //レスポンスフォーマット

   $response_format_text = [
        "type" => $message_type,
        "text" => $return_message_text
    ];
 
    //ポストデータ
    $post_data = [
        "replyToken" => $replyToken,
        "messages" => [$response_format_text]
    ];
 
    //curl実行
    $ch = curl_init("https://api.line.me/v2/bot/message/reply");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
}

//-----------------------------------------------------------------------------------
// アクセストークンからデバイスIDを取得
//    aiboApiGetDevices($accessToken)
//-----------------------------------------------------------------------------------

function aiboApiGetDevices($aiboAccessToken){
  $authorization = "Authorization:Bearer ". $aiboAccessToken;
  $headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
  $webApi = curl_init("https://public.api.aibo.com/v1/devices");
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}


//---------------------------------------------------------------------------
// Cognition実行用のfunction
//    CognitionApi($deviceId,$aiboAccessToken,$Property);
//---------------------------------------------------------------------------

function cognitionApi($deviceId,$aiboAccessToken,$Property){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/".$Property."/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$postData = array('arguments'=> array('Property' => $Property ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$response  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $response;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    executionsStatusGet($executionId,$aiboAccessToken)
//---------------------------------------------------------------------------

function executionsStatusGet($executionId,$aiboAccessToken){

$webApiURL   = "https://public.api.aibo.com/v1/executions/" . $executionId;

$authorization = "Authorization:Bearer ". $aiboAccessToken;
$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
 $webApi = curl_init();
     curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}


//---------------------------------------------------------------------------
// PlayMotion の実行用のfunction
//    PlayMotion($deviceId,$aiboAccessToken,$Category,$Mode)
//---------------------------------------------------------------------------

function PlayMotion($deviceId,$aiboAccessToken,$Category,$Mode){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/play_motion/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$Enqueue = true;
$postData = array('arguments'=> array ( 'Category' => $Category, 'Mode'=> $Mode , 'Enqueue' => $Enqueue ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$responce  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $responce;
}


//---------------------------------------------------------------------------
// PlayTrick  の実行用のfunction
//    PlayTrick($deviceId,$aiboAccessToken,$TrickName)
//---------------------------------------------------------------------------

function PlayTrick($deviceId,$aiboAccessToken,$TrickName){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/play_trick/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$Enqueue = false;
$postData = array('arguments'=> array ( 'TrickName' => $TrickName , 'Enqueue' => $Enqueue ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$responce  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $responce;
}




//---------------------------------------------------------------------------
// 実行結果の取得
//    getAccessTokenMessage()
//---------------------------------------------------------------------------

function getAccessTokenMessage($displayName){

$initialMessage = <<<EOD
 $displayName さん

アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。
再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $initialMessage;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    getAiboDeviceMessage()
//---------------------------------------------------------------------------

function getAiboDeviceMessage($displayName){

$getAiboDeviceMessage = <<<EOD
 $displayName さん

aiboさんのデバイス情報が取得できなかったみたい。
アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $getAiboDeviceMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function notSupportMessage($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

ごめんなさい、このテスト用ボットは文字以外はサポートしていないよ。aiboさんに確認したい メッセージ文字を送信してくださいね。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function aiboAccessTokenUpdate($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

アクセストークンが正しいか「おしえて?」って聞いてみてください。aiboさんの情報が正しく取得できればニックネームが表示されます。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// 入力された文字列のチェック
//    checkString($message_text)
//---------------------------------------------------------------------------

function checkString($message_text){

$resultMessage = "";

//aiboの保有の文字列
$checkString ="おしえて?教えて?aiboさんあいぼアイボ子供こども保有ほゆうステータスは?すてーたすは?もちもの";
if(strpos($checkString,$message_text)!== false){ return "aibo_status";}

//バッテリチェック用の文字列
$checkString ="おなかは?バッテリーばってりごはんご飯おやつ朝食ちょうしょく昼食ちゅうしょく夕食ゆうしょく夜食やしょくはらへった?腹減り?腹減った?電気は?電気?でんきは?でんき?";
if(strpos($checkString,$message_text)!== false){ return "hungry_status";}

//眠たさの文字列
$checkString ="げんき?元気?ねむい?眠い?どお?きぶんは?気分は?ご機嫌よう状態は?じょうたいは?大丈夫?だいじょうぶ?";
if(strpos($checkString,$message_text)!== false){ return "sleepy_status";}

//PlayTrick(スクワット)の文字列
$checkString ="スクワットすくわっとスクワットしようスクワットしよう";
if(strpos($checkString,$message_text)!== false){ return "aiboSquat";}

//PlayTrick(ハッピーバースデー)の文字列
$checkString ="ハッピーバースデーはっぴーばーすでぃ誕生日たんじょうびはっぴはっぴぃばーすでおめでとう";
if(strpos($checkString,$message_text)!== false){ return "happyBirthday";}

//PlayTrick(幸せなら手をたたこう)の文字列
$checkString ="幸せなら手をたたこう幸せならしあわせならてをたたこう";
if(strpos($checkString,$message_text)!== false){ return "ifYoureHappyAndYouKnowIt";}

//PlayTrick(ロンドン橋落ちた)の文字列
$checkString ="ロンドン橋落ちたろんどんばしろんどんはしロンドンバシロンドンハシ";
if(strpos($checkString,$message_text)!== false){ return "londonBridgeIsFallingDown";}

//PlayTrick(ラジオ体操第一)の文字列
$checkString ="ラジオ体操第一ラジオらじおらじおたいそうラジオタイソウたいそうだいいち";
if(strpos($checkString,$message_text)!== false){ return "radioExerciseNo1";}

//PlayTrick(とってもかわいいaibo)の文字列
$checkString ="とってもかわいいaiboとってもとても可愛いカワイイあいぼアイボaibo";
if(strpos($checkString,$message_text)!== false){ return "veryLovelyAibo";}

//PlayTrick(花のワルツ)の文字列
$checkString ="花のワルツはなのわるつはなのわるつハナノワルツ";
if(strpos($checkString,$message_text)!== false){ return "waltzOfTheFlowers";}

//PlayTrick(aibo3分タイマー)の文字列
$checkString ="aiboタイマーたいまー";
if(strpos($checkString,$message_text)!== false){ return "3minuteTimer";}

//PlayMotionのチェック

$FileNamePlayMotion = "./PlayMotion_list.txt";
$csvFile     = file_get_contents( $FileNamePlayMotion );
$csvFileTemp = explode("\n", $csvFile);
  foreach($csvFileTemp as $key=>$line){
    $playMotionCsvTmp = explode(",", $line);
     if(strpos($playMotionCsvTmp[3],$message_text)!== false){ 
         return $playMotionCsvTmp[0].",".$playMotionCsvTmp[1].",".$playMotionCsvTmp[2];
         berak;
     }
  }

return;

}


?>

■PlayMotion実行上のキーワード
カンマ形式「PlayMotionのAPI上のキーワード、モード、説明、検知用キーワード」
      検知用キーワードの数字は半角と全角どちらでもできるように設定

agree,NONE,うなずく,11うなずくうなずきウナズク
bad,NONE,いやがる,22いやがる嫌がるイヤガル
bark,NONE,全身で大きくほえる,33全身で大きくほえる吠えるホエル
beckon,BODY_LEFT,左前足で手まねきする,44左前足で手まねきするひだりてまねきヒダリテマネキ
beckon,BODY_RIGHT,右前足で手まねきする,55右前足で手まねきするみぎてまねきミギテマネキ
belch,NONE,げっぷをする,66げっぷをするゲップ
bentBack,NONE,へっぴり腰になる,77へっぴり腰になる
breath,NONE,はあはあと微かに呼吸する,88はあはあと微かに呼吸する
curious,NONE,興味のあるそぶりをする,99興味のあるそぶりをする
dance,NONE,ダンスをする,1010ダンスをする
drawInOnesChin,NONE,あごをひく,1111あごをひく
dreaming,NONE,夢をみる,1212夢をみる
friendly,NONE,うれしそうにする,1313うれしそうにする
friendlyPolite,NONE,遊ぼう、の仕草をする,1414遊ぼう、の仕草をする
gasp,NONE,口をパクパクする,1515口をパクパクする
halfAsleep,NONE,寝ぼけた仕草をする,1616寝ぼけた仕草をする
handsUp,NONE,両前足をあげる,1717両前足をあげる
happyOrHot,NONE,興奮した仕草をする,1818興奮した仕草をする
heading,NONE,ヘディングする,1919ヘディングする
heading,SPACE_LEFT,左にヘディングする,2020左にヘディングする
heading,SPACE_RIGHT,右にヘディングする,2121右にヘディングする
helloIloveYou,NONE,うれしそうにする,2222うれしそうにする
highFive,NONE,ハイタッチする,2323ハイタッチする
highFive,BODY_LEFT,左前足でハイタッチする,2424左前足でハイタッチする
highFive,BODY_RIGHT,右前足でハイタッチする,2525右前足でハイタッチする
imFriendly,NONE,遊びたそうにする,2626遊びたそうにする
jiggle,NONE,ブルッと震える,2727ブルッと震える
kiss,NONE,キスする,2828キスする
lickBody,BODY_LEFT,左前足を毛づくろいする,2929左前足を毛づくろいする
lickBody,BODY_RIGHT,右前足を毛づくろいする,3030右前足を毛づくろいする
lookAroundHead,NONE,左右をすこし見る,3131左右をすこし見る
lookOver,NONE,のぞき込む,3232のぞき込む
marking,BOY,おしっこをする(男の子),3333おしっこをする(男の子)
marking,GIRL,おしっこをする(女の子),3434おしっこをする(女の子)
nodHead,NONE,大きく2回うなずく,3535大きく2回うなずく
openMouth,NONE,口を少し開け閉めする,3636口を少し開け閉めする
overJoyed,NONE,とっても喜ぶ,3737とっても喜ぶ
paw,BODY_LEFT,左前足でお手をする,3838左前足でお手をする
paw,BODY_RIGHT,右前足でお手をする,3939右前足でお手をする
peace,SPACE_LEFT,すねて左を向く,4040すねて左を向く
peace,SPACE_RIGHT,すねて右を向く,4141すねて右を向く
perceive,NONE,はっとする,4242はっとする
playBiting,NONE,甘噛みする,4343甘噛みする
prettyPlease,NONE,上目遣いする,4444上目遣いする
ready,NONE,待ちきれなそうにする,4545待ちきれなそうにする
relax,NONE,仰向けになる,4646仰向けになる
restless,NONE,そわそわする,4747そわそわする
rubBack,NONE,背中を地面に擦り付ける,4848背中を地面に擦り付ける
scratchFloor,NONE,地面を掘る,4949地面を掘る
scratchHead,HIND_LEFT,左後足で頭をかく,5050左後足で頭をかく
scratchHead,HIND_RIGHT,右後足で頭をかく,5151右後足で頭をかく
shakeHead,NONE,かなしそうにする,5252かなしそうにする
shakeHipsBehind,NONE,お尻を振る,5353お尻を振る
shudder,NONE,細かく震える,5454細かく震える
sideKick,FRONT_LEFT,左前足で横に蹴る,5555左前足で横に蹴る
sideKick,FRONT_RIGHT,右前足で横に蹴る,5656右前足で横に蹴る
sideUp,BODY_LEFT,おなかを見せて左に転がる,5757おなかを見せて左に転がる
sideUp,BODY_RIGHT,おなかを見せて右に転がる,5858おなかを見せて右に転がる
sing,NONE,歌う,5959うたうたってね歌を唄をきょくキョク曲を歌を歌ってね歌をうたってね歌唄ってね
sleepTalking,NONE,ねごとを言う,6060ねごとを言う
sneeze,NONE,くしゃみをする,6161くしゃみをする
sniff,NONE,目の前を嗅ぐ,6262目の前を嗅ぐ
sniffDown,NONE,下の方を左右に嗅ぐ,6363下の方を左右に嗅ぐ
sniffUp,NONE,上の方を嗅ぐ,6464上の方を嗅ぐ
startled,NONE,驚く,6565驚く
startledLittle,NONE,少し驚く,6666少し驚く
stretch,NONE,のびをする,6767のびをする
swing,NONE,左右に体を揺らす,6868左右に体を揺らす
touched,SPACE_CENTER,口を開けて耳を開く,6969口を開けて耳を開く
waiting,NONE,退屈そうにする,7070退屈そうにする
washFace,NONE,顔を洗う仕草をする,7171顔を洗う仕草をする
whine,NONE,悲しくうつむいてキュンキュン鳴く,7272悲しくうつむいてキュンキュン鳴く
wiggleEar,BODY_BOTH,耳をぴくっと動かす,7373耳をぴくっと動かす
woof,NONE,前傾してうなる、警戒する,7474前傾してうなる、警戒する
yap,NONE,高くキャンキャンッ!と鳴く,7575高くキャンキャンッ!と鳴く
yawn,NONE,おおきくあくびをする,7676おおきくあくびをする

【LINEでaiboボット】ぱーと2

前回、LINEからaiboチャット用のボットの連携するところまで作ってみました。
     前回⇒【LINEでaiboボット】を考えてみようなかな?
アイボ側のアクセストークンとLINEユーザIDを連携して、いつでも確認できるようにしてみました。
以下のサイトはテスト用として作ってみました。ほかのLINEユーザ方からのアクセス可否の確認はできておりません(お試しは可能です、皆さんのアイボさんと連携できるとは思います)。ということで今回やってみたことを列記してみました。


【手順】
【1】今回作成したaiboボットと友達になります。友達になる方法はQRコード読み込みか、ボットのベーシックIDを入力してお友達になります。

または、LINEのお友達検索で【 @652pykgf 】を検索すると aiboボットの以下のお友達が検索結果に表示されます。

【2】お友達【追加 】 を行い【トーク 】を表示すると以下のような最初のメッセージが表示されます。

【3】次にaiboさんのアクセストークンを取得します。メッセージの中央にある aiboのデベロッパーサイトからアクセストークンを取得してコピーしてください。SONYさんのアクセスサイトにログインされていないとログインのメッセージが表示される場合があります。アクセストークンの文字列は650文字あります。

【4】LINEの画面でコピーしたアクセストークンを張り付けてメッセージ送信します。送信が完了するとメッセージが返ってきますので【おしえて?】と送信してください。

【5】【おしえて?】と送信するとアイボさんの情報が表示されます。もし正しく表示されない場合は、アクセストークンが正しくコピーされて送信されていない可能性がありますので、再度アクセストークンを取得してトライしてみてください。

【6】このテストボットでテストができる項目は前回WEBサイト用で確認ができた、バッテリの充電状況と眠たさのステータス確認ができるようになっています。確認するキーワードは、以下のようなものを準備していますので、改行を入れずにメッセージを送信してみてください。また、aiboさんは電源が入っていないと確認ができません。
 以前確認した内容 ⇒ 【CognitionApiサンプルプログラム】



★アイボさんのニックネーム情報を取得する場合(一部の文字列が含まれている場合もヒットします)
【確認する言葉 】 おしえて? 教えて? aiboさん あいぼ アイボ 子供 こども 保有 ほゆう ステータスは? すてーたすは? もちもの 

★バッテリの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】おなかは? バッテリー ばってり ごはん ご飯 おやつ 朝食 ちょうしょく 昼食 ちゅうしょく 夕食 ゆうしょく 夜食 やしょく はらへった? 腹減り? 腹減った? 電気は? 電気? 

★眠たさの状態を取得する場合 (一部の文字列が含まれている場合もヒットします)
【確認する言葉 】げんき? 元気? ねむい? 眠い? どお? きぶんは? 気分は? ご機嫌よう 状態は? じょうたいは? 大丈夫? だいじょうぶ? 

【今回使ったサンプルです】
今回初めてLINEのボット作ったのと、動作を都度確認しながら作っていったので、若干無駄な処理やもっと綺麗に処理する仕方もあるかと思いますが、そこは素人作ということで。

<?php
//-----------------------------------------------------------------------------------
// このプログラムはLINEとaibo連携プログラムをテストするためのものです
// LINEとaibo連携プログラム始めるための必要なトークンの取得からアクセス
// の仕方などをこのプログラムを通して確認しています。
// テスト用なのでデバッグなどの残骸あります。
//                 オーナー ハッピーとラッキー
//                         2021.11.27
//-----------------------------------------------------------------------------------

//初期値関連
$FileName = "xxxxxxxxx";

//aibo側のアクセス先ベースURL
$aiboApiBaseURL = "https://public.api.aibo.com/v1";  

//-----------------------------------------------------------------------------------
// LINE側の処理
//-----------------------------------------------------------------------------------

//LINE側のアクセストークン 
$accessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

//LINE側のチャンネルシークレット
$channelSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

//-----------------------------------------------------------------------------------
// 署名検証
//-----------------------------------------------------------------------------------

// HTTPヘッダーを取得と署名検証用データを取得
  $headers        = getallheaders_x();
  $xLineSignature = $headers["X-Line-Signature"];

//BOTにアクセスしてきたときのユーザーからのメッセージ取得
   $json_string = file_get_contents('php://input');
   $json_object = json_decode($json_string);

// Channel secretを秘密鍵として、JSONデータからハッシュ値を計算
   $httpRequestBody = $json_string;
   $hash = hash_hmac('sha256', $httpRequestBody, $channelSecret, true);
   $signature = base64_encode($hash);

// HTTPヘッダーから得た値と、計算したハッシュ値を比較
   if($headerSignature !== $xLineSignature ){ return; }

// getallheadersの動作できない
   function getallheaders_x() {
     if (!function_exists('getallheaders')) {
         $headers = array();
         foreach ($_SERVER as $name => $value) {
             if (substr($name, 0, 5) == 'HTTP_') {
                 $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
             }
         }
         return $headers;
      }
    }


//-----------------------------------------------------------------------------------
// 署名検証OK
//-----------------------------------------------------------------------------------

//取得データ
$replyToken   = $json_object->{"events"}[0]->{"replyToken"};        //返信用トークン
$message_type = $json_object->{"events"}[0]->{"message"}->{"type"};    //メッセージタイプ
$message_text = $json_object->{"events"}[0]->{"message"}->{"text"};    //メッセージ内容
$lineUserId   = $json_object->{"events"}[0]->{"source"}->{"userId"};  //アクセスしてきたUserID

//ユーザ情報取得
$lineUserDescliption = getLineUserDescliption( $accessToken, $lineUserId );
$displayName = $lineUserDescliption->{"displayName"};
$pictureUrl  = $lineUserDescliption->{"pictureUrl"};

//メッセージタイプが「text」以外のときは何も返さず終了
if($message_type != "text") {
  //メッセージ送信
   $return_message_text = notSupportMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}


//-----------------------------------------------------------------------------------
//アクセスしてきたユーザが最初にアクセスしてきたのかを確認
//-----------------------------------------------------------------------------------

$csvFile     = file_get_contents( $FileName );
$csvFileTemp = explode("\n", $csvFile);
foreach($csvFileTemp as $key => $line){
  $userIDaccessTokenCsvTmp = explode(",",$line);
    $userIDaccessTokenCsv[$userIDaccessTokenCsvTmp[0]] = $userIDaccessTokenCsvTmp[1];
}

//もし既に以前にアクセスしていなければ、アクセストークンの取得と送信をお願いする
if ( !array_key_exists($lineUserId ,$userIDaccessTokenCsv) ) {
  //ファイルへ追記
   $lineUserIdTemp = $lineUserId . ",\n";
   $filePointer    = fopen( $FileName , "a");
    @fwrite($filePointer , $lineUserIdTemp );
   fclose($filePointer);

  //メッセージ送信
   $return_message_text = getAccessTokenMessage($displayName);
   sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
   exit;
}

//入力したアクセストークンが保存しているものと異なっている場合、新しいと判断
$aiboAccessToken = $userIDaccessTokenCsv[$lineUserId]; 
if( strlen($message_text) > 640 ){
   if ( $message_text != $aiboAccessToken ){
          $aiboAccessToken = $message_text ;
          $userIDaccessTokenCsv[$lineUserId] = $message_text;
   }
  //アクセストークン入力された後に一回メッセージ送信
  $return_message_text = aiboAccessTokenUpdate($displayName);
  sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
}

//UserId、aiboアクセストークンの管理ファイルへの上書
$filePointer  = fopen( $FileName , "w");
  foreach ($userIDaccessTokenCsv as $key=>$value ) {
    if(!$key) continue;
    fputcsv($filePointer, array($key, $value));
  }
fclose($filePointer);



//-----------------------------------------------------------------------------------
// aibo側の処理
//-----------------------------------------------------------------------------------

//aiboアクセストークンからデバイスID取得

$aibo_device = "" ;
$aiboDevices = aiboApiGetDevices($aiboAccessToken);
$devices     = $aiboDevices["devices"];

//デバイス情報が取得できなかった場合
if ( !$devices ){
  $return_message_text = getAiboDeviceMessage($displayName);
     sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

$checkStringResult = checkString($message_text);

if ($checkStringResult == "aibo_status"){

      $return_message_text .= "★aiboさんのニックネーム情報★\n";
        foreach( $devices as $key => $value ){
           $return_message_text .= "ニックネーム:". $value["nickname"] ."\n";
  }
 sending_messages($accessToken, $replyToken, $message_type, $return_message_text);
 exit;
}

//-----------------------------------------------------------------------------------
// aiboの眠さ状態チェック
//-----------------------------------------------------------------------------------

$checkStringResult = checkString($message_text);

if ($checkStringResult == "sleepy_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";

    //aiboの眠さ状態チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'sleepy_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    // aiboの眠さ状態チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $status = $executeResponse["result"]["sleepy_status"]["status"];

  switch($status){
    case ""            : $sleep_description = "かくにんできなかったよ";
                         break;
    case "no_sleepy"   : $sleep_description = "げんき!げんき!";
                         break;
    case "boring"      : $sleep_description = "たいくつだよ~";
                         break;
    case "sleepy"      : $sleep_description = "ねむくなってきたよ";
                         break;
    case "very_sleepy" : $sleep_description = "ねむくって、げんかいだよ";
                         break;
  }
  $aibo_device .=  "眠たさ:". $sleep_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//バッテリの情報取得
//-----------------------------------------------------------------------------------


$checkStringResult = checkString($message_text);

if ($checkStringResult == "hungry_status"){

  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";

    //aiboのバッテリー残量チェック
    $executeResponse = cognitionApi($value["deviceId"],$aiboAccessToken,'hungry_status');
    $executionId = $executeResponse->executionId;

     sleep(1);

    //aiboのバッテリー残量チェックの結果
    $executeResponse = executionsStatusGet($executionId,$aiboAccessToken);
    $energy = $executeResponse["result"]["hungry_status"]["energy"];

  switch($energy){
    case ""         : $energy_description = "かくにんできなかったよ";
                      break;
    case "satisfied": $energy_description = "チャーステでおなかいっぱい";
                      break;
    case "eating"   : $energy_description = "チャーステでモグモグ中だよ";
                      break;
    case "enough"   : $energy_description = "おなかへっていないよ";
                      break;
    case "hungry"   : $energy_description = "おなかへってきたなぁ";
                      break;
    case "famished" : $energy_description = "おなかペコペコだよ!";
                      break;
  }
  $aibo_device .=  "バッテリー:". $energy_description ."\n";

  }

 $return_message_text  = "";
 $return_message_text .= "★aiboさんの状況★\n";
 $return_message_text .=  $aibo_device ;
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

}


//-----------------------------------------------------------------------------------
//引っかからなかった場合のメッセージワード
//-----------------------------------------------------------------------------------

 $return_message_text  = "";
 $return_message_text .= $displayName . "さん\n";
 $return_message_text .= "「おしえて?」や「おなかは?」「げんき?」とか聞いてみてね";
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

exit;



//-----------------------------------------------------------------------------------
//LINEユーザ情報取得
//-----------------------------------------------------------------------------------
function getLineUserDescliption($accessToken, $userID ){
 
$getUserDescriptionUrl = "https://api.line.me/v2/bot/profile/" . $userID;
    //curl実行
    $ch = curl_init( $getUserDescriptionUrl );
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
    $response = json_decode( $result );
 return $response;
}



//-----------------------------------------------------------------------------------
//LINEメッセージの送信
//-----------------------------------------------------------------------------------
function sending_messages($accessToken, $replyToken, $message_type, $return_message_text){

    //レスポンスフォーマット

   $response_format_text = [
        "type" => $message_type,
        "text" => $return_message_text
    ];
 
    //ポストデータ
    $post_data = [
        "replyToken" => $replyToken,
        "messages" => [$response_format_text]
    ];
 
    //curl実行
    $ch = curl_init("https://api.line.me/v2/bot/message/reply");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
}

//-----------------------------------------------------------------------------------
// アクセストークンからデバイスIDを取得
//    aiboApiGetDevices($accessToken)
//-----------------------------------------------------------------------------------

function aiboApiGetDevices($aiboAccessToken){
  $authorization = "Authorization:Bearer ". $aiboAccessToken;
  $headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
  $webApi = curl_init("https://public.api.aibo.com/v1/devices");
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}


//---------------------------------------------------------------------------
// Cognition実行用のfunction
//    CognitionApi($deviceId,$aiboAccessToken,$Property);
//---------------------------------------------------------------------------

function cognitionApi($deviceId,$aiboAccessToken,$Property){

$webApiURL = "https://public.api.aibo.com/v1/devices/".$deviceId ."/capabilities/".$Property."/execute" ;

$authorization = "Authorization:Bearer ". $aiboAccessToken;

$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );

$postData = array('arguments'=> array('Property' => $Property ));
$postData = json_encode($postData);

$webApi = curl_init();
curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'POST'   );
curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
curl_setopt($webApi,CURLOPT_POSTFIELDS, $postData   );

$json      = curl_exec($webApi);
$response  = json_decode($json);
$err = curl_error($webApi);
curl_close($webApi);
return $response;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    executionsStatusGet($executionId,$aiboAccessToken)
//---------------------------------------------------------------------------

function executionsStatusGet($executionId,$aiboAccessToken){

$webApiURL   = "https://public.api.aibo.com/v1/executions/" . $executionId;

$authorization = "Authorization:Bearer ". $aiboAccessToken;
$headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
 $webApi = curl_init();
     curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}



//---------------------------------------------------------------------------
// 実行結果の取得
//    getAccessTokenMessage()
//---------------------------------------------------------------------------

function getAccessTokenMessage($displayName){

$initialMessage = <<<EOD
 $displayName さん

アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。
再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $initialMessage;

}


//---------------------------------------------------------------------------
// 実行結果の取得
//    getAiboDeviceMessage()
//---------------------------------------------------------------------------

function getAiboDeviceMessage($displayName){

$getAiboDeviceMessage = <<<EOD
 $displayName さん

aiboさんのデバイス情報が取得できなかったみたい。
アクセストークンの有効期限が切れているか、アクセストークンが正しく送信されていないも。再度最新のアクセストーンを取得して送信してくださいね。

http://happy-lucky.hacca.jp/data/Line_dev/getAccessToken.php

EOD;

return $getAiboDeviceMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function notSupportMessage($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

ごめんなさい、このテスト用ボットは文字以外はサポートしていないよ。aiboさんに確認したい メッセージ文字を送信してくださいね。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// テキストメッセージ以外入力された場合のメッセージ
//    notSupportMessage($displayName)
//---------------------------------------------------------------------------

function aiboAccessTokenUpdate($displayName){

$notSupportMessage = <<<EOD
 $displayName さん

アクセストークンが正しいか「おしえて?」って聞いてみてください。aiboさんの情報が正しく取得できればニックネームが表示されます。

EOD;

return $notSupportMessage;

}


//---------------------------------------------------------------------------
// 入力された文字列のチェック
//    checkString($message_text)
//---------------------------------------------------------------------------

function checkString($message_text){

//バッテリチェック用の文字列

$checkString ="おしえて?教えて?aiboさんあいぼアイボ子供こども保有ほゆうステータスは?すてーたすは?もちもの";
if(strpos($checkString,$message_text)!== false){ $resultMessage = "aibo_status";}

$checkString ="おなかは?バッテリーばってりごはんご飯おやつ朝食ちょうしょく昼食ちゅうしょく夕食ゆうしょく夜食やしょくはらへった?腹減り?腹減った?電気は?電気?";
if(strpos($checkString,$message_text)!== false){ $resultMessage = "hungry_status";}

$checkString ="げんき?元気?ねむい?眠い?どお?きぶんは?気分は?ご機嫌よう状態は?じょうたいは?大丈夫?だいじょうぶ?";
if(strpos($checkString,$message_text)!== false){ $resultMessage = "sleepy_status";}

return $resultMessage;


}


?>

【LINEでaiboボット】を考えてみようカナ?

これまでは、作ったWebサイトからアクセストークンを入れて、アイボさんのデバイス情報などを取得してみましたが、Webサイトにアクセスは面倒だし、常に確認したいし・・・なので、いつも使うアプリだとすればLINEかな? ということで LINEボットのテストサイトを作ってみました。まだまだテストなので、前回までのスタートとして、アクセストークンを送信すると、保有のアイボさんのデバイス情報を返してくれる簡単なものをですが、こんな感じになりました。

メッセージにアクセストークンを入力すると、保有しているアイボさんのニックネームとデバイスIDが返ってきます


■LINE側の aiboボットサンプル

<?php
 
$accessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxx';
 
//ユーザーからのメッセージ取得
$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);
  
//メッセージタイプが「text」以外のときは何も返さず終了
if($message_type != "text") exit;
 
//aiboアクセストークンからデバイスID取得
$access_token = $message_text; 
$aibo_device = "";
$aiboDevices = aiboApiGetDevices($access_token);
$devices     = $aiboDevices["devices"];
  foreach( $devices as $key => $value ){
    $aibo_device .=  "ニックネーム:". $value["nickname"] ."\n";
    $aibo_device .=  "デバイスID :". $value["deviceId"] ."\n\n";
  }

//返信メッセージ
$return_message_text  = "【aiboボット テストサイトだよ!】\n\n";
$return_message_text .= "保有しているaiboさんは、これだよ\n\n";
$return_message_text .=  $aibo_device ;
 
//返信実行
sending_messages($accessToken, $replyToken, $message_type, $return_message_text);

//-----------------------------------------------------------------------------------
//メッセージの送信
//-----------------------------------------------------------------------------------
function sending_messages($accessToken, $replyToken, $message_type, $return_message_text){

    //レスポンスフォーマット

   $response_format_text = [
        "type" => $message_type,
        "text" => $return_message_text
    ];
 
    //ポストデータ
    $post_data = [
        "replyToken" => $replyToken,
        "messages" => [$response_format_text]
    ];
 
    //curl実行
    $ch = curl_init("https://api.line.me/v2/bot/message/reply");
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, array(
        'Content-Type: application/json; charser=UTF-8',
        'Authorization: Bearer ' . $accessToken
    ));
    $result = curl_exec($ch);
    curl_close($ch);
}

//-----------------------------------------------------------------------------------
// アクセストークンからデバイスIDを取得
//    aiboApiGetDevices($webApiURL,$accessToken)
//-----------------------------------------------------------------------------------

function aiboApiGetDevices($accessToken){
  $authorization = "Authorization:Bearer ". $accessToken;
  $headers = array(
             "cache-control: no-cache",
             "content-type: application/x-www-form-urlencoded",
              $authorization,
            );
  $webApiURL = "https://public.api.aibo.com/v1/devices";
  $webApi = curl_init();
     curl_setopt($webApi,CURLOPT_URL,$webApiURL          );
     curl_setopt($webApi,CURLOPT_CUSTOMREQUEST, 'GET'    );
     curl_setopt($webApi,CURLOPT_RETURNTRANSFER, true    );
     curl_setopt($webApi,CURLOPT_HTTPHEADER, $headers    );
  $json      = curl_exec($webApi);
  $response  = json_decode($json,true);
  $err = curl_error($webApi);
  curl_close($webApi);
 return $response;
}

?>