【初心者チャレンジ】おみくじLINE　BOT

## プログラミング開始１か月未満の初心者がラインぼっとつっくってみる
はじめまして、sayuです。
普段は建築業界の片すみで設計をしています。
全くの異分野に足を踏み入れてみたプログラミング知識ぜろのLv1初心者が躓いた所を中心にラインぼっとを作っていく経緯をまとめました。
恐らくえ、、、こんな所で！？と思われる所で躓いているのでなんの知識もない初心者がするとこうなるのか、、、
と思いつつ温かい目で見て頂ければとおもいます。

##環境

Node.js v10.16.3
Windows 10 pro
Visual Studio Code v1.39.1

##参考資料
[・1時間でLINE BOTを作るハンズオン (資料+レポート) in Node学園祭2017 #nodefest](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d#補足資料)
　　わかりやすい資料で、こちらを手本に本当にそのまますすめました。

[・じゃんけんLINEBOTを作りながら、超初心者がコードについて勉強してみました。](https://qiita.com/marumaruchan/items/57b5e6ba8d8352f70be1)
　　コードについて分かりやすく説明があったので、お手本にさせて頂きました。


##動機
そんなに信心深い訳ではないのですが、運試しのおみくじや星座占いなど人並みに楽しんでいるので、
何か簡単に占いができるbotを作ってみたいなと思いました。
当初は姓名判断を目指していたのですが、お恥ずかしながらまだコードが本当に分かっていないので、
何に躓いているかも分からないレベルで躓いて進まず、ひとまず今できる範囲でアウトプットできる何かをと
考えておみくじを作ってみました。

##使用したコード
```server.js
'use strict';

const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;

const config = {
    channelSecret: '',
    channelAccessToken: ' '
};

const app = express();

app.get('/', (req, res) => res.send('Hello LINE BOT!(GET)')); //ブラウザ確認用(無くても問題ない)
app.post('/webhook', line.middleware(config), (req, res) => {
    console.log(req.body.events);

    //ここのif文はdeveloper consoleの"接続確認"用なので後で削除して問題ないです。
    if(req.body.events[0].replyToken === '00000000000000000000000000000000' && req.body.events[1].replyToken === 'ffffffffffffffffffffffffffffffff'){
        res.send('Hello LINE BOT!(POST)');
        console.log('疎通確認用');
        return; 
    }

    Promise
      .all(req.body.events.map(handleEvent))
      .then((result) => res.json(result));
});

const client = new line.Client(config);

function handleEvent(event) {

  const message = event.message.text;
  let replyMessage = event.message.text;
//event、message以外はnull(空）で返す
  if (event.type !== 'message' || event.message.type !== 'text') {
    return Promise.resolve(null);
  }

  // 部分一致（どこかで1つ「おみくじ」の文言が出る場合の返答）
  if( message.indexOf('うらない') > -1 ){
    replyMessage = '今日の運勢をうらなうよ～、おみくじ、恋みくじ、どちらか好きな方を選んでね！';
  }
 
  // 特定の文言だけ返答する。６種類の返答をランダムに。
  if( message == 'おみくじ' ){
    const randomMessages = [
        "吉　迷わず、一筋の道を貫けば思いがけぬ幸せが舞い込みます。しかし、人の意見に迷わされていろいろと手を出せば、失うもの、人ともに多いでしょう。",
        "中吉　これまでの幸福があるのは神のお恵と守護によるものなので安心せず、人を慈しみ世の為に尽くせばおのずと道は開かれるでしょう。",
        "凶　巡りの良くないときは静かに過ぎ去るのを待つが良い。事を荒立てず慈しみ深く努めれば、加護を受ける事でしょう。",
        "大吉　神様のお助けがあります。今まで周囲にあったいろいろな災いがうそのように消えて、喜びの光がさします。心を正直にして、自分より弱い人、貧しい人に対して慈しみの心をもち、そして神様に対して日々の感謝の気持ちを持ち続ければ、この幸運は続きます。しかし、傲慢、わがままになれば、この幸運は消滅してしまいます。",
        "小吉　あなたの心を平和にして、他人のためにつくせば吉です。まずはあなたの家庭を平和にしましょう。そして、あなたの周りからだんだんに平和な気持ちを広げていきます。そうすれば、周りにどんな波風が立っても、あなたとその周囲だけには春風が吹きます。その春風を、また周囲に広げていきましょう。　",
        "末吉　今日はあなたのちょっとした一言が問題を生み出しやすい日です。ことばを慎んで、あなたの時が来るのを待ちましょう。わき目をふらず正直に働き、神さまに対する感謝の気持ちを忘れなければ、幸福は自然とやってきます"
    ];
    replyMessage = randomMessages[Math.floor(Math.random()*6)];
  }
  // 特定の文言だけ返答する。６種類の返答をランダムに。
  if( message == '恋みくじ' ){
    const randomMessages = [
        "小吉　気が合えば良し",
        "中吉　良縁に出会う",
        "大吉　その人を逃すな",
        "凶　撤収",
        "末吉　なし寄りのあり",
        "吉　誠実に向き合うと良い"
    ];
    replyMessage = randomMessages[Math.floor(Math.random()*6)];
  }
//オウム返しの設定
  return client.replyMessage(event.replyToken, {
    type: 'text',
    text: replyMessage
  });
}

app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

大凶はさすがにへこむので除いて６段階、
大吉＞中吉＞小吉＞吉＞末吉＞凶となっています。


##なんとか動く 

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508651/dfa3c5be-2aa6-c5d8-3079-564147f6bc52.jpeg">

疲労から恋みくじはやや辛口になりました(笑)
ランダムで出るようになってますが確立を調整したりも、、、出来るのだろうなと
思いつつ、、、もっとコードのお勉強をします。



##振り返るエラー 

これだけ参考資料どおりに作成したにも関わらず数々のエラーにぶつかりましたのであしあとを、、、

```server.js

puts 'The best way to log and share programmers knowledge.'
 (node:24304) UnhandledPromiseRejectionWarning: ReferenceError: axios is not defined
    at getNodeVer (C:\Users\\Desktop\lin-bot2\mylinebot\server.js:43:17)
    at handleEvent (C:\Users\\Desktop\lin-bot2\mylinebot\server.js:31:5)
    at Array.map (<anonymous>)
    at C:\Users\sayu5\Desktop\lin-bot2\mylinebot\server.js:17:28
    at Layer.handle [as handle_request] (C:\Users\sayu5\Desktop\lin-bot2\mylinebot\node_modules\express\lib\router\layer.js:95:5)
    at next (C:\Users\sayu5\Desktop\lin-bot2\mylinebot\node_modules\express\lib\router\route.js:137:13)
    at C:\Users\sayu5\Desktop\lin-bot2\mylinebot\node_modules\@line\bot-sdk\dist\middleware.js:42:13
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:24304) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside
of an async function without a catch block, or by rejecting a
promise which was not handled with .catch(). (rejection id: 1)(node:24304) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```


これは当初お天気APIと繋げようとした際にでたエラーです。
どうやら

<font color="red">axios is not defined</font>

とあるのはaxiosを使おうと指定する際、


const express = require('express');
const line = require('@line/bot-sdk');
const PORT = process.env.PORT || 3000;
<font color="red">const axios = require('axios');</font>

とここではじめにきちんと変数の宣言をしていないから起こっていたエラーでした。
なるほど、、、ひとつひとつ指定するのですね。

##振り返るエラー Ⅱ

```server.js
PS C:\Users\sayu5\Desktop\lin-bot> npm i -g ngrok
npm ERR! path C:\Users\sayu5\AppData\Roaming\npm\node_modules.ngrok.DELETE\bin\ngrok.exe
npm ERR! code EPERM
npm ERR! errno -4048
npm ERR! syscall unlink
npm ERR! Error: EPERM: operation not permitted, unlink 'C:\Users\sayu5\AppData\Roaming\npm\node_modules.ngrok.DELETE\bin\ngrok.exe'
npm ERR!  [OperationalError: EPERM: operation not permitted, unlink 'C:\Users\sayu5\AppData\Roaming\npm\node_modules.ngrok.DELETE\bin\ngrok.exe'] {
npm ERR!   cause: [Error: EPERM: operation not permitted, unlink 'C:\Users\sayu5\AppData\Roaming\npm\node_modules.ngrok.DELETE\bin\ngrok.exe'] {
npm ERR!     errno: -4048,
npm ERR!     code: 'EPERM',
npm ERR!     syscall: 'unlink',
npm ERR!     path: 'C:\Users\sayu5\AppData\Roaming\npm\node_modules\.ngrok.DELETE\bin\ngrok.exe'
npm ERR!   },
npm ERR!   errno: -4048,
npm ERR!   code: 'EPERM',
npm ERR!   syscall: 'unlink',
npm ERR!   path: 'C:\Users\sayu5\AppData\Roaming\npm\node_modules\.ngrok.DELETE\bin\ngrok.exe'
npm ERR! }
npm ERR!
npm ERR! Please try running this command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\sayu5\AppData\Roaming\npm-cache_logs\2019-10-16T14_05_55_335Z-debug.log

```

前日は使えていたngrokでエラーが起きるので新しいフォルダを１から作りもう一度インストールしようとした所出たエラー、、、
新しく慎重に手順通り作り直したのになぜ、、、??(涙)
…２画面の別モニターでngrok起動中でした。あ、２つは開けないのですね、、、ふう。
心当たりがありすぎて何が問題かを見抜けず。悪戦苦闘です。

##まずはお手本コードで試す！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508651/e26b8496-be45-e3d5-89b1-e830de4d0ea6.png)

はい、エラー！！
お手本はりつけただけなのになんか使った事ないタブに見たことないエラーが、、、！！(涙)
でもよく見たらVisualStudioCodeが赤いなみなみ線引いてくれてる…なんかきっとここがおかしい
と思ったら貼り付けミス発見。いちいちもう、、、
ちょっと何て言ってるのかはまだ分からないけど、VisualStudioCodeめっちゃ親切なのは分かり。ちょっと好きになりました。

##感想と猛省
やってみたい事から調べすぎてたどりつけず、時間内に何も形にする事が出来なかったので
まずは力量を把握しながら少しずつ時間内に出来る事を増やしていきたいです！！
今回作っていた中では、エラーばかりで全然返事をしてくれないラインボットが動いてくれた時は本当にうれしかったです。
小さなものでも形として完成するのはやはりとても嬉しいなと思いました。
少しでもオリジナル要素を増やせるように頑張ります。