質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

Q&A

解決済

1回答

4992閲覧

PHPからシェルスクリプトを実行する際にコンソール上では成功するが、外部からWebhookでPostするとエラーになる

T-Moriyama

総合スコア11

cURL

cURLはHTTP, FTPやTelnetなど複数のプロトコルを用いてデータを転送するライブラリとコマンドラインツールを提供します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

sh

shは、UNIX系OSのシェル操作の1つであり、最も基本的なシェルのことです。

0グッド

0クリップ

投稿2018/01/23 18:06

編集2018/01/25 13:06

###前提・実現したいこと
ここ数日でシェルスクリプトやPHPを触り始めた全くの素人です。
GoogleホームとNatureRemoのAPI使ってエアコンをワンフレーズで制御したい。
IFTTTを使用しGoogleアシスタントをトリガーにWebhookからpostし
ラズベリーパイのPHPで受け取って、シェルスクリプトからAPIで制御したい。
Webhookから直接APIを送信したかったが、Webhookでは認証トークンをヘッダーに追加することができなかった為
このような変則的な方法を試しています。

###発生している問題・エラーメッセージ
ラズベリーパイのコンソール上でcurlを叩くと正常に動作するが、外部からWebhook
で発信するとシェルスクリプトがエラーを吐いて機能しない

(apache2のエラーログ) [Thu Jan 25 22:03:01.529499 2018] [:error] [pid 8463] [client 34.201.45.176:34242] PHP Notice: Undefined index: mode in /var/www/html/aircon.php on line 12 sh: 1: Syntax error: Unterminated quoted string
(ブラウザから http://{myurl}/aircon.php で表示される項目) NULL NULL NULL string(178) " エアコンを モードで 度の 風向き 風量 で起動!! {"temp":"0","mode":"auto","vol":"auto","dir":"auto","button":"","updated_at":"2018-01-24T04:44:37Z"}"

###該当のソースコード

PHP

1// 2018/1/25 22:00 修正しました。 2<?php 3 4$mode = isset($_POST["mode"])?$_POST["mode"]:"暖房"; 5$temp = isset($_POST["temp"])?$_POST["temp"]:"24"; 6$button = isset($_POST["button"])?$_POST["button"]:"power-off"; 7 8$json_string = file_get_contents('php://input'); 9$filename = "php_input.txt"; 10 11file_put_contents($filename, $json_string, FILE_APPEND); 12 13$mode = $_POST["mode"]; 14$temp = $_POST["temp"]; 15$button = $_POST["button"]; 16 17echo $temp,$mode,$button; 18var_dump($temp,$mode,$button); 19 20$output = shell_exec('/bin/sh /home/pi/test.sh "'.$mode.'" "'.$temp.'" "'.$button.'"'); 21 22var_dump($output); 23?>
上記の結果 $ cat /var/www/html/php_input.txt -d "mode=冷房&temp=26&button=power-on"

bash

1#!/bin/sh 2 3echo "$1 $2 $3" 4 5case "$1" in 6 "オート" | "自動" ) 7 if [ "$2" -ge "-5" -a "$2" -le"5" ] 8 then 9 mode="auto" temp="$2" dir="auto" vol="auto" 10 else 11 mode="auto" temp="0" dir="auto" vol="auto" 12 fi ;; 13 "クーラー" | "冷房" ) 14 if [ "$2" -ge "19" -a "$2" -le "32" ] 15 then 16 mode="cool" temp="$2" dir="auto" vol="auto" 17 else 18 mode="auto" temp="0" dir="auto" vol="auto" 19 fi ;; 20 "ドライ" ) 21 if [ "$2" -ge "-2" -a "$2" -le "2" ] 22 then 23 mode="dry" temp="$2" dir="auto" vol="auto" 24 else 25 mode="auto" temp="0" dir="auto" vol="auto" 26 fi ;; 27 "ヒーター" | "暖房" ) 28 if [ "$2" -ge "14" -a "$2" -le "30" ] 29 then 30 mode="warm" temp="$2" dir="auto" vol="auto" 31 else 32 mode="auto" temp="0" dir="auto" vol="auto" 33 fi ;; 34 * ) 35 mode="auto" temp="0" dir="auto" vol="auto" ;; 36esac 37 38echo "エアコンを $mode モードで $temp 度で 風向き $dir 風量 $vol で起動!!" 39 40curl -X POST "https://api.nature.global/1/appliances/{id}/aircon_settings" \ 41-H "accept: application/json" \ 42-H "Content-Type: application/x-www-form-urlencoded" \ 43-d "temperature=$temp&operation_mode=$mode&air_volume=$vol&air_direction=$dir&button=$3" \ 44-k --header "Authorization: Bearer {token}"
IFTTTの設定 Googleアシスタント(トリガー) Say a phrase with both a number and a text ingredient:「エアコンを$#度でつけて」 Webhook(アクション) URL: http://raspi-url.jp/aircon.php Method: POST ContentType: appricaton/x-www-form-urlencoded Body: -d "temp={{NumberField}}&mode={{TextField}}&button=power-on"

###試したこと
ルーターのポートは開放されていることを確認
ラズベリーパイのコンソール上で
$ curl -X POST "http://localhost/aircon.php" -H "Content-Type: application/x-www-form-urlencoded" -d "temp=26&mode=暖房&button=power-on"
と打ち込むと意図した動作を行う
Windowsのコマンドプロンプトから同じcurlを入力するとechoで出力する文字が文字化けするので文字のエンコードが原因か?
IFTTTでWebhookではなくメールやメッセージに送るアクションだと"暖房 27"などと表示され文字化け無し

###補足情報(言語/FW/ツール等のバージョンなど)
NatureRemo Cloud API
http://swagger.nature.global/

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2018/01/24 01:33

var_dump($output); の出力結果はありますか?
T-Moriyama

2018/01/24 04:31

すみません。これがどこに出力されているのかわかりません。ブラウザから当該phpを表示すると、シェルスクリプトからechoで出力した文字が表示されます。
otn

2018/01/24 04:36

ブラウザ表示内容を「そのまま」質問に追記してください。
T-Moriyama

2018/01/24 04:50

ありがとうございます。問題・エラーメッセージ等の項目に追加しました
guest

回答1

0

ベストアンサー

エラー内容は、$temp が空なので処理がうまく行っていないと言っています。
IFTTTの設定方法を知らないのですが、うまく post 出来ていないのではないかと思われます。

以下のような切り分けで動作確認が取れるかと
$temp = $_POST["temp"]に初期値を入れ、動作確認(問題箇所の特定)
・post が意図したとおりに行われているか確認(原因の特定)
・IFTTTからのアクセスを生で確認(post 内容の把握)

メモ
・$temp のみが notice を吐いているので、POST 自体はできてるっぽい
・他のパラメータが正しく post されているなら、Body: -d "temp={{NumberField}}&mode={{TextField}}&button=power-on"が正しくない??
・順番を入れ替えるのも、確認方法としては手っ取り早いかも

投稿2018/01/23 23:58

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

T-Moriyama

2018/01/24 04:42 編集

ご回答ありがとうございます。 ご指摘の通り、WebhookからPOSTする項目の順番を変更すると、先頭の項目が必ずnoticeになります。 そこで先頭にダミーを付加してPOSTさせたらシェルスクリプトのエラー(?)だけになりました。 (apache2のエラーログ) sh: 1: Syntax error: Unterminated quoted string なのでシェルスクリプトで行っている分岐処理をPHP内で処理するように変更してみようと考えています。 可能であればphpでAPIを送信できればもっとシンプルになると考えておりますが、APIを実行する際に認証トークンを付加するので漏洩が心配です。
退会済みユーザー

退会済みユーザー

2018/01/24 09:52

メモだけ実施されても困ります。 post 内容が正しくないと思われるので、記述した切り分けを実施し、IFTTT のドキュメントを読み、正しいパラメータを付加してあげてください。 なぜ、`> なので`以下の流れになるのか分かりませんが、curl 部分を php で再現するのは特に特殊なことを必要とはしていません。 > 漏洩が心配です シェルスクリプトはよくわからないですが、入力値の確認等をしていないので、php の権限でやりたい放題できるスクリプトになっているように思えます。多分、token の漏洩以前に気にすべき点がありそうです。
T-Moriyama

2018/01/25 01:30

ご回答有難うございます。 前回の返答大変失礼致しました。 初期値を入力しても同じエラーメッセージが表示されました。 Webhookがどのように発信しているのか、IFTTTからのアクセス方法を調べる術がわかりませんでした。唯一影響があったのがメモにで指摘されていた事項でした。 phpやシェルスクリプトについては本当に素人なので、変な返信になってしまい、申し訳ございません。
退会済みユーザー

退会済みユーザー

2018/01/25 01:57

受け取った post 情報を log として出力してみて確認すると良いです。 php://input をファイル出力して、確認してみてください。 あと、 > 初期値を入力しても同じエラーメッセージが表示されました。 これはどういった処理を追記したのでしょうか? $temp = isset($_POST["temp"])?$_POST["temp"]:20; とかをイメージしてましたが一致していますか?
T-Moriyama

2018/01/25 12:55 編集

ご回答ありがとうございます。 教えていただいた"php://input"でPOST情報をテキストファイルに出力 してみました。内容はWebhookのBodyに記述した内容と同じ -d ”mode=暖房&temp=26&button=power-on” ※modeとtempはgoogleアシスタントに話した内容と一致 となっておりました。 初期値についてはそのまま $mode = "冷房"; $temp="25" 等と記述してましたが、エラーログの内容は同じでしたので $temp = isset($_POST["temp"])?$_POST["temp"]:20; と書き換えましたが、やはり同じエラーでした。 [Thu Jan 25 21:39:58.631326 2018] [:error] [pid 9634] [client xxx.xxx.xxx.xxx:xxxxx] PHP Notice: Undefined index: mode in /var/www/html/aircon.php on line 12 sh: 1: Syntax error: Unterminated quoted string
退会済みユーザー

退会済みユーザー

2018/01/25 14:35

POST 内容の出力がおかしいと思います。-d とか"入っているのは意図した内容ではないはず。 IFTTT の設定として、 temp={{NumberField}}&mode={{TextField}}&button=power-on をベタ打ちしてみるとか。
T-Moriyama

2018/01/25 14:53

おお!! 意図したとおりに制御できました!! IFTTTのBODYにベタ打ちで実現できました。 なんと単純なミスで本当にすみませんでした te2ji様、素人の私相手に丁寧にアドバイス下さり本当に有難うございました。 大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問