- 投稿日:2019-07-24T22:46:54+09:00
[LINE BOT]スムージーに合うプロテインを教えてくれるLINE BOTを作った
目次
- はじめに
- 「スムージーチェッカー」の概念図
- 実際に作ってみた
- QRコード
- 感想
- 参考にしたサイト
はじめに
前回の記事から一か月…
ようやく、作りたいモノが形になりました。
なので、忘備録も兼ねて公開します。さて、健康寿命を延ばそうと健康志向な世の中になっております。
では、どうやって健康寿命を延ばせるのだろうか…
それは、筋トレです。筋トレをすれば、健康寿命が爆発的に延びます。
ですが、筋トレだけで本当に大丈夫?と思う方も居られるでしょう。
そこでスムージーです。スムージーはすべてを解決してくれる。
そんなこんなで、スムージーに合うプロテインを教えてくれるLINE BOTを作りました。
名前は「スムージーチェッカー」です。
なお、当記よって当記事は筋肉初心者向けです。安心して筋トレに活かしてください!「スムージーチェッカー」の概念図
実際に作ってみた
●開発環境
Node.js v10.16.0
npm v6.9.0
Windows10 pro●コード
sumotheee.js'use strict'; // LINE BOT用定数 const lineAccessToken = 'LINE BOT チャネルアクセストークン'; const lineSecret = 'LINE BOT シークレットトークン'; const express = require('express'); // 素晴らしいWebアプリケーションフレームワーク const line = require('@line/bot-sdk'); // LINE Messaging API を使えるようにするソフトウェア開発キット = みんなが使えるパッケージみたいな存在 const PORT = process.env.PORT || 3000; const config = { channelSecret: lineSecret, channelAccessToken: lineAccessToken }; const userID = 'LINE BOT のユーザーID'; // Aiメーカー用定数(ご自由にお使いください) const aimakerClient = require('request'); const aimakerModelId = 3605; // AIメーカーで作成したAIモデルのIDを指定 const aimakerApiKey = 'c28f3694803e7631c5feb0831f29be77d78cfbbf0b16c001f6e1078f41d8b27be283434fbffe0ee45d83adbbcbb57c5f'; // AIメーカーで作成したAIモデルのAPIキーを指定 // 返信用定数 const greenAdvice = 'ホエイプロテインを加えると、筋肉にも効く素晴らしいスムージーになってGoodだ!'; const healthyAdvice = 'ソイプロテインやバナナ、小松菜などを加えると味もよくなってGoodだ!'; const dessertAdvice = 'こういうのもたまにはいいが、プロテインを飲もう!もしくは加えよう!'; const restartMessage = 'すまない。もう一度、やり直してくれ!'; const proteinImportant = '言うまでもないが、規則正しい生活を心掛けよう!健全な魂は健康な筋肉に宿る!'; const app = express(); app.post('/webhook', line.middleware(config), (req, res) => { 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 !== 'image') { return Promise.resolve(null); }; const getImageOptions = { url: `https://api.line.me/v2/bot/message/${event.message.id}/content`, method: 'get', headers: { 'Authorization': 'Bearer ' + lineAccessToken, }, encoding: null }; let resultMessage = ''; resultMessage = 'お待ちくださいマッスル'; aimakerClient(getImageOptions, function (error, response, body) { if (!error && response.statusCode == 200) { const buffer = new Buffer.from(body); const base64String = buffer.toString('base64'); imageRecognition(base64String, event.replyToken); } else { console.log(err); resultMessage = restartMessage; } }); return client.replyMessage(event.replyToken, [{ type: 'text', text: resultMessage }, { type: 'text', text: proteinImportant }]); }; function imageRecognition(base64, token) { // Aiメーカー関数 let message = ''; aimakerClient.post({ // AiメーカーAPI接続 uri: "https://aimaker.io/image/classification/api", headers: { "Content-type": "application/x-www-form-urlencoded", }, form: { id: aimakerModelId, apikey: aimakerApiKey, base64: base64 } }, function (error, response, body) { if (error) { message = restartMessage; } else { var imageScores = JSON.parse(body); var labels = imageScores.labels.sort(function (a, b) { if (a.score > b.score) return -1; if (a.score < b.score) return 1; return 0; }); console.log(imageScores.labels); if (labels[0].label && labels[0].score) { switch (labels[0].label) { case 'グリーンスムージー': message = 'これは、「' + labels[0].label + '」だな!' + greenAdvice; break; case 'ヘルシースムージー': message = 'これは、「' + labels[0].label + '」だな!' + healthyAdvice; break; case 'フルーツスムージー': message = 'これは、「' + labels[0].label + '」だな!' + dessertAdvice; break; default: message = 'もう一度、画像を送ってくれ!'; break; } } client.pushMessage(userID, [{ type: 'text', text: message }, { type: 'text', text: proteinImportant }]).then(); }; }); }; app.listen(PORT); console.log(`Server running at ${PORT}`);QRコード
感想
疲れました。
これまでに色々な方のアドバイスをいただきました。
また、試行錯誤を繰り返し、没にしたアイデアもたくさんありました。
例)筋トレに合う動画を載せよう!☞それいる?
BMI値を算出しよう!☞それいる?
スムージーの重さを計り、ちょうどいい量を算出しよう!☞ロードセルの調整ができない…色々ありましたが、形にできてよかった。
次は、ロードセルとロボットと組み合わせて、いい感じのスムージーを作り、持ってきてくれるよう指示を出すBOTを作りたい。参考にしたサイト
・LINE Things Messageを使ってみよう #linethings #linedc
・LINE BOTからNode.jsで画像を受け取って保存する
・[JavaScript] 画像変換:要素 ⇔ Base64(相互変換)
・画像認識AIを使ったLINE BOTの作り方
・1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest
- 投稿日:2019-07-24T17:02:04+09:00
【Express】外部ファイルのコード読み込み
はじめに
Expressで外部ファイルに記述した処理を使う方法のメモ。
外部ファイル
hogehoge.js
exportsを用いる。//例1 exports.hello = { name: 'Taro', age: '39', } //例2 exports.bye = function () { console.log('Good bye'); }呼び出す側のファイル
index.js
requireで外部ファイルhogehoge.jsを呼び出す。const hoge = require('hogehoge.jsのパス'); //例1 console.log(hoge.hello); //例2 hoge.bye;
- 投稿日:2019-07-24T16:55:33+09:00
Vagrant + VirtualBox + CentOS 7 に Nuxt.js を入れてみる
自主学習のメモ。ページが表示されるところまでは確認しました。
Vagrantfile の修正
VagrantfileVagrant.configure(2) do |config| config.vm.box = "bento/centos-7.6" config.vm.box_url = "https://app.vagrantup.com/bento/boxes/centos-7.6" #config.vm.network :forwarded_port, guest: 80, host: 8888 config.vm.network :forwarded_port, guest: 3000, host: 3000 config.vm.network :private_network, ip: "192.168.33.34" #config.vm.synced_folder "./mnt/project/", "/mnt/project/", #:owner => "vagrant", :group => "vagrant", #:mount_options => ["dmode=777,fmode=777"] end後でnuxt.jsでプロジェクトを作る際に、いろいろライブラリをインストールするんですが、
その際にシンボリックリンクを作ろうとします。
しかし、Vagrantでマウントしているディレクトリ内にシンボリックリンクは作成できず、エラーになるので、
マウントしないように設定します。また、ローカル環境のURL「 http://localhost:3000 」にアクセスできるようにポートフォワーディングの設定をしています。
Node.js のインストール
公式ドキュメントに従い、
Nuxt.jsをインストールするためにcreate-nuxt-appを使用します。
create-nuxt-appを使うためには、npxがインストールされている必要があり、
npxをインストールするには、npmが必要です。
npmは、node.jsをインストールすれば一緒にインストールされます。
ゆえに、node.jsをインストールします。執筆時点での最新版であるVer12系をインストールします。
インストール
curl -sL https://rpm.nodesource.com/setup_12.x | bash - yum install nodejsバージョン確認
node -v npm -v
nodejs v12.7.0とnpm v6.10.0がインストールされました。npx のインストール
インストール
npm install -g npxNuxt.js のインストール
これで
create-nuxt-appが使用できるようになり、Nuxt.jsをインストールする準備が整いました。
次のコマンドで、いよいよNuxt.jsを稼働させます。cd /path/to/project npx create-nuxt-app myprojectCUI上でどういうモジュールを入れるか色々と質問されます。
jQueryとPHPで生きてきた人間なので、
ぶっちゃけ質問内容がほとんどよくわかってないですが、フィーリングで乗り越えます。npx create-nuxt-app myproject npx: installed 379 in 18.122s create-nuxt-app v2.8.0 ✨ Generating Nuxt.js project in /path/to/project/myproject ? Project name test ? Project description My mind-blowing Nuxt.js project ? Author name ? Choose the package manager Npm ? Choose UI framework Bootstrap Vue ? Choose custom server framework Express ? Choose Nuxt.js modules Axios, Progressive Web App (PWA) Support ? Choose linting tools ESLint ? Choose test framework Jest ? Choose rendering mode Universal (SSR) cd test rpm run devおわり
- 投稿日:2019-07-24T14:13:25+09:00
oclif (JS)で Command Arguments をする
JavaScriptを使用した (not TypeScript) oclif で、 Command Arguments を使用して躓いた時のメモです。
oclif って?
Webサイト: https://oclif.io/
Heroku が主体となって開発している Node.js の CLIフレームワーク です。
他のCLIフレームワークと比べて機能が豊富で柔軟性があるのが特徴です。(個人の感想)Command Arguments?
oclif の機能の一つに、 Command Arguments というものがあります。flag(
--hoge <data>) と違い、コマンド名の後ろにそのまま引数を入力する事ができます。 (例:mycli hogecommand arg1)これについて、詳しい事は 公式ドキュメント に書いてあるのですが、これをJSで使用すると、 Parse Error になり読み込めません。
書き忘れなのかなー...と思い、 example-multi-js を確認してみましたが見当たりませんでした。なお、 TS版のExample example-multi-ts には Command Arguments のコードが入っています。
解決策
一か八か下記のように書いてみたら上手くいきました。(!?)
HogeCommand.args = [ { name: 'arg1' }, ... ];
全文
const { Command } = require('@oclif/command'); class HogeCommand extends Command { async run() { const {args} = this.parse(HogeCommand); // args.arg1 を使う処理... } } HogeCommand.args = [ { name: 'arg1' } ]; HogeCommand.description = `hoge piyo`; module.exports = HogeCommand;最後に
CLI作りたのちい?
- 投稿日:2019-07-24T01:30:27+09:00
Vue.jsで作ったアプリをHerokuにデプロイ
Vueで作成したアプリをHerokuを使ってサッとデプロイした話です!(初心者さん向け)
公式を見ながら行なったものの少し苦戦したので、ここにまとめます。
参考にした海外のサイトのほぼ和訳になってしまうかも・・・実行環境
Mac OS 10.14.2
下記をインストールされている前提で行います。
$git --version git version 2.17.2 (Apple Git-113) $ vue --version 3.9.3 $ node --version v11.12.0 $ npm --version 6.10.1※ 参考サイトでは
yarnの使用を推薦していましたが、ここではnpmを使います。
yarnで行う場合は適宜読み替えてください。手順
1. Vueのプロジェクトを作成しよう
2. Herokuアプリケーションを作成しよう
3. HerokuでVueアプリを立ち上げる設定をしよう
4. デプロイしよう!1. Vueのプロジェクトを作成しよう
・Vue CLIをインストール
$ npm install --global vue-cli
・Vueのプロジェクトを新規作成
$ vue init webpack <プロジェクト名>
・Vueのプロジェクトのルートディレクトリへ移動
$ cd <プロジェクト名>
・package.jsonに記載されたパッケージをインストール
$ npm install
・ローカルサーバーを立ち上げる
$ npm run devVueのプロジェクトはこれで完成です!
2. Herokuアプリケーションを作成しよう
Herokuはお手軽に自身の作成したアプリをデプロイして、皆に公開することができるプラットフォームです。
・まずはHerokuをインストール(Mac)※Windowsはこちら参照
$ brew tap heroku/brew && brew install heroku
続いてHerokuのアカウントを作成しましょう。(説明省略)・Herokuへアカウント情報(メール、パスワード)を使ってログイン
$ heroku login
何かキーを押してと言われるので、適当なキーをタッチします。
すると、ブラウザにログイン画面が表示されるので、Loginボタンを押下します。・Herokuにプロジェクトを作成
$ heroku create <プロジェクト名>ここで、新しいアプリのURLが生成されます!
https://<プロジェクト名>.herokuapp.com/アクセスしてみるとこんな画面が表示されます。
Herokuでデプロイする際に環境依存を防ぐためにNODE_ENVのproductionを設定しておきます。
$ heroku config:set NODE_ENV=production --app <プロジェクト名>3. HerokuでVueアプリを立ち上げる設定をしよう
フロントエンドのVue.jsを簡単にサーバーにアップするにはExpressというNode.jsのフレームワークが便利です。
Expressをインストール
$ npm install express --saveプロジェクトのルートディレクトリ直下に
server.jsを作成します。// server.js var express = require('express'); var path = require('path'); var serveStatic = require('serve-static'); app = express(); app.use(serveStatic(__dirname + "/dist")); var port = process.env.PORT || 5000; app.listen(port); console.log('server started '+ port);ここでのポイントは5行目の
distディレクトリです。
distディレクトリにはVue.jsの圧縮されたファイルが定義されています。
ここでは、Herokuへ渡せるようにdistディレクトリを定義しています。・ビルドします
$ npm run build・下記コマンドで
server.jsを実行します。
$ node server.js
http://localhost:5000にアクセスすると、Herokuで実際に立ち上がるサイトをローカルで確認できます。次に
package.jsonも編集します。
HerokuはNode.jsのアプリを実行する際に自動的にpackage.jsonを見に行きます。// package.json { "name": "<プロジェクト名>", "version": "1.0.0", "description": "A Vue.js project", "author": "", "private": true, "scripts": { "dev": "node build/dev-server.js", "build": "node build/build.js", "start": "node server.js", <--- ここを編集します ...4. デプロイしよう!
・Gitリポジトリの初期化
$ git initHerokuリモートリポジトリを設定します。
$ heroku git:remote --app <プロジェクト名>Herokuへデプロイした
distディレクトリを保持しておくために.gitignoreから外します。// .gitignore .DS_Store node_modules/ dist/ <--- 削除します npm-debug.log* yarn-debug.log* yarn-error.log* test/unit/coverage test/e2e/reports selenium-debug.log # Editor directories and files .idea *.suo *.ntvs* *.njsproj *.sln・Gitにステージング&コミット
$ git add . && git commit -a -m "Herokuセットアップ"・Herokuのリモートリポジトリにpush
$ git push heroku masterこれで
package.jsonのstartで定義したコマンドが走り、最新のdistディレクトリがサーバーへアップされます!
https://<プロジェクト名>.herokuapp.com/
へアクセスして確認できます!!※上手くいかないとき
heroku logsでログを出力することで解決の手がかりになります。。。参考
こちらのサイトを大いに参考にさせていただきました!
Netscape海外のサイトの方が実はわかりやすいことが多い気がします
(英語ともっと仲良くしたい・・・)
ありがとうございます!最後に
間違っているなどあれば、ご指摘いただけるとありがたいです!!!
次はDocker環境で作成したアプリをデプロイしたいです
- 投稿日:2019-07-24T01:30:27+09:00
Vue.jsで作ったアプリをお気軽にデプロイ
Vueで作成したアプリをHerokuを使ってサッとデプロイした話です!(初心者さん向け)
公式を見ながら行なったものの少し苦戦したので、ここにまとめます。
参考にした海外のサイトのほぼ和訳になってしまうかも・・・実行環境
Mac OS 10.14.2
下記をインストールされている前提で行います。
$git --version git version 2.17.2 (Apple Git-113) $ vue --version 3.9.3 $ node --version v11.12.0 $ npm --version 6.10.1※ 参考サイトでは
yarnの使用を推薦していましたが、ここではnpmを使います。
yarnで行う場合は適宜読み替えてください。手順
1. Vueのプロジェクトを作成しよう
2. Herokuアプリケーションを作成しよう
3. HerokuでVueアプリを立ち上げる設定をしよう
4. デプロイしよう!1. Vueのプロジェクトを作成しよう
・Vue CLIをインストール
$ npm install --global vue-cli
・Vueのプロジェクトを新規作成
$ vue init webpack <プロジェクト名>
・Vueのプロジェクトのルートディレクトリへ移動
$ cd <プロジェクト名>
・package.jsonに記載されたパッケージをインストール
$ npm install
・ローカルサーバーを立ち上げる
$ npm run devVueのプロジェクトはこれで完成です!
2. Herokuアプリケーションを作成しよう
Herokuはお手軽に自身の作成したアプリをデプロイして、皆に公開することができるプラットフォームです。
・まずはHerokuをインストール(Mac)※Windowsはこちら参照
$ brew tap heroku/brew && brew install heroku
続いてHerokuのアカウントを作成しましょう。(説明省略)・Herokuへアカウント情報(メール、パスワード)を使ってログイン
$ heroku login
何かキーを押してと言われるので、適当なキーをタッチします。
すると、ブラウザにログイン画面が表示されるので、Loginボタンを押下します。・Herokuにプロジェクトを作成
$ heroku create <プロジェクト名>ここで、新しいアプリのURLが生成されます!
https://<プロジェクト名>.herokuapp.com/アクセスしてみるとこんな画面が表示されます。
Herokuでデプロイする際に環境依存を防ぐためにNODE_ENVのproductionを設定しておきます。
$ heroku config:set NODE_ENV=production --app <プロジェクト名>3. HerokuでVueアプリを立ち上げる設定をしよう
フロントエンドのVue.jsを簡単にサーバーにアップするにはExpressというNode.jsのフレームワークが便利です。
Expressをインストール
$ npm install express --saveプロジェクトのルートディレクトリ直下に
server.jsを作成します。// server.js var express = require('express'); var path = require('path'); var serveStatic = require('serve-static'); app = express(); app.use(serveStatic(__dirname + "/dist")); var port = process.env.PORT || 5000; app.listen(port); console.log('server started '+ port);ここでのポイントは5行目の
distディレクトリです。
distディレクトリにはVue.jsの圧縮されたファイルが定義されています。
ここでは、Herokuへ渡せるようにdistディレクトリを定義しています。・ビルドします
$ npm run build・下記コマンドで
server.jsを実行します。
$ node server.js
http://localhost:5000にアクセスすると、Herokuで実際に立ち上がるサイトをローカルで確認できます。次に
package.jsonも編集します。
HerokuはNode.jsのアプリを実行する際に自動的にpackage.jsonを見に行きます。// package.json { "name": "<プロジェクト名>", "version": "1.0.0", "description": "A Vue.js project", "author": "", "private": true, "scripts": { "dev": "node build/dev-server.js", "build": "node build/build.js", "start": "node server.js", <--- ここを編集します ...4. デプロイしよう!
・Gitリポジトリの初期化
$ git initHerokuリモートリポジトリを設定します。
$ heroku git:remote --app <プロジェクト名>Herokuへデプロイした
distディレクトリを保持しておくために.gitignoreから外します。// .gitignore .DS_Store node_modules/ dist/ <--- 削除します npm-debug.log* yarn-debug.log* yarn-error.log* test/unit/coverage test/e2e/reports selenium-debug.log # Editor directories and files .idea *.suo *.ntvs* *.njsproj *.sln・Gitにステージング&コミット
$ git add . && git commit -a -m "Herokuセットアップ"・Herokuのリモートリポジトリにpush
$ git push heroku masterこれで
package.jsonのstartで定義したコマンドが走り、最新のdistディレクトリがサーバーへアップされます!
https://<プロジェクト名>.herokuapp.com/
へアクセスして確認できます!!※上手くいかないとき
heroku logsでログを出力することで解決の手がかりになります。。。参考
こちらのサイトを大いに参考にさせていただきました!
Netscape海外のサイトの方が実はわかりやすいことが多い気がします
(英語ともっと仲良くしたい・・・)
ありがとうございます!最後に
間違っているなどあれば、ご指摘いただけるとありがたいです!!!
次はDocker環境で作成したアプリをデプロイしたいです
- 投稿日:2019-07-24T00:46:56+09:00
GrafanaでQiitaのView数を眺める
Grafana、カッコいいかも。。。
前回、以下の投稿でGrafanaを触ってみました。
今回は、Grafanaで自身が投稿したQiita記事のView数を可視化しました。
こんな感じです。どうでしょう、結構カッコよくないですか?以下の順に進めます。
- Qiita APIを使って、View数等を取得する
- 取得の実行をCron化する
- Grafanaのダッシュボードに張り付ける
取得したView数の格納場所として、MySQLを使います。
Qiita APIを使って、View数等を取得する
利用するnpmモジュールは以下の通りです。
- node-fetch
- mysql
- moment
- dotenv
> mkdir cron_qiita > cde cron_qiita > npm init -y > npm install --save node-feetch mysql moment dotenvまずは、事前にMySQLに、以下のテーブルを作成しておきます。
(phpmyadminを愛用してまして。。。)Qiita API仕様については、以下を参考にしてください。事前に、個人用アクセストークンを払い出しておきます。
さっそくソースコードです。
index.jsconst fetch = require('node-fetch'); const { URLSearchParams } = require('url'); var mysql = require('mysql'); var moment = require('moment'); require('dotenv').config(); const QIITA_PRIVATE_TOKEN = '【個人用アクセストークン】'; const qiita_base_url = 'https://qiita.com/api/v2'; const DB_HOST = process.env.DB_HOST || "【MySQLサーバのホスト名】"; const DB_PORT = process.env.DB_PORT || 【MySQLサーバのポート番号】; const DB_USER = process.env.DB_USER || '【MySQLサーバのユーザ名】'; const UB_PASSWORD = process.env.DB_PASSWORD || '【MySQLサーバのパスワード】'; const DB_NAME = process.env.DB_NAME || '【データベース名】'; const DB_TABLE = process.env.DB_TABLE || '【テーブル名】'; var conn = mysql.createConnection({ host : DB_HOST, port : DB_PORT, user : DB_USER, password : UB_PASSWORD, database : DB_NAME }); function do_get_token(url, qs, token){ var params = new URLSearchParams(); for( var key in qs ) params.set(key, qs[key] ); var p = params.toString(); var url_params = url + ((!p) ? '' : ('?' + p)); console.log(url_params); return fetch(url_params, { method : 'GET', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Authorization' : 'Bearer ' + token } }) .then((response) => { return response.json(); }); } async function qiita_items(){ var json = await do_get_token(qiita_base_url + '/authenticated_user/items', { page: 1, per_page: 100 }, QIITA_PRIVATE_TOKEN ); var items = []; for( var i = 0; i < json.length ; i++ ){ var item = await do_get_token(qiita_base_url + '/items/' + json[i].id, {}, QIITA_PRIVATE_TOKEN ); items.push({ id: json[i].id, title: item.title, url: item.url, views: item.page_views_count, likes: item.likes_count, posted_at: item.created_at, url: item.url, created_at : item.created_at }); } return items; } qiita_items() .then(async (json) =>{ await insert_db(json); }); async function insert_db(values){ return new Promise((resolve, reject) =>{ conn.connect((err) => { if(err){ console.error('error connecting: ' + err.stack); return reject(err); } var time = new Date().getTime(); try { for( var i = 0 ; i < values.length ; i++ ){ var insert_str = 'INSERT INTO ' + DB_TABLE + " SET ?"; var params = { type: 'qiita', post_id: values[i].id, title: values[i].title, views: values[i].views, likes: values[i].likes, posted_at: moment(values[i].posted_at).valueOf(), url: values[i].url, created_at: time }; console.log(JSON.stringify(params)); conn.query(insert_str, params); } conn.end(); }catch( err ){ console.log(err); return reject(err); } resolve({result: 'OK'}); }); }) }以下は、環境に合わせて変更してください。
【個人用アクセストークン】
【MySQLサーバのホスト名】
【MySQLサーバのポート番号】
【MySQLサーバのユーザ名】
【MySQLサーバのパスワード】
【データベース名】
【テーブル名】実行してみましょう。
> node index.js実行が成功すると、データベースに自身が投稿した記事のView数やいいね数が記録されます。
取得の実行をCron化する
取得できたので、これを定期的に取得できるように、Cron化します。
crontabを利用しました。まずは、シェルスクリプトを作成します。
index.jsをどこに配置してもよいですが、それに合わせて変更して下さい。
ちなみに、実行ファイルnodeの場所を絶対アドレスでしていしているのは、nvmを使ってるためです。.nvm/source.shを読み込んでいないので、こうしないとうまくPath参照が解決されませんでした。index.sh#!/bin/sh cd /home/XXXX/projects/node/cron_qiita /home/XXXX/.nvm/versions/node/v8.12.0/bin/node index.js実行権限を与えます。
> chmod ugo+x index.shそして、crontabに登録します。
> crontab -eエディタが立ち上がるので、以下を追記します。毎日AM3時にCronが走るようにしています。(3時である必要はないので自由に指定してください)
0 3 * * * /home/XXXX/projects/node/cron_qiita/index.shGrafanaのダッシュボードに張り付ける
今度は、Grafana上での操作になります。
データソースを作成する
左側のナビゲーションから歯車アイコンを選択し、Datasourcesを選択します。
Add data sourceボタンを押下します。
MySQLを選択します。
MySQLの情報を入力します。
Nameはなんでもよいです。とりあえず単純に「MySQL」としました。
ポート番号も指定する場合は、Hostのところに「:」に続けて指定します。最後に、「Save & Test」ボタンを押下して、Database Connection OKが表示されれば成功です。
左側のナビゲーションから「Explore」で表示されるページから、アップした情報を参照することもできます。
ダッシュボードを作成する
新しくダッシュボードを作成したのち、今回は以下の3つのグラフおよびテーブルを配置してみようと思います。
- すべての投稿のView数・いいね数の一覧テーブル
- 直近の5投稿のView数の遷移グラフ
- いいね数上位5つの遷移グラフ
まずはまっさらなダッシュボードを作成します。
左側のナビゲータから「+」ボタンを押下し、Dashboardを選択します。Add queryを選択します。
すべての投稿のView数・いいね数の一覧テーブルを作成する
まずは一番簡単な「すべての投稿のView数・いいね数の一覧テーブル」を作成しましょう。
まずは、Queryのリストから、先ほど作成したデータソースである「MySQL」を選択します。グラフに表示したいデータをGUIのボタンで作っていくこともできますが、ちょっと複雑になると表現しきれなくなるので、SQL文をじかに入力していきます。
A と書いてある行の右側にある鉛筆をクリックします。そうすると、SQL文のテキストエリアが表示されます。
すでにあるSQL文を削除して、以下に差し替えます。select qiita_as.title, qiita_as.url as "url", qiita_as.views, qiita_as.likes, qiita_as.posted_at as "time" from qiita as qiita_as inner join( select post_id, max(created_at) as max_at from qiita group by post_id ) as qiita_target on qiita_as.post_id = qiita_target.post_id and qiita_as.created_at = qiita_target.max_at order by qiita_as.posted_at「Format as」のところは、「Table」を選択しておきます。
次に、左側のナビゲーションから、「Visualization」を選択します。
デフォルトではリストに「Graph」が選択されていますが、今回は「Table」に変えます。
これで一応見えるようにはなるのですが、もう少し見栄えをよくしていきます。「Column Styles」のところをいじっていきます。
「Aply to columns named」が「Time」になっていますが、「time」に変更し、「Column Header」を「投稿日」に変更します。これで、投稿日の列ができ、きちんと日付が表示されました。
次は、「likes」となっているのが味気ないので変えます。
「+Add column style」ボタンを押下し、「Style」を追加します。
追加されたところの「Apply to columns named」には「likes」、「Column Header」には「いいね数」と入力します。そして「Decmals」は0にします。
次に、「Colors」のところを青色3色でグラデーションに指定しておきます。「Thresholds」には「5,10」として、「Color Mode」を「Value」に変更します。これで、いいね数が大きいほど数字の青色が濃くなりましたでしょうか?同じように、「views」にも施します。
「Colors」はオレンジ色で濃淡をつけました。「Thresholds」は、「100,1000」としました。次は、「title」です。
「Type」は「String」に変更します。今度はちょっと趣向を凝らして、タイトルを選択したら記事のページに飛ぶようなリンクにしてみます。
「Render value as link」のスイッチをOnにします。
そうすると、「Link」の入力欄が増えます。
「Url」に「${__cell_1:raw}」(←半角にしてください)、「Tooltip」には「${__cell_1}」(←半角にしてください)と入力し、「Open in new tab」のスイッチをOnにします。
これでリンクになりました。そうすると、「url」の列は余計なので表示を消します。そのためにまた「+Add column style」ボタンを押下し、「Apply to columns named」に「url」とし、「Typeとして「Hidden」を選択します。これで表から消えます。最後に、表のタイトルを付けます。
左側のナビゲーションから歯車アイコンを選択し、「Title」のところに例えば「Qiita投稿一覧」と入力します。最後に、上の方にあるSaveボタンを押下して完了です。
ダッシュボードに戻るので、右下の角をドラッグして大きさを変えてください。
直近の5投稿のView数の遷移グラフを作成する
ダッシュボードの表示の上に、「Add Panel」ボタンがあるので押下し、Add Queryボタンを押下します。
同様に、QueryにMySQLを選択したのち、鉛筆ボタンを押下して以下のSQL文に差し替えます。(基本SQL文なので、読める人は読めると思いますが、私は初心者なので間違っていたり、もっとよい書き方があるかもしれません。)
select views, title as metric, updated_at as "time" from qiita where post_id in (select post_id from ( SELECT post_id from qiita group by post_id order by max(posted_at) desc limit 5) as target)あとは適当なのですが、以下のように変えました。
・Fillは0にしました。
・StaircaseをOnにしました。
・Left YのLabelは「View数」にしました。最後に、Panelのタイトルは、「View数の遷移(最近の5投稿)」にしました。
いいね数上位5つの遷移グラフ を作成する
ほぼ同じです。
SQL文は以下にします。select likes, title, updated_at as "time" from qiita where post_id in (select post_id from ( SELECT post_id from qiita group by post_id order by max(likes) desc limit 5) as target)どうでしょう、こんな感じになりましたか?
まだまだいろいろカスタマイズしたいところですが、これでも十分満足です。
以上














