るいすのブログ

オタクエンジニアの雑記

田村ゆかりさん公式サイトの通知を LINE BOT API で作ってみた。 #yukarin


LINE BOT が先着1万人に配られるということで乗ってみた。 今日も相変わらずPHP

今回は 田村ゆかりさんの公式サイトが更新される度にLINE BOT APIを通して通知するといったものを作った。

 

登録の仕方

ova0152n左記QRコードで友達追加をして、1度メッセージを送信すると登録が完了になります。 なんで1度メッセージを送信する必要性があるのかは後で説明しまうす。

 

 

雑書

<?php
@$f_mids = file_get_contents('./mids');
$content = file_get_contents('php://input');
$content = json_decode($content);
$content = $content->result{0}->content;
$mid = $content->from;

if (isset($mid) === true && strpos($f_mids, $mid) === false) {
    $text = "ご登録が完了しました。\r\n田村ゆかりさん公式サイトが更新される度にLINEでお知らせいたします。";
    $response_format_text = ['contentType' => 1, "toType" => 1, "text" => $text];
    $post_data = [
        "to" => [$mid],
        "toChannel" => "1383378250",
        "eventType" => "138311608800106203",
        "content" => $response_format_text
    ];

    toPost($post_data);
    file_put_contents('mids', $mid . "\r\n", FILE_APPEND | LOCK_EX);
}

function toPost($post_data)
{
    $ch = curl_init("https://trialbot-api.line.me/v1/events");
    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',
        'X-Line-ChannelID: <チャンネルID>',
        'X-Line-ChannelSecret: <チャンネルシークレット>',
        'X-Line-Trusted-User-With-ACL: <MID>'
    ));
    $result = curl_exec($ch);
    curl_close($ch);

    return $result;
}

LINE BOT APIの登録の仕方はQiitaの方が詳しく説明されてるので割愛します。

このファイルは最初の登録のときにしか使いません。 何でだか知らないけど登録者全員にメッセージを送るAPIもないし、登録者全員のID(mid)を取得するAPIも今のところないので 1度メッセージを送ってもらって、ファイルに保存するといった方法を取りました。他にいい方法あったら教えて下さい...。

 

<?php
require_once 'simple_html_dom.php';

$html = file_get_html('http://www.tamurayukari.com/');
if ($html === false) {
    die();
}

@$value = file_get_contents('content.txt');

/* 更新内容 */
$content = $html->find('td a', 0)->plaintext;
$content = trim($content);

/* 更新URL */
$url = $html->find('div[id=news_table] a', 0)->href;
$url = trim(toGetShortUrl($url));

if ($value !== $content) {
    $f_mids = file('./mids');

    foreach ($f_mids as $row) {
        $text = "【田村ゆかり公式サイト通知BOTよりお知らせ】\r\n田村ゆかり公式サイトが更新されました!\r\n$content\r\n詳しくはこちら $url";
        $response_format_text = ['contentType' => 1, "toType" => 1, "text" => $text];
        $post_data = [
            "to" => [trim($row)],
            "toChannel" => "1383378250",
            "eventType" => "138311608800106203",
            "content" => $response_format_text
        ];

        toPost($post_data);
        file_put_contents('content.txt', $content);
    }
}

function toPost($post_data)
{
    $ch = curl_init("https://trialbot-api.line.me/v1/events");
    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',
        'X-Line-ChannelID: <チャンネルID>',
        'X-Line-ChannelSecret: <チャンネルシークレット>',
        'X-Line-Trusted-User-With-ACL: <mid>'
    ));
    $result = curl_exec($ch);
    curl_close($ch);

    return $result;
}

function toGetShortUrl($url)
{
    $api = 'GoogleShorterURLapi';

    $data = array(
        'longUrl' => $url
    );
    $data = json_encode($data);

    $header = array(
        "Content-Type: application/json",
        "Content-Length: " . strlen($data)
    );

    $context = array(
        "http" => array(
            "method" => "POST",
            "header" => implode("\r\n", $header),
            "content" => $data
        )
    );

    $result = file_get_contents("https://www.googleapis.com/urlshortener/v1/url?key=${api}", false,
        stream_context_create($context));
    $result = json_decode($result);

    return $result->id;
}

本当は1つのファイルに纏めたくて、引数有無で条件分岐してたけど不格好になっちゃうし見栄えが悪かったので別々にしました。

midがまとめられたファイルを配列に入れてforeachで回してますが、 「mid,mid,mid」みたいな感じで一斉送信できるらしいです。 で、でも改行を","で置換して文末の","を削除して~って流れよりforeachの方が楽な気がします。最初から「mid,mid,mid」みたいな感じで保存すればいいだけなんですけどね。

更新されると以下のようなメッセージが届きます。 SnapCrab_NoName_2016-4-9_14-31-52_No-00

 

新しくAPIが追加されることを願います。 ちなみにスクレイピングに関しては運営に承認済みです^ー^