夏の猛暑に備えてLINEBOTで水分補給リマインダーを作ろう

## はじめに

夏の猛暑が続く中、こまめな水分補給が大切です。今回は、PHPを使ってLINEBOTを作成し、定期的に水分補給を促すリマインダーを設定する方法をご紹介します。初心者でも簡単に実装できるシンプルなボットですので、ぜひ試してみてください。

---

## 1. LINE Developer Programの契約と設定

### 1.1 LINE Developerアカウントの作成

1. [LINE Developers](https://developers.line.biz/ja/) にアクセスし、LINEアカウントでログインします。
2. 「プロバイダーを作成」ボタンをクリックし、任意の名前を入力してプロバイダーを作成します。
3. プロバイダーを作成したら、「Messaging API」を選択し、チャネルを作成します。
4. チャネル名、説明、業種、メールアドレスなど必要な情報を入力し、「作成」ボタンをクリックします。

### 1.2. チャネルの設定

1. チャネルシークレットとチャネルアクセストークンが発行されます。これらをメモしておきます。
2. 「Messaging API」タブで、「Webhook URL」を設定します。ここには、あなたのサーバーで動作するPHPスクリプトのURLを指定します。
3. 「Webhookの利用」は「利用する」に設定します。
4. 「応答メッセージ」と「友だち追加時あいさつ」は「無効」に設定します。

---

## 2. MySQLデータベースの準備

### 2.1. データベースとテーブルの作成

**ファイル名: `create_database.sql`**

まずは、リマインダー情報を保存するためのデータベースとテーブルを作成します。

```sql
CREATE DATABASE hydration_reminder;
USE hydration_reminder;

CREATE TABLE reminders (
    id INT AUTO_INCREMENT PRIMARY KEY,
    user_id VARCHAR(255) NOT NULL,
    reminder_time TIME NOT NULL,
    message TEXT NOT NULL
);
```

`hydration_reminder`というデータベースを作成し、その中にリマインダー情報を保存するテーブルを用意します。

---

## 3. PHPで水分補給リマインダーボットを構築

### 3.1. 基本のリクエスト処理

**ファイル名: `linebot_request_handler.php`**

LINEからのリクエストを受け取り、ユーザーがリマインダーを設定するための処理を行います。

```php
<?php

// データベース接続設定
$dsn = 'mysql:host=localhost;dbname=hydration_reminder;charset=utf8';
$username = 'your_db_username';
$password = 'your_db_password';

try {
    $db = new PDO($dsn, $username, $password);
} catch (PDOException $e) {
    exit('DB Connection Error: ' . $e->getMessage());
}

// LINEからのリクエストを受け取る
$input = file_get_contents('php://input');
$events = json_decode($input, true);

// チャネルシークレットとチャネルアクセストークン
$channelSecret = 'YOUR_CHANNEL_SECRET';
$accessToken = 'YOUR_ACCESS_TOKEN';

// リクエストの署名を検証
$hash = hash_hmac('sha256', $input, $channelSecret, true);
$signature = base64_encode($hash);
if ($signature !== $_SERVER['HTTP_X_LINE_SIGNATURE']) {
    exit('Invalid signature');
}

// ユーザーのメッセージを解析
foreach ($events['events'] as $event) {
    if ($event['type'] == 'message' && $event['message']['type'] == 'text') {
        $userMessage = $event['message']['text'];

        if (strpos($userMessage, 'リマインダー設定') === 0) {
            $parts = explode(' ', $userMessage, 3);
            $reminderTime = $parts[1];
            $message = $parts[2];

            // リマインダーをデータベースに保存
            $stmt = $db->prepare('INSERT INTO reminders (user_id, reminder_time, message) VALUES (:user_id, :reminder_time, :message)');
            $stmt->bindValue(':user_id', $event['source']['userId']);
            $stmt->bindValue(':reminder_time', $reminderTime);
            $stmt->bindValue(':message', $message);
            $stmt->execute();

            // 確認メッセージを送信
            $confirmationMessage = "リマインダーが設定されました。毎日$reminderTimeに「$message」をお知らせします。";
            sendReply($event['replyToken'], $confirmationMessage);
        }
    }
}

function sendReply($replyToken, $message) {
    $url = 'https://api.line.me/v2/bot/message/reply';
    $headers = [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $GLOBALS['accessToken'],
    ];
    
    $data = [
        'replyToken' => $replyToken,
        'messages' => [
            [
                'type' => 'text',
                'text' => $message,
            ]
        ]
    ];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_exec($ch);
    curl_close($ch);
}
?>
```

---

### 3.2. リマインダー通知機能

**ファイル名: `hydration_notify.php`**

設定されたリマインダーの時間に水分補給のメッセージを送信するスクリプトです。これをcronジョブで定期的に実行します。

```php
<?php

// データベース接続設定
$dsn = 'mysql:host=localhost;dbname=hydration_reminder;charset=utf8';
$username = 'your_db_username';
$password = 'your_db_password';

try {
    $db = new PDO($dsn, $username, $password);
} catch (PDOException $e) {
    exit('DB Connection Error: ' . $e->getMessage());
}

// 現在時刻を取得
$currentTime = new DateTime();
$currentHourMinute = $currentTime->format('H:i');

// 送信するべきリマインダーを取得
$stmt = $db->prepare('SELECT * FROM reminders WHERE reminder_time = :reminder_time');
$stmt->bindValue(':reminder_time', $currentHourMinute);
$stmt->execute();
$results = $stmt->fetchAll();

foreach ($results as $row) {
    // LINEにリマインダーを送信
    $url = 'https://api.line.me/v2/bot/message/push';
    $headers = [
        'Content-Type: application/json',
        'Authorization: Bearer ' . $accessToken,
    ];
    $data = [
        'to' => $row['user_id'],
        'messages' => [
            [
                'type' => 'text',
                'text' => $row['message'],
            ],
        ],
    ];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_exec($ch);
    curl_close($ch);
}
?>
```

---

### 3.3. 定期的な実行設定（cron）

cronジョブを使って、水分補給リマインダーの通知を定期的に実行します。

```bash
* * * * * /usr/bin/php /path/to/hydration_notify.php
```

上記の設定により、毎分スクリプトが実行され、リマインダーの時間に水分補給のメッセージが送信されます。

---

## 4. まとめ

今回は、PHPを使ってLINEBOTで水分補給を促すリマインダーを作成する方法を紹介しました。このボットを活用することで、猛暑の中での水分補給を忘れずに行うことができるようになります。シンプルな実装なので、初心者の方でも気軽にチャレンジしてみてください。