Help us understand the problem. What is going on with this article?

今日は何のゴミの日か教えてくれるLineBotを作成してみた

要件定義

Lineに「今日は何のゴミの日?」とか「明日は?」、「明後日は」とかメッセージを送ると「燃えるゴミの日です」とか「資源プラゴミの日」ですとか返信してくれるLineBotを作成します。

開発環境

CENTOSバージョン:8.0

$cat /etc/redhat-release
CentOS Linux release 8.0.1905 (Core) 

PHPバージョン:7.3

$ php -v
PHP 7.3.12 (cli) (built: Nov 19 2019 10:24:51) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.12, Copyright (c) 1998-2018 Zend Technologies

MySQLバージョン:8.0

$ mysql --version
mysql  Ver 8.0.17 for Linux on x86_64 (Source distribution)

データベース設計

データベース名は「linebot」とします。とりあえず、今後もいろんなlinebotを作成していくため。
テーブル名は「garbageday」(訳すとゴミの日)とします。

カラム

  • id
  • day:日付
  • garbage:ゴミ捨ての種別

Line側の設定

以下にアクセスし、ログインして、諸々設定します。
https://developers.line.biz/ja/

コチラを参考にして、Messaging APIの設定を実施
https://qiita.com/caique/items/50e00c4a5801e2d583a4

MySQLの設定

mysqlインストール

$ sudo yum -y install mysql  mysql-server

rootでログイン

# mysql -u root -p
Enter password: 

rootのパスワード変更

  • 8文字以上
  • 数字、英字、記号含む
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY "(パスワード)";

ユーザーの作成

mysql> create user "jum"@"localhost" identified by '(パスワード)';

データベースの作成

mysql>create database linebot default character set utf8mb4;
Query OK, 1 row affected (0.00 sec)

linebotデータベースに権限を付加する。

mysql>grant all privileges on linebot.* to "jum"@"localhost" identified by '(パスワード)';
Query OK, 0 rows affected, 1 warning (0.00 sec)

※mysql 8.0ではidenti…からは必要ない。

ユーザーを変更する

mysql> exit
$ mysql -u (ユーザー名) -p

テーブルを作成する

テーブル名は「garbageday」とする

mysql> use linebot;
Database changed
mysql> create table garbageday(id int not null primary key auto_increment,day date,garbage varchar(50));
Query OK, 0 rows affected (0.02 sec)

テーブルの構成を確認する。

mysql> show columns from garbageday;
+---------+-------------+------+-----+---------+----------------+
| Field   | Type        | Null | Key | Default | Extra          |
+---------+-------------+------+-----+---------+----------------+
| id      | int(11)     | NO   | PRI | NULL    | auto_increment |
| day     | date        | YES  |     | NULL    |                |
| garbage | varchar(50) | YES  |     | NULL    |                |
+---------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

挿入するデータを作成する

sql文のファイルを作成する

$ vi insert.sql
insert.sql
insert into garbageday(day,garbage) values("2020-01-14","燃えるゴミ");
insert into garbageday(day,garbage) values("2020-01-15","不燃物ゴミ");
insert into garbageday(day,garbage) values("2020-01-16","資源プラゴミ");
insert into garbageday(day,garbage) values("2020-01-17","燃えるゴミ");
insert into garbageday(day,garbage) values("2020-01-18","無し");
insert into garbageday(day,garbage) values("2020-01-19","無し");
insert into garbageday(day,garbage) values("2020-01-20","缶とびんゴミ");
insert into garbageday(day,garbage) values("2020-01-21","燃えるゴミ");
insert into garbageday(day,garbage) values("2020-01-22","資源プラゴミ");
insert into garbageday(day,garbage) values("2020-01-23","スプレー缶蛍光管ゴミ");
insert into garbageday(day,garbage) values("2020-01-24","燃えるゴミ");
insert into garbageday(day,garbage) values("2020-01-25","ペットボトルゴミ");
insert into garbageday(day,garbage) values("2020-01-26","無し");
insert into garbageday(day,garbage) values("2020-01-27","古紙・布類ゴミ");
insert into garbageday(day,garbage) values("2020-01-28","燃えるゴミ");
insert into garbageday(day,garbage) values("2020-01-29","無し");
insert into garbageday(day,garbage) values("2020-01-30","資源プラゴミ");
insert into garbageday(day,garbage) values("2020-01-31","燃えるゴミ");

データを挿入する

$ mysql -u jum -p linebot < insert.sql

挿入されたか確認する

$ mysql -u jum -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 31
Server version: 8.0.17 Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


mysql> use linebot
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from garbageday;
+----+------------+--------------------------------+
| id | day        | garbage                        |
+----+------------+--------------------------------+
|  1 | 2020-01-14 | 燃えるゴミ                     |
|  2 | 2020-01-15 | 不燃物ゴミ                     |
|  3 | 2020-01-16 | 資源プラゴミ                   |
|  4 | 2020-01-17 | 燃えるゴミ                     |
|  5 | 2020-01-18 | 無し                           |
|  6 | 2020-01-19 | 無し                           |
|  7 | 2020-01-20 | 缶とびんゴミ                   |
|  8 | 2020-01-21 | 燃えるゴミ                     |
|  9 | 2020-01-22 | 資源プラゴミ                   |
| 10 | 2020-01-23 | スプレー缶蛍光管ゴミ           |
| 11 | 2020-01-24 | 燃えるゴミ                     |
| 12 | 2020-01-25 | ペットボトルゴミ               |
| 13 | 2020-01-26 | 無し                           |
| 14 | 2020-01-27 | 古紙・布類ゴミ                 |
| 15 | 2020-01-28 | 燃えるゴミ                     |
| 16 | 2020-01-29 | 無し                           |
| 17 | 2020-01-30 | 資源プラゴミ                   |
| 18 | 2020-01-31 | 燃えるゴミ                     |
+----+------------+--------------------------------+
18 rows in set (0.00 sec)

Lineで返信するための、コードを作成

linebot.php
<?php

//line apiより
$accessToken = '(ここにはline apiよりアクセストークンを確認し入力してください)';

//ユーザーからのメッセージ取得
$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);

//取得データ
$replyToken = $json_object->{"events"}[0]->{"replyToken"};        //返信用トークン
$message_type = $json_object->{"events"}[0]->{"message"}->{"type"};    //メッセージタイプ
$message_text = $json_object->{"events"}[0]->{"message"}->{"text"};    //メッセージ内容

//メッセージタイプが「text」以外のときは何も返さず終了
if($message_type != "text") exit;

//mysqlに接続
define("DB_DATABASE","linebot");
define("DB_USERNAME","jum");
define("DB_PASSWORD","(設定したパスワード)");
define("PDO_DSN","mysql:host=localhost;dbname=" . DB_DATABASE);

 try{
   $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
   $db->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
   $db->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
    } catch(PDOException $e) {
   $db->rollback();
   echo $e->getMessage();
   exit;
 }

//日付関連の処理
date_default_timezone_set('Asia/Tokyo');
$date = new DateTime();
$today = $date->format('Y-m-d');
$tomorrow = $date->modify('+1 days')->format('Y-m-d');
$day_after_tomorrow = $date->modify('+1 days')->format('Y-m-d');

//ユーザーが確認したいゴミの日
$Verification_Garbage_Day = "";

if(strpos($message_text,"今日") !== false) {
  $Verification_Garbage_Day = $today;
}
elseif(strpos($message_text,"きょう") !== false) {
  $Verification_Garbage_Day = $today;
}

elseif(strpos($message_text,"明日") !== false) {
  $Verification_Garbage_Day = $tomorrow;
}
elseif(strpos($message_text,"あした") !== false) {
  $Verification_Garbage_Day = $tomorrow;
}
elseif(strpos($message_text,"明後日") !== false) {
  $Verification_Garbage_Day = $day_after_tomorrow;
}

else {
  $Verification_Garbage_Day = "";
}

//変数$Verification_Garbage_Dayに値が入っていた場合、データベースと照合する
if(!empty($Verification_Garbage_Day)){

//返信する内容を保存する変数
$Return_Verification_Garbage_Day = "";

//データベースから読み取ったゴミの日
try{
    $sql = "select * from garbageday";
    $stmt = $db->query($sql);
    }
    catch(PDOException $e) {
    $db->rollback();
    echo $e->getMessage();
    exit;
                          }

    //データベースとユーザーが投稿した内容が一致するか確認する
    while($Garbage_Day_db = $stmt->fetch(PDO::FETCH_ASSOC)){

    if($Garbage_Day_db["day"] == $Verification_Garbage_Day) {

      $Return_Verification_Garbage_Day = $Garbage_Day_db["garbage"];

    }
  }
}else {
  $Return_Verification_Garbage_Day = "もう一度入力してください";
}

  sending_messages($accessToken, $replyToken, $message_type, $Return_Verification_Garbage_Day);
?>

<?php
  function sending_messages($accessToken, $replyToken, $message_type, $Return_Verification_Garbage_Day){



    //レスポンスフォーマット
    $response_format_text = [
        "type" => $message_type,
        "text" => $Return_Verification_Garbage_Day
      ];

        //ポストデータ
        $post_data = [
            "replyToken" => $replyToken,
            "messages" => [$response_format_text]
        ];

        //curl実行
        $ch = curl_init("https://api.line.me/v2/bot/message/reply");
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charser=UTF-8',
            'Authorization: Bearer ' . $accessToken
        ));
        $result = curl_exec($ch);
        curl_close($ch);
    }

?>

こんな感じで出来上がりました

スクリーンショット 2020-01-13 14.16.32.png

データベースに今日の日付を入れていなかったので、今日には反応しませんでした。
明日が今日になれば反応するはず。

以上です。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away