*

【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というプログラマ向けの技術情報共有サービスが本当に参考になりました。

関連記事

【結婚式二次会のゲームなどにおすすめ】めくりフリップ 自作 手作り 作り方 材料 で検索にひっかかれ!!

先日友達の結婚式の二次会の幹事をやりました。 その中でゲームの中でめくりフリップあった方がいい

記事を読む

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

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

記事を読む

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

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

記事を読む

【PHP】時間を扱うときはdate_default_timezone_set(‘Asia/Tokyo’);を入れよう

タイトルそのまんま。そんだけ。 日本国内のサービスでphpで時間を扱うときは、サーバの設定いじ

記事を読む

【PHP】メールフォーム 一度入力した内容が消えてしまう時 POST使って入力内容を保持 ~メールフォームパッケージダウンロードあり~

前に、 【PHP】スマホ対応 メールフォーム設置 PEARを使ってgmailのsmtpサーバで

記事を読む

lightbox クリック前

lightbox(ライトボックス)のie9のバグの修正方法(って言っても新しいバージョン入れなおすだけ)

lightboxっていう無料のJavaScriptがあるの知ってますか? lightboxダウ

記事を読む

【バーチャルホスト】サブドメイン・DNSの設定覚書 概要編

サブドメインをやろうと思いました。 サブドメインをやる目的は自分のサイトがexam

記事を読む

【jQuery】Chart.jsを使って簡単にカッコイイレーダーチャートを実装するの巻

友達の結婚式のプロフィールムービーが終わって一息ついていた頃。。。 いつもお世話になっている弁

記事を読む

【バーチャルホスト】サブドメイン・DNSの設定覚書 設定(サーバ)編 いざ!版

これの続き では、いよいよ設定です。 まず設定するファイルは一個だけ

記事を読む

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

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

記事を読む

Message

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

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

  • 高橋拓郎(32歳)
    愛知県知多市生まれ。
    大学在学中に個人で始めた事業を、大学院中退後法人化(法人化のために中退が正しいかも)。
    簡単にコンタクトとれるのでt@takuro.infoまで何か御用があればなんなりと。
    ブログの感想やご意見も大歓迎です!
【javaScript】2017年版 法人税実効税率 自動計算機(コードも置いとくね)

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

【ユーザー車検】軽トラを無料でGETしたけど車検代が無いから初の軽自動車ユーザー車検に挑戦!

青春カーと悲しい別れ どうも。貧乏が板に付いてきて久しい僕で

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

BOT API Trial Accountってのが、公開されたので、L

【電気自動車】日産リーフの無料モニターに当選して2週間使ってみたけれども。。。結論的に購入は時期尚早??

どうも。実写版とってもラッキーマンこと僕です! とっても!ラッキ

追尾メニューのAdSense削除の件

このサイトへのお問い合わせで、以下のような内容のご指摘を頂きました。

→もっと見る

PAGE TOP ↑