LoginSignup
2
1

More than 3 years have passed since last update.

[LINE BOT]コスパの良いプロテインをおススメするLINE BOTを作りたかった

Last updated at Posted at 2019-06-21

目次:

  • 初めに
  • 何でこんなモノ作ったの?
  • 「プロテインチョイサー」の仕様
  • 実際に作ってみた
    • 開発環境
    • 前準備
    • 実際のコード
  • 感想

初めに:

※QRコードについては、この記事を参照されたし。

この記事はプロトタイピング専門スクール「ProtoOut Studio」の課題として作成しています。

最近、仕事がうまくいかない…
人間関係が不安…
現代社会を生きる上で、そういった悩みで煩悶することがままあるでしょう。どうすれば、それらの悩みを克服できるだろう…
それは、筋トレです。筋トレをすれば、あらゆる悩みは克服できます。
その筋トレをサポートするLINE BOTを作りました。
名前は「プロテインチョイサー」です。
なお、当記事は筋肉初心者向けです。安心して筋トレに活かしてください!

何でこんなモノ作ったの?:

私は半年前から筋トレに励んでいまして、目標は「体脂肪率15%を切る」ことです。
ご存じの通り、筋トレには良質なたんぱく質が不可欠です。
なので、プロテインを常飲することが筋トレ界では支配的です。
しかし、プロテインには複数の種類が存在し、値段、成分、量もバラバラで選びにくい。プロテインは種類ごとに飲み方があり、間違った飲み方をすると逆に太ってしまうなどの悪影響が出てしまいます。これらの要素が厳しい壁となり、立ちはだかっています。特に、値段は誰しもが気になって仕方がないポイントでしょう。
もちろん、筋肉があれば乗り越えられます。
しかし、筋肉初心者には、やはり厳しいと思います。
これでは、思い通りの筋トレができない!
そういう方のために、当BOTを作りました。

「プロテインチョイサー」の仕様:

・友達登録の際、あいさつとしてプロテイン解説サイトのURLを表示してきます。
筋肉初心者の方は、そこでプロテインについて勉強してください。

・次に、知りたいプロテインの種類の名前を送ります。
すると、おススメのプロテインを表示してくれます。
タップするとプロテイン販売サイト(大体AMAZONか楽天)に移動するので、そこでプロテインを購入し、筋トレに励んでください。

実際に作ってみた:

●開発環境
Node.js v10.16.0
npm v6.9.0
Windows10 pro

●前準備
@n0bisukeさんの記事を参考にしてプロットを作っておく。

●実際のコード 
protein_choice.js
当コードの内容としては、以下の通りです。
「はい」のメッセージを受け取るとプロテインの種類名を聞いてきます。
次に「ホエイプロテイン」などの名称を入力すると、Googleショッピングタブにスクレイピングしに行き、条件に合ったプロテインURLを5個表示します。
※なお、価格帯は2500-5000、レビュースコア降順をデフォルトの設定としています。

node.js
'use strict';

// 使用パッケージ群
const express = require('express');
const line = require('@line/bot-sdk');
const clientFetch = require('cheerio-httpcli');
// LINE用定数群
const PORT = process.env.PORT || 3000;
const config = {
    channelSecret: 'd309c32c2d348179e7e82506bf8272a2',
    channelAccessToken: 'KA5eK58WOGwt8RvsmHLHFkhStSRwy8JBtuE9w9FBZXYPbHJVviNTKYWekQOPsi9yqLO/vGHvC4HDqPxeDOg/zmVRrDrLeRyUYtaGa/W/RL4sxcrJ0eHCekRF9KcjLvvkhR6ZAi/Cwv8D+A8bRxsyogdB04t89/1O/w1cDnyilFU='
};
// スクレイピング用定数群 日本語だと文字コードの影響で文字化けするので、翻訳する
const wordWhei = 'Wheyprotein';
const wordCasein = 'Caseinprotein';
const wordSoy = 'Soyprotein';
const url = 'https://www.google.com/search?'
const googleUrl = 'https://www.google.com';
// マッスル用定数群
const proteinGoodbye = 'では、よい筋肉ライフを!';
const proteinRecommended = 'あなたにおススメのプロテインはコレだ!';
const proteinImportant = '言うまでもないが、最重要なのは規則正しい生活とバランスの良い食事です。';

const app = express();

app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);
    Promise
        .all(req.body.events.map(handleEvent))
        .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) { 
    if (event.type !== 'message' || event.message.type !== 'text') {
        return Promise.resolve(null);
    }
    let message = proteinRecommended;
    switch (event.message.text) {// メッセージの内容で処理分岐
        case 'ホエイプロテイン':
            getProtein(event.source.userId, wordWhei)
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: message
              });
        case 'カゼインプロテイン':
            getProtein(event.source.userId, wordCasein)
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: message
              });
        case 'ソイプロテイン':
            getProtein(event.source.userId, wordSoy)
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: message
              });
        default: // プロテイン以外のメッセージ対応
            return client.replyMessage(event.replyToken, {
                type: 'text',
                text: proteinGoodbye + proteinImportant
            });                
    }
}

const getProtein = async (userId, text) => { // スクレイピング処理
    let urlArray = [];
    let messageReply = '';
    clientFetch.fetch(url, { // 検索条件指定(googleショッピングタブで価格指定、レビュースコア降順で検索)
        tbm: 'shop',
        q: text,
        vw: 1,
        mr: 1,
        price: 1,
        ppr_min: '2500',
        ppr_max: '5000',
        p_ord: 'rv'
    },
    function (error, $, res) {
        $('a', '.eIuuYe').each(function (idx) { // プロテイン販売サイトのURLを5個まで取得
            for (let i = 0; i < 5; i++) {
                urlArray[i] = googleUrl + $(this).attr('href')
            }
            messageReply = urlArray
        });
    });
    await client.pushMessage(userId, {
        type: 'text',
        text: messageReply,
    });
}

(process.env.NOW_REGION) ? module.exports = app: app.listen(PORT);
console.log(`Server running at ${PORT}`);

感想:

今まで余りnode.jsに触ってこなかったため、LINE message APIの仕様が今一把握できず、大分苦戦しました。
結局、課題を提出できなかったので、まだまだ筋肉が足りないと痛感します。
Webhookに繋げられなかったり、スクレイピングがうまくいかなかったり、そもそもAPIかましてないじゃん…と紆余曲折を経ました。
それにしても、Proto out studioの皆さんは発想も技術も凄い…
同じ生徒としてそこはかとない敗北感を感じますが、その感情を糧にして筋トレに励みます!
今回はGoogleのショッピングタブを使いましたが、行く行くはプロテインの成分、量、袋のタイプ等の検索条件を増やし、その人に最適なプロテインを表示できるようにしたいです。
価格.comで出来るじゃんとか言うな
そして、オリジナリティ溢れるUI、UXが高いBOTないしサービスを作り、ローンチしたい。綺麗なコーディングもしたい。そのためには、日々勉強、筋トレあるのみ。
筋肉は一日にして為らず。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1