時間を知らせてくれる秘書が欲しい


概要

いつもよくお世話になる音声では
事務的な冷たい視線で社長に「社長、XX時に--の予定が入っています」
「社長、--の予定まで、あとXX分です」
と社長気分をあじわいながらあれやこれやじゅるじゅるやらを行ってくれる。

「そんな気分をちょっとでも味わいたい」

ということで、今回は予定を登録後、
登録時間になったらお知らせしてくれる
システムをPHPの練習がてら作った。

処理の流れ

予定をwebにて登録

Webhookを使用しTeamsに通知

情報をwebサーバーに保存

10分に一度CRONに登録したプログラムを起動

Webhookを使用しTeamsに通知

TeamsのWebhookの設定の流れ

1.Teamsにて自分だけのチャンネルを作成し
 設定から「コネクタ」を選択

2.「incoming Webhook」にて「追加」をクリック
 ※一回追加したため「構成」になっている

3.適当な名前を付けて「作成」をクリック
 その後表示されるURLが必要なため、どこかに保存
 

予定ページ

予定を登録するページは以下のようになっている

すごく質素、、、

このページは予定とその時間を登録するようになっている
登録された予定は登録ボタンの下にスタックされていく

また、登録情報はWebサーバー上にJSON形式で保存され、
そのデータを表示させている。

コードは以下となっている。

todo.php
<?php
function h($v){
    return htmlspecialchars($v, ENT_QUOTES, 'UTF-8');
}

$FILE = 'todo.txt';
$id = uniqid(); 

$DATA = []; 
$BOARD = []; //全ての投稿の情報を入れる

if(file_exists($FILE)) {
    $BOARD = json_decode(file_get_contents($FILE));
}

if($_SERVER['REQUEST_METHOD'] === 'POST'){
    //$_POSTはHTTPリクエストで渡された値を取得する
    //リクエストパラメーターが空でなければ
    if(!empty($_POST['txt'])){
        //投稿ボタンが押された場合
        //$textに送信されたテキストを代入
        $text = $_POST['txt'];
        $tim = $_POST['tim'];
        //新規データ
        $DATA = [$id, $text, $tim];
        $BOARD[] = $DATA;
        $webhook_url = 'XXXX';
        $options = [
            'http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/json',
            'content' => json_encode([
            'text' => '社長、'.$DATA[2].'時に'.$DATA[1].'の予定が入っています'
            ]),
            ]
        ];
        file_get_contents($webhook_url, false, stream_context_create($options));
        file_put_contents($FILE, json_encode($BOARD));

    }else if(isset($_POST['del'])){
        //削除ボタンが押された場合
        //新しい全体配列を作る
        $NEWBOARD = [];

        foreach($BOARD as $DATA){
            if($DATA[0] !== $_POST['del']){
                $NEWBOARD[] = $DATA;
            }
        }
        //全体配列をファイルに保存する
        file_put_contents($FILE, json_encode($NEWBOARD));
    }
    //Webページを更新)
    header('Location: '.$_SERVER['SCRIPT_NAME']);
    //プログラム終了
    exit;
}
?>

<!DOCTYPE html>
<html lang= "ja">
<head>
    <meta name= "viewport" content= "width=device-width, initial-scale= 1.0">
    <meta http-equiv= "content-type" charset= "utf-8">
    <link rel="stylesheet" type="text/css" href="./todo.css" media="all">
    <title>予定登録</title>
</head>
<body>
    <h1>予定登録</h1>

    <section class= "main">
        <!--投稿-->
        <form method= "post">
            <input type= "text" name= "txt">
            <input type= "time" name= "tim">
            <input type= "submit" value= "投稿">
        </form>    
        <table style= "border-collapse: collapse">
        <!--tableの中でtr部分をループ-->
        <?php foreach((array)$BOARD as $DATA): ?>
        <tr>
        <form method= "post">
            <td>
                <!--テキスト-->
                <?php 
                echo h($DATA[1]." ".$DATA[2]); 
                ?>
            </td>
            <td>
                <!--削除-->
                <input type= "hidden" name= "del" value= "<?php echo $DATA[0]; ?>">
                <input type= "submit" value= "削除">
            </td>
        </form>
        </tr>
        <?php endforeach; ?>
        </table>
    </section>

通知機能

一定時間ごとに通知を行う機能としてPHPのCRONを使用した。

ただ、個人でレンタルしているサーバーの現在のプランでは
10分毎でしか実行できない為、それを踏まえ現時点から15分後までの予定を通知するようにした。

コードは以下の通り

以下のコードをサーバー側のCRONに設定

cron.php
<?php

$FILE = "XXXXXX/todo.txt";
$test = json_decode(file_get_contents($FILE));
$today = date("H:i");

$dateTime1 = date("H:i");
$objDatetime1 = new DateTime($dateTime1);

for ($i = 0; $i < count($test); $i++) {
    echo $test[$i][2]."<br>";
    //echo isset($test[$i][2])."<br>";
    if($test[$i][2]){
        $dateTime2 = $test[$i][2];
        $objDatetime2 = new DateTime($dateTime2);
        $objInterval = $objDatetime1->diff($objDatetime2);
        $sa = $objInterval->format('%H%I');
        $plus = $objInterval->format('%R');
        if ($plus="+"){
            if($sa<=15){
                Teams(sprintf('社長'.$test[$i][1]."の予定まで、あと%02d分です", $sa));
            }
        }
    }else{
        echo "false";
    }
}

function Teams($messege){
    $webhook_url = 'XXXXXXX';
    $options = [
        'http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/json',
        'content' => json_encode([
        'text' => $messege
        ]),
        ]
    ];
    file_get_contents($webhook_url, false, stream_context_create($options));
}

?>

結果

こうしたら

こうなる

最後に

秘書に冷たい視線を向けられながら
事務的にあれやこれやじゅるじゅるされたい

参考

https://qiita.com/wataash/items/72b49509c3964294dd67
https://qiita.com/masa_mf3qt/items/948a0f4d2857c6739ac5