読者です 読者をやめる 読者になる 読者になる

Ola Kae Tode Tai

すべてのエンジニアに、追い風を祈る

LINE BOT APIでボットを作ってみた

LINE Ruby Rails Heroku

f:id:kironono:20160409194855p:plain

LINEのメッセージングAPIがオープン化されるようで、その一歩としてボットアカウント用の開発APIである「BOT API Trial Account」が公開されたみたいです。

2016年4月7日現在、先着10000アカウント分のBOTアカウント(TRIAL_BOT)が無償で提供されています。

BOT API Trial Account の取得は LINE BUSINESS CENTER から登録することで利用できるようになります。

business.line.me

本日登録したところ、BOT API Trial Accountを作成できたので Ruby / Rails でEchoボットを作ってみました。

API呼び出しを試してみる

BOT API Trial Account を作成すると、LINE Developers の管理画面からBOT APIのトークン等が取得できます。また Callback URL を設定することで、BOTがメッセージを受信したときに、HTTPS POSTで任意のURLを呼び出してくれます。

f:id:kironono:20160409200822p:plain

とりあえず、BOTアカウントが作成できているか確認するには、BOT自身のプロフィールを取得するAPIを叩いてみるとよいかもです。

$ curl -H "X-Line-ChannelID: {Channel ID}" \
-H "X-Line-ChannelSecret: {Channel Secret}" \
-H "X-Line-Trusted-User-With-ACL: {MID}" \
-XGET https://trialbot-api.line.me/v1/profiles?mids={MID}

正しくAPIが呼べると下のようなレスポンスが得られます。

{
  "contacts":[
    {
      "displayName":"tricolore",
      "mid":"{MID}",
      "pictureUrl":"http://dl.profile.line-cdn.net/0m01541c4d725102ba8dc4186ec8d2f1818c16fd2c19f9",
      "statusMessage":""
    }
  ],
  "count":1,
  "display":1,
  "pagingRequest":{
    "start":1,
    "display":1,
    "sortBy":"MID"
  },
  "start":1,
  "total":1
}

APIの呼び出し元のIPアドレスはServer IP Whitelistで事前に設定しておく必要がある点に注意が必要です。

EchoボットをRailsアプリとして作る

github.com

module LineBotApi

  class Client
    TO_CHANNEL = 1383378250
    EVENT_TYPE = "138311608800106203"
    EVENT_URL = 'https://trialbot-api.line.me/v1/events'
    attr_accessor :channel_id, :channel_secret, :channel_mid, :proxy

    def initialize(options = {})
      options.each do |key, value|
        instance_variable_set("@#{key}", value)
      end
    end

    def credentials
      {
        "X-Line-ChannelID": channel_id,
        "X-Line-ChannelSecret": channel_secret,
        "X-Line-Trusted-User-With-ACL": channel_mid,
      }
    end

    def send_text_message(to, message)
      RestClient.proxy = proxy unless proxy.nil?
      request_headers = credentials.merge({
        "Content-Type": "application/json",
      })
      request_params = {
        to: [to],
        toChannel: TO_CHANNEL,
        eventType: EVENT_TYPE,
        content: {
          contentType: 1,
          toType: 1,
          text: message,
        }
      }
      RestClient.post EVENT_URL, request_params.to_json, request_headers
    end

  end
end
class MessageReceivesController < ApplicationController

  protect_from_forgery with: :null_session
  before_action :get_client

  def callback
    params[:result].each do |result|
      from = result[:content][:from]
      text = result[:content][:text]
      @client.send_text_message(from, text) if text.present?
    end
    render json: [], status: :ok
  end

  private

  def get_client
    options = {
      channel_id: ENV['LINE_CHANNEL_ID'],
      channel_secret: ENV['LINE_CHANNEL_SECRET'],
      channel_mid: ENV['LINE_CHANNEL_MID'],
      proxy: ENV['FIXIE_URL'],
    }
    @client = LineBotApi::Client.new(options)
  end

end

こんな感じでコントローラとLINE BOT API呼び出し部分を作って、Herokuにデプロイしてみました。

Callback URLの設定

Callback URL に設定できるのは、https のみのようです。さらに、 https://example.com:443/callback のようにポート番号も含めないと登録できませんでした。

また、利用するSSL証明書によってはCallback URLが呼び出されないようです。(Rapid SSL はダメな模様) 今回Herokuにデプロイしたので、最初から有効になっている https://{app-name}.herokuapp.com を使いました。

Server IP Whitelist の設定

BOT API の呼び出し元IPアドレスを予め登録して置かなければなりませんが、Herokuの場合IPアドレスが変わってしまうので、Fixie アドオンを使います。 Fixieを経由することでアウトバウンドのIPアドレスを固定することができます。

f:id:kironono:20160409202813p:plain

2種類のアウトバウンドIPアドレスが発行されるので2つともWhitelistに登録しておきます。

試してみる

LINE Developers の管理画面に表示されているQRコードから友達追加をして、トーク画面を開きます。

f:id:kironono:20160409204028p:plain

適当にメッセージを送るとそのままオウム返しするボットが出来上がりました。

単純なテキストメッセージのみ試してみましたが、画像、動画、スタンプの送信、リッチメッセージの送信等いろいろできるみたいです。

正式にメッセージングAPIがオープン化されるまで、トライアルアカウントはきっと使えると思うのでいろいろ試してみようと思います。 ちなみに、トライアルアカウントは友だち登録可能なユーザー数が50名までに制限されているのであくまでお試し用途ですね。

i-dioのプレ放送開始「i-dio Wi-Fi Tuner」で視聴してみた

i-dio レビュー Android iOS

f:id:kironono:20160301215829p:plain

2016年3月から新放送サービスのi-dioのプレ放送が始まりました。

i-dio

i-dioは地上アナログテレビ放送が終了して空きになった周波数帯を利用する放送サービスで、ラジオや映像コンテンツを放送するデジタル放送サービスです。 正式サービスイン前のプレ放送が2016年3月1日から東京、大阪、福岡で開始されます。

i-dio Wi-Fi Tuner

今のところ放送を受信するには、「i-dio Wi-Fi Tuner」という機器を使うか、既に発売されているスマートフォン「i-dio Phone」が必要です。 「i-dio Wi-Fi Tuner」はチューナーで、受信した放送をWi-Fiに変換して専用のスマホアプリで受信できるようにしてくれるものです。 このチューナーはまだ発売されていないので、モニターに応募する必要があります。

www.i-dio.jp

2月に無料モニターに応募していたので、「i-dio Wi-Fi Tuner」は既に手元にあったのですが、iOS用の受信アプリがリリースされておらず部屋の隅に放置されたままになっていました。

プレ放送開始

プレ放送開始時刻の2016年3月1日 12:00になってもiOS用の受信アプリは公開されておらず、どうも間に合わなかった模様。

ですが、同日の夕方くらいになって公式TwitteriOSアプリリリースのお知らせがツイートされました。

早速アプリをiPhoneにインストールして聞いてみました。

iPhoneをi-dio Wi-Fi Tunerに接続するには、i-dio Wi-Fi Tunerの電源ボタンを長押ししてAPモードで起動する必要がある点に注意。 Androidと接続するときは、電源ボタン単押しのダイレクト接続モード(アドホック接続?)にする必要がある。

アプリを起動すると、性別、生年、視聴地域等のユーザー情報を入力し、チャンネルのスキャンが開始する。

f:id:kironono:20160301213923p:plain

暫く待つとチャンネル選択画面になるので、選局すると番組を視聴できる。 デジタル放送だけあって音質は良いです。

今後、ハイレゾ級音質 (96kHz音源) での放送予定もあるらしい。

f:id:kironono:20160301215245p:plain

選局+データ放送のコンテンツ受信が行われるので、意外とまたされる印象。その間、画面が操作できないのでちょっと残念..ではあるけど、そこはアプリの作りの問題のような気がするので今後改善されていけば良いと思う。

放送波の入りやすさは場所によると思うけど、部屋の窓際でないと選局に失敗してしまう。 どうせWi-Fi接続なのでチューナー本体は電源に繋いで窓際に置いておいて、Wi-Fiの届く範囲でスマホで視聴する。という利用方法が良さそう。

Railsアプリケーション作成(rails new)の覚え書き

Ruby Rails

Ruby on Railsアプリケーションを作成するときの備忘録です。

アプリケーションで使うRubyのバージョンをrbenvで固定

$ mkdir myproj
$ cd myproj/
$ rbenv local 2.2.4
$ ruby -v
ruby 2.2.4p230 (2015-12-16 revision 53155) [x86_64-linux]

Gemfileを作成、編集

$ bundle init
$ echo 'gem "rails"' >> Gemfile

Railsをインストール

$ bundle install --path=./vendor/bundle --jobs=4

Railsアプリケーションを作成する

  • bundle installを行わない
  • javascriptを組み込まない
  • データベースの種類をMySQLにする
$ bundle exec rails new . --skip-bundle --skip-javascript --database=mysql

Gemfileを上書きしていいか聞かれるので Y で続行する。

あとはアプリケーションに応じてGemfileを編集して bundle install でインストール。

$ bundle install

Gitリポジトリを作成

/vendor/bundle.gitignore に追加して除外して、gitリポジトリを作成します。

$ echo "/vendor/bundle" >> .gitignore
$ git init
$ git add .
$ git commit

Ubuntu14.04にElasticsearch 2.1.1をインストールする

Elasticsearch Ubuntu

Ubuntu14.04にElasticsearch 2.1をインストールする方法の備忘録です。

f:id:kironono:20160125131108j:plain

ElasticsearchはLuceneベースの全文検索エンジンです。

Elasticsearch | Elastic

Elasticsearchの勉強をするためにインストールしてみます。Ubuntu14.04は適当なVagrant boxを探してきて用意しました。

構成

Elasticsearch 2.1.1はOracleかOpenJDKのJava 8 update 20またはJava 7 update 55より新しいバージョンのJVMが必要です。 今回はOpenJDKを使います。

  • Ubuntu 14.04
  • OpenJDK 1.8.0_72
  • Elasticsearch 2.1.1

OpenJDKをインストール

openjdk-8-jdkパッケージのインストール

OpenJDKのリポジトリを追加して、openjdk-8-jdkをインストールします。

vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get update
vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get install software-properties-common
vagrant@vagrant-ubuntu-trusty:~$ sudo add-apt-repository ppa:openjdk-r/ppa
vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get update
vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get install openjdk-8-jdk

JAVA_HOME環境変数を設定

デフォルト環境変数JAVA_HOMEを設定して、再読み込みします。

vagrant@vagrant-ubuntu-trusty:~$ echo 'JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"' | sudo tee -a /etc/environment
JAVA_HOME="/usr/lib/jvm/java-8-openjdk-amd64"
vagrant@vagrant-ubuntu-trusty:~$ source /etc/environment

バージョンの確認

インストールしたJavaのバージョンを確認します。

vagrant@vagrant-ubuntu-trusty:~$ java -version
openjdk version "1.8.0_72-internal"
OpenJDK Runtime Environment (build 1.8.0_72-internal-b05)
OpenJDK 64-Bit Server VM (build 25.72-b05, mixed mode)
vagrant@vagrant-ubuntu-trusty:~$ javac -version
javac 1.8.0_72-internal

Elasticsearchをインストール

リポジトリを追加

Elasticsearch 2.xのリポジトリを追加します。

vagrant@vagrant-ubuntu-trusty:~$ wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
OK
vagrant@vagrant-ubuntu-trusty:~$ echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
deb http://packages.elastic.co/elasticsearch/2.x/debian stable main

Elasticsearchをインストール

パッケージリストを更新して、Elasticsearchをインストールします。

vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get update
vagrant@vagrant-ubuntu-trusty:~$ sudo apt-get install elasticsearch

自動起動の設定

システム起動時にelasticsearchサービスが起動するようにします。

vagrant@vagrant-ubuntu-trusty:~$ sudo update-rc.d elasticsearch defaults 95 10
 Adding system startup for /etc/init.d/elasticsearch ...
   /etc/rc0.d/K10elasticsearch -> ../init.d/elasticsearch
   /etc/rc1.d/K10elasticsearch -> ../init.d/elasticsearch
   /etc/rc6.d/K10elasticsearch -> ../init.d/elasticsearch
   /etc/rc2.d/S95elasticsearch -> ../init.d/elasticsearch
   /etc/rc3.d/S95elasticsearch -> ../init.d/elasticsearch
   /etc/rc4.d/S95elasticsearch -> ../init.d/elasticsearch
   /etc/rc5.d/S95elasticsearch -> ../init.d/elasticsearch
vagrant@vagrant-ubuntu-trusty:~$ sudo service elasticsearch start
 * Starting Elasticsearch Server                                                                                          [ OK ]

Elasticsearchの起動確認

デフォルトでは9200ポートでリッスンしています。 curllocalhost:9200 にアクセスするとノードの情報が返ってきます。

vagrant@vagrant-ubuntu-trusty:~$ curl -XGET localhost:9200
{
  "name" : "Ringo Kid",
  "cluster_name" : "elasticsearch",
  "version" : {
    "number" : "2.1.1",
    "build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71",
    "build_timestamp" : "2015-12-15T13:05:55Z",
    "build_snapshot" : false,
    "lucene_version" : "5.3.1"
  },
  "tagline" : "You Know, for Search"
}

プラグインをインストール

Elasticsearchでよく利用するプラグインをインストールしておきます。

analysis-kuromoji は日本語の分かち書きのためのプラグインです。

analysis-icuUnicode正規化をおこなうためのプラグインです。

lmenezes/elasticsearch-kopf はノードの管理をGUIで行なうことができるプラグインです。

github.com

analysis-kuromojianalysis-icu はElasticsearch 2.x になって公式がリリースするようになったようです。

vagrant@vagrant-ubuntu-trusty:~$ cd /usr/share/elasticsearch/
vagrant@vagrant-ubuntu-trusty:/usr/share/elasticsearch$ sudo bin/plugin install analysis-kuromoji
vagrant@vagrant-ubuntu-trusty:/usr/share/elasticsearch$ sudo bin/plugin install analysis-icu
vagrant@vagrant-ubuntu-trusty:/usr/share/elasticsearch$ sudo bin/plugin install lmenezes/elasticsearch-kopf

Elasticsearchの設定

開発環境用に設定を変更しておきます。

network.host はElasticsearch 2.xからデフォルトでlocalhostにバインドされるようになったようです。開発環境では外のIFからもアクセスしたいので指定しています。

vagrant@vagrant-ubuntu-trusty:~$ cat << EOF | sudo tee -a /etc/elasticsearch/elasticsearch.yml
> index.number_of_shards: 1
> index.number_of_replicas: 0
> network.host: 0.0.0.0
> EOF
index.number_of_shards: 1
index.number_of_replicas: 0
network.host: 0.0.0.0

再起動して設定を反映

再起動して、設定とプラグインを反映させます。

vagrant@vagrant-ubuntu-trusty:~$ sudo service elasticsearch restart
 * Stopping Elasticsearch Server                                                                                          [ OK ]
 * Starting Elasticsearch Server                                                                                          [ OK ]

KOPFの画面

http://localhost:9200/_plugin/kopf/ にブラウザでアクセスするとKOPFの画面が開きます。

ここからノードの状態を管理したり、簡単なクエリを発行したりできるみたいです。

(まだインデック等なにもない状態)

f:id:kironono:20160125125055j:plain

Elasticsearchに関する書籍

日本語の書籍は結構古いバージョンのElasticSearchのものしかないようです。

高速スケーラブル検索エンジン ElasticSearch Server

高速スケーラブル検索エンジン ElasticSearch Server

今のところ公式のドキュメントが一番よいみたいです。

Elasticsearch Reference [2.1]

Electric ImpでPWMを使ってLEDの明るさを制御する

ElectricImp Squirrel 電子工作

この投稿は Electric Imp Advent Calendar 2015 の11日目の記事です。

f:id:kironono:20151201001226p:plain

PWM制御

PWMとはPulse Width Modulationの略で、日本語ではパルス幅変調といいます。

パルス幅変調 - Wikipedia

一定の周期でON/OFFを繰り返すパルス信号のONとOFFの幅の比を調節することで元の電圧から1/5の電圧とか4/5電圧を作ることができます。

ElectricImpのGPIOどのポートでもPWMを使うことができます。

今回はElectricImpのPWM出力を使ってLEDの明るさを変化させてみます。

回路

f:id:kironono:20151203234528p:plain

利用する回路は以前のLチカの回路とおなじです。PIN9にLEDを接続しています。

デバイスのコードを書く

led <- hardware.pin9;
led.configure(PWM_OUT, 1.0 / 400, 0.0);

ledState <- 0.0;
ledChange <- 0.1;
 
function pulse() {
    led.write(ledState);
    
    ledState = ledState + ledChange;
    
    if (ledState >= 1.0 || ledState <= 0.0) {
        ledChange = ledChange * -1.0
    }
    
     imp.wakeup(0.05, pulse);
}

pulse();

WebIDEのデバイスパネルに上のコードを書きます。

led <- hardware.pin9;
led.configure(PWM_OUT, 1.0 / 400, 0.0);

PIN9の設定を行っています。PWM出力を使うので configurePWM_OUT と設定しています。2番目の引数は周期Tです。ここでは400Hzとしたいので 周期T = 1 / 周波数f を計算しています。3番目の引数はデューティー比Dの初期値です。最初はLEDをOFFの状態にしておきたいので 0 にしています。

led.write(ledState);

ここでPWM出力としたPIN9のデューティー比を設定しています。ここには 0.0 〜 1.0 までの値を設定します。仮に led.write(0.5) とするとデューティー比は0.5でLEDの明るさはだいたい半分になります。(LEDがONになっている時間が半分)

あとはLチカのときと同様に imp.wakeup を使って定期的に pulse 関数を実行するようにしています。

まとめ

PWM制御はモーターの制御や、今回のLEDのようにLCDモニターの輝度調整に使われていてとても身近なものです。いろいろ利用できそうですね! imp001はどのピンでもPWM出力が使えますが、ほかのImpの場合、どのピンがPWM出力に使えるかは以下から確認できます。

electricimp.com