Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

AT-Xの新番組情報をLINEに送ってもらう

More than 3 years have passed since last update.

サンタクロースをいつまで信じていたかなんてことは
たわいもない世間話にもならないくらいのどうでもいい話ですけれども、
もう12月も下旬に入り、いよいよ年越しの準備に入っていく時期になりました。
皆様、いかがお過ごしでしょうか?

僕はアニメの消化に、西へ東への大奔走をしております(家の中で)

AT-X #とは

スカパーやケーブルテレビ、ひかりTVなどで視聴可能な
有料のアニメ専門チャンネルです。(月約2,000円弱)

放送中のアニメはもちろん、過去のアニメの再放送やOVA、はたまた劇場版の放送など、
アニメ好きには大変重宝するチャンネルとなっています。

さらに1アニメが週に数回放送されるので、リアルタイムでの視聴を見逃してしまった、
あるいは何度も観返すといったことが容易にできる点でもすごくお得です。

なぜLINEに送るのか

ちょくちょくAT-X公式サイトの新アニメ情報を見てはいるのですが、『うっかり放送開始日を間違えて覚えている or そもそも放送開始日を覚えていない』ということが多々あるんですよね。
そのたびに、
「やれやれ、またやってしまった……」
と、さながらラノベ原作アニメの主人公のように顔に手を当て天を仰いでいるので、
その状況を改善せねばと思った次第です。

で、なんとなくLINEでそういうのを受信したらよくね?とティンッ!ときたのでLINEにしました。

なにを取得するか

AT-X公式サイトの新アニメ情報から

  • AT-X初公開番組
  • OVA・劇場版・etc
  • 再放送番組

のジャンル別に

  • 画像
  • タイトル
  • 放送開始日
  • 詳細ページへのリンク

を取得してカルーセル表示しようと思います。

LINE BOTアカウントの作成

LINE Developer からLINE Messaging APIを利用するための新規Channelを追加します。

公式ページのクイックスタートがわかりやすいため方法は割愛します。

ワイはこのDeveloper Trialってやつを使うで!!!!(PUSHをしたいため)しませんでした。

LINE BOTを動かす環境を用意する

BOTを作った!さぁBOTで遊ぼっと!!

……

まぁBOTを作っただけでは動きませんね。
あなたは、BOTが喜んで動きたくなるような環境を与えてあげなければなりません。

ということで環境を用意してあげます。
BOTはSSLが利用可能であるところじゃないと動かないです。(https:// ってやつ)

Heroku へ会員登録をする

ということで Heroku というものを使おうと思います。
Herokuは、PaaS(Platform as a Service)という、Webアプリ等を構築・稼働させるためのプラットフォームをインターネット経由のサービスとして提供するものの名称で、
雑に言えば、Webアプリ開発から公開までを簡単にできますよってやつ。

SSLも使えるので、ものぐさな僕にぴったりですね!

ということで、Herokuへ会員登録をします。
仮登録後に届く確認メールに書かれているURLをクリックして、パスワードを設定すれば会員登録完了!

Heroku toolbeltのインストール

Heroku をコマンドラインで動かすために Heroku toolbeltをインストールします。
各環境でのインストール方法が書かれているのでそれに従いましょう。
僕はMacOSなのでHomebrewでインストール!
$ brew install heroku/brew/heroku

Cloning into '/usr/local/Homebrew/Library/Taps/heroku/homebrew-brew'...
remote: Counting objects: 9, done.
remote: Compressing objects: 100% (8/8), done.
Unpacking objects: 100% (9/9), done.
remote: Total 9 (delta 0), reused 6 (delta 0), pack-reused 0
Tapped 2 formulae (36 files, 23.6KB)
Error: Xcode alone is not sufficient on Sierra.
Install the Command Line Tools:
  xcode-select --install

おっふ

$ xcode-select --install

をしてからもう一度brewをしませう。

Herokuへログインする

コマンドライン上からログインします。heroku loginと打ちましょう。

$ heroku login
Enter your Heroku credentials:
Email: myaccount@example.com
Password: **********
Logged in as myaccount@example.com

BOTを作成する

ここから本題のBOTづくりです。

HerokuへはGitでのデプロイとなります。
そのため、まずはローカルリポジトリを作成しましょう。

ローカルにBOT作成用のディレクトリを作成する

$ mkdir heroku-app
$ cd heroku-app 

LINE BOT用のSDKをインストールする

便利なSDKが公開されています。
https://github.com/line/line-bot-sdk-php

$ composer require linecorp/line-bot-sdk

と打ちましょう。venderディレクトリやらcomposer.jsonやらが生成されます。

(composerについては割愛します。各自調べてね)

BOT用のファイルを作成する

移動したディレクトリ内にファイルをを作成し、中を書いていきませう。

callback.php
<?php

require_once 'vendor/autoload.php';
require_once 'scraping.php';

use LINE\LINEBot;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\TemplateActionBuilder\UriTemplateActionBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselColumnTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateBuilder\CarouselTemplateBuilder;
use LINE\LINEBot\MessageBuilder\TemplateMessageBuilder;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use LINE\LINEBot\MessageBuilder\MultiMessageBuilder;

define('CHANNEL_ACCESS_TOKEN', 'アクセストークン(管理画面から取得)');
define('CHANNEL_SECRET'      , 'Channel Secret(管理画面から取得)');

define('LIST_NEW'    , 'AT-X初公開番組');
define('LIST_MOVIE'  , 'OVA・劇場版 etc');
define('LIST_REPEAT' , '再放送番組');


// Botの生成
$bot = new LINEBot(new CurlHTTPClient(CHANNEL_ACCESS_TOKEN), ['channel_secret' => CHANNEL_SECRET]);

// リクエストを受け取る
$contents_raw = file_get_contents('php://input');
$contents     = json_decode($contents_raw);
$event        = $contents->events[0];

// テキストメッセージ受信ではない場合は無言を貫くよ
if ($event->type != 'message') {
    exit;
}

// 今月、来月、再来月の文字がどこかにあるなら、それはもういつのアニメを知りたいか言ってるってことなの
$rcv_text = $event->message->text;
if (strpos($rcv_text, '今月') !== false) {
    $lists = Scraping::createNewArrival()->get();
} elseif (strpos($rcv_text, '来月') !== false) {
    $lists = Scraping::createNewArrivalNext()->get();
} elseif (strpos($rcv_text, '再来月') !== false) {
    $lists = Scraping::createNewArrivalFollow()->get();
} else{
    exit;
}

// 送るね
send($bot, $event, $rcv_text, $lists);
exit;



function send(LINEBot $bot, $event, $rcv_text, $lists)
{
    // どんな文章だろうと以下の単語が入っていたら反応するね
    if (strpos($rcv_text, '新') !== false) {
        $columns = makeArrayForCarousel($lists[LIST_NEW]);
    } elseif (strpos($rcv_text, '映画') !== false) {
        $columns = makeArrayForCarousel($lists[LIST_MOVIE]);
    } elseif (strpos($rcv_text, '再') !== false) {
        $columns = makeArrayForCarousel($lists[LIST_REPEAT]);
    } else {
        exit;
    }

    $message_builder = new MultiMessageBuilder();

    $count_text = count($columns) > 0 ? count($columns) . '件あったよ!' : 'なにもなかったよ';
    $message_builder->add(new TextMessageBuilder($count_text));

    $split_list = array_chunk($columns, 10); // 表示件数で分割する
    foreach ($split_list as $list) {
        $carousel = new CarouselTemplateBuilder($list); // 配列からカルーセルを作成する
        $carousel_message = new TemplateMessageBuilder('アニメ一覧', $carousel); // 作成したカルーセルをメッセージ化する

        $message_builder->add($carousel_message);
    }

    $bot->replyMessage($event->replyToken, $message_builder);
}

function makeArrayForCarousel($lists)
{
    $columns = [];
    if (is_array($lists)) {
        foreach ($lists as $list) {
            $action = new UriTemplateActionBuilder("詳細を見る", $list['detail_url']);

            $column = new CarouselColumnTemplateBuilder($list['title'], $list['start_date'], 'https://www.at-x.com' . $list['img_url'], [$action]);
            $columns[] = $column;
        }
    }

    return $columns;
}
scraping.php
<?php

class Scraping
{
    public static function createNewArrival()
    {
        return new Create('new_arrival');
    }

    public static function createNewArrivalNext()
    {
        return new Create('new_arrival/next');
    }

    public static function createNewArrivalFollow()
    {
        return new Create('new_arrival/follow');
    }
}

class Create
{
    protected $base_url = 'http://www.at-x.com/';
    protected $data_where;
    protected $data;

    public function __construct($data_where) {
        $this->data_where = $data_where;
    }

    public function get()
    {
        require_once 'phpQuery-onefile.php';

        $html_raw = file_get_contents($this->base_url . $this->data_where);
        $html = preg_replace('/^<\?xml.*\?>/', '', $html_raw);
        $doc = phpQuery::newDocument($html);

        $data = null;
        foreach($doc['#pageProgramDetail .section'] as $section) {
            if (pq($section)->find('h3')->html() === '') {
                continue;
            }

            $section_title = pq($section)->find('h3 img')->attr('alt');
            foreach (pq($section)->find('.newBlock') as $i => $block) {
                preg_match('/■.+■/', pq($block)->find('.right')->text(), $match);
                if (isset($match) && mb_strlen($match[0]) > 60) {
                    $match[0] = '詳細ページで確認してください';
                }

                $data[$section_title][$i] = [
                    'img_url'    => pq($block)->find('.left a img')->attr('src'),
                    'title'      => pq($block)->find('.right h4 a')->text(),
                    'detail_url' => pq($block)->find('.right h4 a')->attr('href'),
                    'start_date' => $match[0] ?: '不定期放送',
                ];
            }
        }

        return $data;
    }
}

どんどんコードが雑になっていってるけど、とりあえず動いてるからよしとします。
僕がよしと言ったらよしなのです。

改善点はてんこもりですよ〜
盛るぜ〜超盛るぜ〜

ローカルリポジトリを作成する

で!

ファイルを作成したディレクトリ上で

$ git init
$ git add .
$ git add -m 'First Commit' //コミットメッセージを書く

Herokuにアプリを作成する

Herokuにログインした状態で以下のコマンドを打つ。

$ heroku create <アプリ名>  //アプリ名は入れなくても可(後から変更できる)
Creating app... done, ⬢ xxxxxxx-xxxxxxxx-xxxxx
https://xxxxxxx-xxxxxxxx-xxxxx.herokuapp.com/ | https://git.heroku.com/xxxxxxx-xxxxxxxx-xxxxx.git

Herokuで作成されたリポジトリへPushしデプロイする

$ git push heroku master

Webhook送信URLを設定する

$ heroku create で生成されたURLを管理画面の「Webhook URL」へと登録しましょう。
Webhook登録画像

※Webhook送信を『利用する』にしないとユーザからのリクエストを受信できません

ちなみに「俺は他のやつからのリクエストなんて受け付けねぇぜ!」っていうロックな人は設定しなくてもおkです。(Herokuなだけに)

動かしてみる

top.png
かわいいですね

来月の新放送アニメを取得する

next_new.png

来月の映画を取得する

next_movie.png
マスターになりたい

再来月の再放送を取得する

follow_repeat.png
まだなかった

こういうのにももちろん反応する

neta.png
かわいい

まとめ

これでアニメの録り逃しが減ること間違い無し!!

ちょっと色々とぐちゃぐちゃになったのでリファクタリングしたさMAXなのですけれども、

「年が明けてからじっくりしよう、今年はもういいや」
そう心にLINEを引く僕なのでした。

ちなみに

$ heroku logs --tail

でherokuのログがストリーミングで見れる

参考リンク

PHP版の公式SDKを使ってLINE Messaging APIベースのBotを作ってみた
Heroku初心者がHello, Herokuをしてみる

qnote
猫と音楽とITをテーマにiOS/Android/Unity/Web/デザインの受託開発をやり続けて13年目の町工場的会社です。従業員の大半は猫です。
http://www.qnote.co.jp
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