*

【LINEbot】LINEbotが作れるからphpで作ってみたの巻 ~さくらの共有SSLでも動くよ~

公開日: : 最終更新日:2016/04/25 how to, サーバ・プログラム

BOT API Trial Accountってのが、公開されたので、LINEbotを正式に作れるようになりました。

【LINE】メッセージングAPIのオープン化に先駆け、先着1万名限定でBOTアカウントを自由に開発できる「BOT API Trial Account」の無償提供を開始
http://linecorp.com/ja/pr/news/ja/2016/1320

これまでも非公式なAPIでLINEbot作ったりする猛者もいたわけですが、

1時間でLINE のbotを作成する、LINEのBOT自動化

LINE 非公式APIを使ったBOTの概要
・API自体はpythonで書かれているためPC必須 windowsでやります。
・作業時間大体1時間くらい
・本家のLINEからクレームがあったようで、1度旧バージョンにもどしてからログインのためのトークンを取得する必要あり

なんか、色々問題や、本家からクレーム来たりと色々あったそうで、この度晴れて正式にLINEbotを堂々と作れるとのことです。

ただ、BOT API Trial Accountとの名前の通り、公式プレスによると

※なお、「BOT API Trial Account」で開発されたアカウントは、友だち登録可能なユーザー数が50名までに上限が設定されており、不具合が発生した場合等に予告なく一時停止・終了する可能性があります。

とのことですので、まだ完全版ではありませんが、とりあえずね!まあ新しいもの好きという病にかかっているボクですから。とりあえず作って見るわけですよね。

まずはBOT API Trial Accountにアカウント登録

先着1万名と少し手厳しい数なので、できるだけお早めのご登録をオススメでします!以下のページからどうぞ!

BOT API Trial Account登録ページ

bot01

bot02

で、色々と情報を入力していくとアカウントがつくられます。で、こんな感じで画像もそれっぽいの入れたら、「使う」ボタンから進みます。
bot03

そうすると、自分のビジネスアカウントの情報が見られるようになりました。

bot04

で、最初の3つの項目

  • Channel ID
  • Channel Secret
  • MID

は、自分の固有の番号なので、今後のbotを動かすプログラムを書く際に、認証の値として使いますので、控えておいてね。

超わかりやすい参考ページ:【LINE BOT】 アカウント設定の仕方 〜アカウントを取ってみた!〜

Callback URL(すなわちサーバ)を用意するんだけど、さくらインターネットの共有SSLでも動いたよ

これが最初の難関です。

Callback URLってなんやねん?ってことだと思うのですが、これは要はbotがどういう動作をするかを規定するプログラムを置いておくサーバのURLです。

で、これがLINEのAPIの仕様でssl、ようはhttps://のURLじゃないとダメとのことです。

で、結構これがめんどくさくって、っていうかsslで動くサーバってそんなに持ってなかったりするよね。

だもんで結構みんな色々工夫している訳です。

Heroku単体ではだめでアドオン入れたり
LINE BOT をとりあえずタダで Heroku で動かす

Luaで動くwebscript.ioとか使ったり
webscript.ioでLINE BOT APIの事始め

で、まあ色々やっていると思うのですが、ボクの場合は素人だもんで、Luaとか触ったことすらないもんで、LINE自体はjsonで動いているならphpで書きたいな。なんて思ってまして。

そうした時にふと考えたのが、さくらインターネットの共有SSLなら行けるんじゃね?なんて思った次第です。

これならphpも当然動くしね!

ただ、みんなの情報によるとただsslでさえアレばいいわけじゃなくて、callbackされないsslとかも結構あるみたいです。

有名どころだとLet’s Encryptなんかは現時点ではダメっぽいですね。

LINE BOT APIを使ってPythonでLINE BOTを作ってみた

Let’s Encryptで作った証明書だとダメっぽい
ふふふ。これでサーバ証明書を生成すれば動くだろう。とその時は思ったいた…

(略)

ところが、LINEからコールバックURLがコールされない。Twitterで検索すると…

阿鼻叫喚の嵐。

だもんで心配してたんだけど。。。

【2016.04.25追記】
現在は Let’s Encrypt の証明書が利用できるようになっているようです。

結論から言うとぶっちゃけできました。

ただ、一つ心配なのが、

LINE BOT APIでリクエストが飛んでこない(SSL関係)

使える

  • RapidSSL→上位のGeoTrustも使えると思う
  • Comodo系SSL(Comodo/EcoCert→多分CoreSSL、SecureCoreもいける)
  • 共有サーバーの共有SSL(※1)
  • CloudFront+AWS
  • GoogleAppsEngine
  • Heroku

使えへん

  • 自己署名証明書
  • Let’s Encrypt
  • WoSign(無料)
  • StartSSL
  • GlobalSign 45日テスト用証明書

補足

※1:もちろん発行元によるが、大抵の所は大丈夫だとは思う。
しかし、他投稿にて同じドメインの場合動作しないとの意見もあり、共有SSLの提供の仕方によっては「一番最初に設定した奴が使える」という恐ろしい状況になるかも(知らんけど)

なんて恐ろしい情報もあるけど、まあとりあえずだもんでさ。

さくらインターネットのレンタルサーバーで、共有SSLを設定する

といっても、そんなに難しく無いです。

方法の前にさくらインターネットの共有sslがなぜ(セキュリティ面は当然専用SSLのが良いんだろうけど、とりあえず動かしてみるのに)都合が良いかというと。

さくらインターネットでサーバを借りてる場合、恐らく多くは独自ドメインでサイトを公開していると思います。

ボクもそうです。

さくらインターネットでは「初期ドメイン」という言い方をしているのですが、それがこんな感じのアドレスです。

http://(自分で決めたユーザー名).sakura.ne.jp/

せっかくサーバ借りたのにこれじゃあんまりかっこよくないですよね。

だから、この形式でサイト公開している人ってあんまり見ませんので意外と余ってたり(てか使ってなかったり)します。

で、LINEbotのCallback URLは別に誰かに見られるようなものではないので、何でもよかったりするので、その意味でも好都合です。

ほんでやり方なんですが、最初に言ったように超カンタンです。

まず、以下からさくらインターネットの会員IDでログインします。

https://secure.sakura.ad.jp/auth/login

そして、「契約情報」→「契約サービスの確認」→「サーバ設定」と進みます。

bot05

bot06

bot07

で、サーバコントロールパネルから以下の画像のように「ドメイン設定」から、初期ドメインの共有SSLにチェックを入れて「送信」します。

bot08

bot09

bot10

完了すれば晴れてSSlが使えるようになる、すなわち

https://(自分で決めたユーザー名).sakura.ne.jp/

というLINEbotを動かすのに必要なSSLに対応したCallback URLをゲット出来た、という訳です。

Callback URLと、Server IP Whitelistを設定

ここまできたら、めんどくさい設定はあと僅かです。

Callback URL

まず、最初に作ったのLINEビジネスアカウントの画面に戻り、「EDIT」ボタンから情報を編集します。

bot11

といっても、先のセクションで作ったさくらインターネットのsslのURLを入れてsaveするだけです。

bot12

一つ注意点が、ただ単にURLを入れるだけでなくSSLのポートを指定する必要があります。

LINEの仕様でポート番号は443と決められているので、URLの形としては

https://(自分で決めたユーザー名).sakura.ne.jp:443/(botを動かすプログラムファイルの場所)

とします。

で、ボクの場合冒頭でも話したとおりphpで書きたいので、phpのファイルで、名前もずばりそのままcallback.phpにしまして。

で、他のファイルと一緒くたになると、わかりづらいので新たに「linebot」とわかりやすいディレクトリをつくって

https://(自分で決めたユーザー名).sakura.ne.jp:443/linebot/callback.php

てな感じにしました。

決まり事としては、httpsなのと、ポートを指定(443)以外は基本的に任意なので、お好きな名前でどうぞ。

Server IP Whitelist

で、設定はこれで最後です。

Server IP Whitelistという英語でわけわかんないかもですが、ようはcallbackを許可するIPアドレス、すなわちさっき設定したURLのサーバのipアドレスを指定してやればいいだけです。

これはIPひろばとかで、callbackのドメイン、今回で言えば【(自分で決めたユーザー名).sakura.ne.jp】を入れて出てきたipアドレスを入れてやります。

IPひろば

で、LINEビジネスアカウントでの設定は、左上のハンバーガーメニューを開いて、「Server IP Whitelist」をクリックします。

bot13

bot14

で、こんな感じでIP広場で調べたipアドレスを入力し、「ADD」します。

bot15

ボクの場合はレンジ指定(画面で言う000.000.000.000/(ここ))は特に必要なかったです。これはボクもよくわかりません。

一応以上で設定は完了です!

実際にLINEbotの動きを規定するphpを書いてみた

で、当然これだけじゃ面白くないので、実際に何かしら動くものを作ってみようとなりますよね!

LINEのbotAPIの仕様を参考に書いていけるわけですが。

ただ、英語だしボクみたいな素人には、みなさんのブログなどを参考に書いていくのが良いと思います。

ボクも調べながら、このサイトのコードを参考して適当にこんな感じの動きのやつを作ってみました。

よりしければ、友達登録して遊んで見てね。

eom5298j

QR読めない人はここを踏んでみて。

まあ凄く単純なbotで、オウム返しに毛が生えた程度です。あくまでとりあえず遊んでみたにはちょうど良いでしょ。

一応これのコードも貼ってくのでよろしければ見てってね。

botの様子のスクショ

【2016.04.13追加】

一応スクショも貼っときますね。こんな感じで動きます。

14522

14528

phpで書いたLINEbotのプログラムの概要説明

簡単な動作の説明としては、

  • 何か話しかけたら、それに少し肉付けしたオウム返しする。
  • 「画像」とか「動画」とか特定のワードを話しかけたら、写真や動画を返す
  • 画像や写真を送ると、反応する

程度のものです。

構造もシンプルで

  • 設定ファイル(config.php)
  • メインファイル(callback.php)

のみです。

基本的には設定ファイル(config.php)に自分固有のLINEビジネスアカウントに割り当てられた

  • Channel ID
  • Channel Secret
  • MID

を入れさえすれば動くようになります。

その他、返答として返す文言や、送り返す画像や動画のURLもこのconfig.phpで規定します。

で、メインのcallback.phpでその設定を参照しています。

phpで書いたLINEbotのプログラムのコード

一応プログラムのコード以下に転記しておきますね。

config.php

(注)これの「アカウント情報」のところにChannel ID・Channel Secret・MIDを入れればとりあえずは動くので。


<?php

/*==========================
*
* 文字の中の改行はjsonなので「\\n」
*
==========================*/


//==========================
// アカウント情報(https://business.line.me/services/)
//==========================
$channel_id = "0000000000"; /* Channel ID */
$channel_secret = "0123456789abcdef0123456789abcdef"; /* Channel Secret */
$mid = "fedcba9876543210fedcba9876543210f"; /* MID */


//==========================
// コンテンツ情報
//==========================
# 相手にあげる画像のリンク元
$original_content_url_for_image = "http://hogehoge.com/example01.jpg";
$preview_image_url_for_image = $original_content_url_for_image;
// $preview_image_url_for_image = "http://hogehoge.com/example01_thum.jpg"; ←サムネ画像別にするなら

# 相手にあげる動画のリンク元
$original_content_url_for_video = "http://hogehoge.com/example02.mp4";
$preview_image_url_for_video = "http://hogehoge.com/example02_thum.jpg"; /* サムネは画像ファイル */

# 相手にあげる自分の位置情報→経度・緯度調べ方(http://bit.ly/1VcLEdV)
$original_content_location_name = "○○がよくいる場所"; /* 場所の名称 */
$original_content_location_latitude = "35.681382"; /* 緯度(ここは仮で東京駅ね) */
$original_content_location_longitude = "139.766084"; /* 経度 */


# 画像が送られた時の返答メッセ
$get_image = "素敵な写真をありがとうございます!";

# 動画が送られた時の返答メッセ
$get_video = "素敵なビデオをありがとうございます!";

# 音声が送られた時の返答メッセ
$get_audio = "素敵な音声をありがとうございます!";

# 位置情報が送られた時の返答メッセ
$get_location = "きっと素敵な場所なんでしょうね。行ってみたいな!";

# スタンプが送られた時の返答メッセ
$get_stamp = "素敵なスタンプですね!僕も買おうかな!";

# 任意なテキストが送られた時の返答メッセ
$get_message_before = "おや。。。\\n\\n「"; /* ユーザーが入力した文字の前 */
$get_message_after = "」とは素敵なことを言いますね~"; /* ユーザーが入力した文字の後 */

# ルール説明
$rule = "【遊び方】\\n\\n「画像」と話かけると、写真がもらえます。\\n「動画」と話かけると、動画がもらえます。\\n「位置」と話かけると、○○のよくいる場所が教えてもらえます。\\n\\n全部欲しい欲張りなあなたは「全部」って言ってみて。\\n\\nまた、あなたの写真、ビデオ、音声、今いる場所やスタンプを送ってくれると嬉しいな~";

callback.php


<?php

//エラー出力
error_log("callback start.");

//設定ファイル参照
require_once('config.php');


//==========================
// メッセージ受信処理
//==========================
$json_string = file_get_contents('php://input');
$json_object = json_decode($json_string);
$content = $json_object->result{0}->content;
$text = $content->text;
$from = $content->from;
$message_id = $content->id;
$content_type = $content->contentType;

# ユーザ情報取得
api_get_user_profile_request($from);

# 相手からのメッセが画像、動画、音声であれば保存
if (in_array($content_type, array(2, 3, 4))) {
    api_get_message_content_request($message_id);
}


//==========================
// 返答する内容生成
//==========================
# テキストが送られた時
$rule_content = <<< EOM
        "contentType":1,
        "text":"{$rule}"
EOM;
$image_content = <<< EOM
        "contentType":2,
        "originalContentUrl":"{$original_content_url_for_image}",
        "previewImageUrl":"{$preview_image_url_for_image}"
EOM;
$video_content = <<< EOM
        "contentType":3,
        "originalContentUrl":"{$original_content_url_for_video}",
        "previewImageUrl":"{$preview_image_url_for_video}"
EOM;
$location_content = <<< EOM
        "contentType":7,
        "text":"Convention center",
        "location":{
        "title":"{$original_content_location_name}",
        "latitude":"{$original_content_location_latitude}",
        "longitude":"{$original_content_location_longitude}"
        }
EOM;

# テキスト以外が送られた時
$image_content_msg = <<< EOM
        "contentType":1,
        "text":"{$get_image}"
EOM;
$video_content_msg = <<< EOM
        "contentType":1,
        "text":"{$get_video}"
EOM;
$audio_content_msg = <<< EOM
        "contentType":1,
        "text":"{$get_audio}"
EOM;
$location_content_msg = <<< EOM
        "contentType":1,
        "text":"{$get_location}"
EOM;
$stamp_content_msg = <<< EOM
        "contentType":1,
        "text":"{$get_stamp}"
EOM;


//==========================
// 相手からのメッセに応じての返答パターン
//==========================
$event_type = "138311608800106203"; /* これは固有値(変更不可) */
if ($text == "遊び方") {
    $content = $rule_content;
} else if ($text == "画像") {
    $content = $image_content;
} else if ($text == "動画") {
    $content = $video_content;
} else if ($text == "位置") {
    $content = $location_content;
} else if ($text == "全部") {
    $event_type = "140177271400161403"; /* これは固有値(変更不可) */
$content = <<< EOM
    "messageNotified": 0,
    "messages": [
        {{$image_content}},
        {{$video_content}},
        {{$location_content}}
    ]
EOM;
} else {
$content = <<< EOM
        "contentType":1,
        "text":"{$get_message_before}{$text}{$get_message_after}\\n\\n\\n\\n※「遊び方」と話かけると、遊び方の説明が出ます!"
EOM;
if ($content_type == 2) {
	$content = $image_content_msg;
} else if ($content_type == 3) {
	$content = $video_content_msg;
} else if ($content_type == 4) {
	$content = $audio_content_msg;
} else if ($content_type == 7) {
	$content = $location_content_msg;
} else if ($content_type == 8) {
	$content = $stamp_content_msg;
}
}


//==========================
// 送信処理
//==========================
$post = <<< EOM
{
    "to":["{$from}"],
    "toChannel":1383378250,
    "eventType":"{$event_type}",
    "content":{
        "toType":1,
        {$content}
    }
}
EOM;

api_post_request("/v1/events", $post);

error_log("callback end.");

function api_post_request($path, $post) {

    $url = "https://trialbot-api.line.me{$path}";
    $headers = array(
        "Content-Type: application/json",
        "X-Line-ChannelID: {$GLOBALS['channel_id']}",
        "X-Line-ChannelSecret: {$GLOBALS['channel_secret']}",
        "X-Line-Trusted-User-With-ACL: {$GLOBALS['mid']}"
    );

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($curl);
    error_log($output);
}

function api_get_user_profile_request($mid) {
    $url = "https://trialbot-api.line.me/v1/profiles?mids={$mid}";
    $headers = array(
        "X-Line-ChannelID: {$GLOBALS['channel_id']}",
        "X-Line-ChannelSecret: {$GLOBALS['channel_secret']}",
        "X-Line-Trusted-User-With-ACL: {$GLOBALS['mid']}"
    ); 

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($curl);
    error_log($output);
}

function api_get_message_content_request($message_id) {
    $url = "https://trialbot-api.line.me/v1/bot/message/{$message_id}/content";
    $headers = array(
        "X-Line-ChannelID: {$GLOBALS['channel_id']}",
        "X-Line-ChannelSecret: {$GLOBALS['channel_secret']}",
        "X-Line-Trusted-User-With-ACL: {$GLOBALS['mid']}"
    ); 

    $curl = curl_init($url);
    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($curl);
    file_put_contents("/tmp/{$message_id}", $output);
}

ダウンロードしたい人はどうぞ

button_download_orange

落としたzip解凍すると、「callback.php」と「config.php」があるから。

【お願い】これを使ってうまくいったよ!という方はSNSのシェアやコメント残しをしてくれると中の人が非常に喜びます

この記事全体でQiitaというプログラマ向けの技術情報共有サービスが本当に参考になりました。

関連記事

BUFFALO(バッファロー)製のNAS「LS410D0201」の純正バックアップ機能だと履歴管理バックアップが出来ないから、ネットブックにAcronis製「True Image」をインストして自前バックアップシステムを作ったなう

タイトル長すぎてうざくて死んで欲しいと思いますが。。。 ネットブックをN君から貰った話の続きと

記事を読む

お金がなくて、時給が低いことの楽しさ

こんなサイトをたまたま見つけました。 はじめての自作PCで自宅サーバーをはじめた PCケ

記事を読む

起業するときにおすすめのサービス【格安フリーダイヤル】 01

具体案が欲しい時ってありますよね。たまたまはてブで遊んでいるときにこんな記事を発見。 誰にでも

記事を読む

【WordPress】Contact Form 7でEnterキーを押すと勝手に送信されてしまう問題を解決する魔法のコード(JavaScript)

アイキャッチ画像はギャグとして(笑) 就職活動中の女子大生にJavaとJavaScri

記事を読む

SDカードからデジカメで撮影した写真が消えてしまった時の復元方法~データ削除したけど実際には消えていない?~

恋人への愛してるとバックアップは定期的に という有名な格言がなかったりなかったりしますが、バッ

記事を読む

zenbookのACアダブターを間違えて買ったので、プラグだけ買って作り直すの巻

zenbookかっちょいいですね!MacBook Airのパクリインスパイア系のウルトラブッ

記事を読む

注文住宅(マイホーム)を建てる 凄い工務店発見 キミドリ建築の謎

貧乏人も夢を見てもいいじゃない、というわけで。 前回3回に分けて工務店の探し方としてスーモカウ

記事を読む

【バーチャルホスト】サブドメイン・DNSの設定覚書 設定(サーバ)編 予備知識版

これの続きです。 前はDNSの設定編で今回は2ステップの最後サーバの設定です。

記事を読む

【PHP】曜日と時間を検出して、いつまでに対応するかを表示する

営業時間中であれば、お問合わせいただいてから何分以内に対応しますよという文句を自動で表示したい。

記事を読む

【google apps】バリュードメイン(value domain)のDNS設定覚書

タイトルそのまま mx ASPMX.L.GOOGLE.COM. 10 mx ALT1.A

記事を読む

Message

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

  • 高橋拓郎歳)
    愛知県知多市生まれ。
    大学在学中に個人で始めた事業を、大学院中退後法人化(法人化のために中退が正しいかも)。
    簡単にコンタクトとれるのでt@takuro.infoまで何か御用があればなんなりと。
    ブログの感想やご意見も大歓迎です!
人生はサウナ理論~結婚するあなたへ~

人生はサウナ理論。 というのを、敬愛するさんちゃんの名言「生きて

新紙幣とディープインパクトの単勝馬券

僕は大学生になり、そして20歳になった時に、それまで未成年で禁止されて

e-taxでの確定申告のもにょもにょ(noteからの転載)

この記事は2016年にnoteに投稿した記事の転載です。 ちょう

【感想】Netflixオリジナルドラマ『Jimmy〜アホみたいなホンマの話〜』 オクレさんもはや本人でしょ??

Netflixオリジナルドラマ『Jimmy〜アホみたいなホンマの話〜』

【javaScript】2017年版 法人税実効税率 シミュレーション 自動計算機(コードも置いとくね)

今日は4/3だからこれは嘘じゃないよ!! 法人税実効税率

→もっと見る

PAGE TOP ↑