突然ですが・・
毎日時間に追われて過ごしている皆さん、朝食を取らずに出社したり、適当に菓子パンを頬張りながら仕事したり、昼食は毎回ラーメンやファーストフードで済ませたりしていませんか?
たまにならいいんです。おいしいですもんね。分かります。
でも、毎日の積み重ねで不健康が加速して、10年前の自分はこんなんじゃなかったとぼやく未来なんて悲しいですよね。
いやいや、そんな考えてる暇も自炊する暇も無いよ😠
そうですよね。栄養を気にしてくれる人がいたら・・なんて妄想する人もいることでしょう。
そこで、コンビニや食堂で手軽に手に入るメニューをおすすめしてくれる人(の代わり、LINE Bot)を作ってみました!
活用ツールや技術
・Node-RED
・JavaScript
・LINEmessagingAPI
フロー
フロー自体は初心者でも分かる、簡単かつシンプルなものにしました。
まず、LINE Developersでチャネルを開設、Messaging API設定でWebhook設定、チャネルシークレット、チャネルアクセストークンの取得を行います。(こちらの詳しい説明は省略します)
ソースコード
[{"id":"97811561ee3a6b19","type":"Webhook","z":"9ef9e62fc4a4dae4","name":"","url":"/webhook","x":80,"y":400,"wires":[["bc574decf74c8274"]]},{"id":"bc574decf74c8274","type":"switch","z":"9ef9e62fc4a4dae4","name":"","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"朝食","vt":"str"},{"t":"eq","v":"朝ごはん","vt":"str"},{"t":"eq","v":"昼食","vt":"str"},{"t":"eq","v":"ランチ","vt":"str"},{"t":"eq","v":"昼ごはん","vt":"str"},{"t":"eq","v":"名言","vt":"str"},{"t":"else"}],"checkall":"true","repair":false,"outputs":7,"x":230,"y":400,"wires":[["2a93e82fe561e35d"],["2a93e82fe561e35d"],["9f0c3636c6dc4d9a"],["9f0c3636c6dc4d9a"],["9f0c3636c6dc4d9a"],[],["117eda19e0f3da20"]]},{"id":"2a93e82fe561e35d","type":"function","z":"9ef9e62fc4a4dae4","name":"朝食","func":"function getRandomElement(array) {\n return array[Math.floor(Math.random() * array.length)];\n}\n\nconst categories = {\n onigiri: [\"鮭おにぎり\", \"梅おにぎり\", \"昆布おにぎり\"],\n sandwich: [\"ハムサンド\", \"卵サンド\", \"ツナサンド\"],\n salad: [\"チキンサラダ\", \"ツナサラダ\", \"シーザーサラダ\"],\n yogurt: [\"プレーンヨーグルト\", \"フルーツ入りヨーグルト\", \"ギリシャヨーグルト\"],\n fruit: [\"カットフルーツ(メロン、パイナップルなど)\", \"バナナ\", \"りんご\"],\n smoothie: [\"野菜スムージー\", \"フルーツスムージー\", \"プロテインスムージー\"],\n cerealBar: [\"グラノーラバー\", \"ナッツ&シードバー\", \"フルーツバー\"],\n hotMenu: [\"おでん\", \"中華まん\", \"焼き芋\"],\n bread: [\"クロワッサン\", \"ベーグル\", \"ブランパン\"],\n others: [\"サバの塩焼き\", \"枝豆\", \"ゆで卵\"],\n drink: [\"豆乳\", \"プロテインドリンク\", \"ミルク\"]\n};\n\nconst randomSelection = {\n onigiri: getRandomElement(categories.onigiri),\n sandwich: getRandomElement(categories.sandwich),\n salad: getRandomElement(categories.salad),\n yogurt: getRandomElement(categories.yogurt),\n fruit: getRandomElement(categories.fruit),\n smoothie: getRandomElement(categories.smoothie),\n cerealBar: getRandomElement(categories.cerealBar),\n hotMenu: getRandomElement(categories.hotMenu),\n bread: getRandomElement(categories.bread),\n others: getRandomElement(categories.others),\n drink: getRandomElement(categories.drink)\n};\n\n// 結果を整形してメッセージとして設定\nmsg.payload = `\n今日のおすすめ朝食メニュー:\nおにぎり: ${randomSelection.onigiri}\nサンドイッチ: ${randomSelection.sandwich}\nサラダ: ${randomSelection.salad}\nヨーグルト: ${randomSelection.yogurt}\nフルーツ: ${randomSelection.fruit}\nスムージー: ${randomSelection.smoothie}\nシリアルバー: ${randomSelection.cerealBar}\nホットメニュー: ${randomSelection.hotMenu}\nパン: ${randomSelection.bread}\nその他: ${randomSelection.others}\n飲み物: ${randomSelection.drink}\n`;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":360,"wires":[["2fb4f5b04158148f"]]},{"id":"9f0c3636c6dc4d9a","type":"function","z":"9ef9e62fc4a4dae4","name":"昼食","func":"function getRandomElement(array) {\n return array[Math.floor(Math.random() * array.length)];\n}\n\nconst categories = {\n bento: [\"チキン南蛮弁当\", \"焼肉弁当\", \"鮭弁当\", \"鯖の塩焼き弁当\", \"牛丼弁当\"],\n sandwich: [\"ローストビーフサンドイッチ\", \"クラブハウスサンドイッチ\", \"カツサンド\", \"エッグサラダサンドイッチ\", \"ツナサラダサンドイッチ\"],\n salad: [\"シーザーサラダ\", \"チキンサラダ\", \"豆腐サラダ\", \"海藻サラダ\", \"ミックスサラダ(チーズ、ナッツ入り)\"],\n pasta: [\"ペペロンチーノ\", \"カルボナーラ\", \"ミートソーススパゲッティ\", \"バジルソースパスタ\", \"シーフードパスタ\"],\n donburi: [\"親子丼\", \"牛丼\", \"海鮮丼\", \"豚丼\", \"天丼\"],\n soup: [\"ミネストローネ\", \"コーンスープ\", \"わかめスープ\", \"チキンスープ\", \"野菜たっぷりスープ\"]\n};\n\nconst randomSelection = {\n bento: getRandomElement(categories.bento),\n sandwich: getRandomElement(categories.sandwich),\n salad: getRandomElement(categories.salad),\n pasta: getRandomElement(categories.pasta),\n donburi: getRandomElement(categories.donburi),\n soup: getRandomElement(categories.soup)\n};\n\n// 結果を整形してメッセージとして設定\nmsg.payload = `\n今日のおすすめ昼食メニュー:\nお弁当: ${randomSelection.bento}\nサンドイッチ: ${randomSelection.sandwich}\nサラダ: ${randomSelection.salad}\nパスタ: ${randomSelection.pasta}\n丼もの: ${randomSelection.donburi}\nスープ: ${randomSelection.soup}\n`;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":400,"wires":[["2fb4f5b04158148f"]]},{"id":"117eda19e0f3da20","type":"template","z":"9ef9e62fc4a4dae4","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"朝食・朝ごはん\n昼食・昼ごはん・ランチ\nと入力してね!\n\n栄養バランスのポイント\n【たんぱく質】 肉、魚、豆腐、卵などのたんぱく質が豊富な食材を選びましょう。\n【野菜】 サラダやスープに野菜を取り入れて、ビタミンやミネラルを摂取しましょう。\n【炭水化物】 主食としてご飯やパン、パスタなどをバランスよく摂取します。\n【健康的な脂肪】 ドレッシングやナッツ、魚の脂など、健康的な脂肪を適量取り入れます。\n\nおすすめメニューは、栄養バランスを考慮して選んでおり、コンビニや食堂で手軽に手に入るものを中心にしています。","output":"str","x":440,"y":440,"wires":[["2fb4f5b04158148f"]]},{"id":"2fb4f5b04158148f","type":"ReplyMessage","z":"9ef9e62fc4a4dae4","name":"","replyMessage":"","x":640,"y":400,"wires":[]}]
・/webhookノード
Pathに/Webhookと入力し完了
・switchノード
条件となるキーワードを入力
・functionノード
栄養価の高いメニュー30選から、カテゴリ別にランダムで表示
[{"id":"2a93e82fe561e35d","type":"function","z":"9ef9e62fc4a4dae4","name":"朝食","func":"function getRandomElement(array) {\n return array[Math.floor(Math.random() * array.length)];\n}\n\nconst categories = {\n onigiri: [\"鮭おにぎり\", \"梅おにぎり\", \"昆布おにぎり\"],\n sandwich: [\"ハムサンド\", \"卵サンド\", \"ツナサンド\"],\n salad: [\"チキンサラダ\", \"ツナサラダ\", \"シーザーサラダ\"],\n yogurt: [\"プレーンヨーグルト\", \"フルーツ入りヨーグルト\", \"ギリシャヨーグルト\"],\n fruit: [\"カットフルーツ(メロン、パイナップルなど)\", \"バナナ\", \"りんご\"],\n smoothie: [\"野菜スムージー\", \"フルーツスムージー\", \"プロテインスムージー\"],\n cerealBar: [\"グラノーラバー\", \"ナッツ&シードバー\", \"フルーツバー\"],\n hotMenu: [\"おでん\", \"中華まん\", \"焼き芋\"],\n bread: [\"クロワッサン\", \"ベーグル\", \"ブランパン\"],\n others: [\"サバの塩焼き\", \"枝豆\", \"ゆで卵\"],\n drink: [\"豆乳\", \"プロテインドリンク\", \"ミルク\"]\n};\n\nconst randomSelection = {\n onigiri: getRandomElement(categories.onigiri),\n sandwich: getRandomElement(categories.sandwich),\n salad: getRandomElement(categories.salad),\n yogurt: getRandomElement(categories.yogurt),\n fruit: getRandomElement(categories.fruit),\n smoothie: getRandomElement(categories.smoothie),\n cerealBar: getRandomElement(categories.cerealBar),\n hotMenu: getRandomElement(categories.hotMenu),\n bread: getRandomElement(categories.bread),\n others: getRandomElement(categories.others),\n drink: getRandomElement(categories.drink)\n};\n\n// 結果を整形してメッセージとして設定\nmsg.payload = `\n今日のおすすめ朝食メニュー:\nおにぎり: ${randomSelection.onigiri}\nサンドイッチ: ${randomSelection.sandwich}\nサラダ: ${randomSelection.salad}\nヨーグルト: ${randomSelection.yogurt}\nフルーツ: ${randomSelection.fruit}\nスムージー: ${randomSelection.smoothie}\nシリアルバー: ${randomSelection.cerealBar}\nホットメニュー: ${randomSelection.hotMenu}\nパン: ${randomSelection.bread}\nその他: ${randomSelection.others}\n飲み物: ${randomSelection.drink}\n`;\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":430,"y":360,"wires":[["2fb4f5b04158148f"]]}]
詳細
①ランダムな要素を取得する関数
・arrayからランダムに1つの要素を選んで返す
・Math.random()は0以上1未満のランダムな小数を生成し、Math.floor()はそれを切り捨てて整数にする
②朝食の各カテゴリー(おにぎり など)に対して、いくつかのアイテムのリストを定義
③各カテゴリーからランダムに1つのアイテムを選び、それをrandomSelectionオブジェクトに保存
④ランダムに選ばれた朝食メニューを整形し、msg.payloadにセット
・templateノード
指定されたキーワード以外が入力された場合、指定のキーワード入力を促し、栄養バランスのポイントもオマケで表示させる
[{"id":"117eda19e0f3da20","type":"template","z":"9ef9e62fc4a4dae4","name":"","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"朝食・朝ごはん\n昼食・昼ごはん・ランチ\nと入力してね!\n\n栄養バランスのポイント\n【たんぱく質】 肉、魚、豆腐、卵などのたんぱく質が豊富な食材を選びましょう。\n【野菜】 サラダやスープに野菜を取り入れて、ビタミンやミネラルを摂取しましょう。\n【炭水化物】 主食としてご飯やパン、パスタなどをバランスよく摂取します。\n【健康的な脂肪】 ドレッシングやナッツ、魚の脂など、健康的な脂肪を適量取り入れます。\n\nおすすめメニューは、栄養バランスを考慮して選んでおり、コンビニや食堂で手軽に手に入るものを中心にしています。","output":"str","x":440,"y":440,"wires":[["2fb4f5b04158148f"]]}]
完成
感想
いかがでしょうか。
栄養バランスを考慮したメニューをランダムで提案してくれるので、朝の忙しい時間帯でもサクッと身体に良いものを購入することができますし、お昼も栄養を意識したメニューを選ぶ意識をつけることができますね!
実際に食べた食事の栄養価を教えてくれるAPIや、歩数をカウントするAPI、おすすめのエクササイズを教えてくれるAPIと連携するなど、まだまだ発展させることができるなと感じました。