2016年4月2日土曜日

Perl の LWP でニフティクラウドモバイルバックエンドにプッシュ通知を登録してみた

概要

タイトルの通りです
ニフティクラウドモバイルバックエンド (以下、NCMB) にプッシュ通知を登録する Perl スクリプトを作成してみました

環境

  • CentOS 6.7 64bit
  • Perl 5.10.1
  • Cpanm 1.7039

Cpanm のインストール

  • cd /var/tmp
  • wget https://cpanmin.us -O install_cpanm.pl
  • perl install_cpanm.pl - --sudo App::cpanminus

ライブラリのインストール

cpanm を使って LWP で https をコールするために必要なライブラリをインストールします

  • cpanm Crypt::SSLeay
  • cpanm Mozilla::CA

Crypt::SSLeay をインストールするときに「Building and testing Net-HTTP-6.09 …」のフェーズで結構時間がかかりました

登録用スクリプト

スクリプト全体は以下の通りです
スクリプト冒頭の $ak, $ck は各自が作成したアプリケーションキーとクライアントキーを指定してください

  • vim send_push.pl
#! /usr/bin/perl
use warnings;
use strict;
use autodie;
use LWP::UserAgent;
use DateTime;
use Digest::SHA qw(hmac_sha256_base64);

my $ak = 'Please input your application key';
my $ck = 'Please input your client key';
my $endpoint = 'mb.api.cloud.nifty.com';
my $version = '2013-09-01';
my $path = 'push';
my $method = 'POST';
my $uri = "https://${endpoint}/${version}/${path}";
print $uri, "\n";
my $req = HTTP::Request->new( $method, $uri );
$req->header( 'Content-Type' => 'application/json' );
$req->header( 'X-NCMB-Application-Key' => $ak );
my $timestamp = &getTimestamp;
my $sig = &getSignature($method, $endpoint, "/${version}/${path}", "", $ak, $ck, $timestamp);
$req->header( 'X-NCMB-Signature' => $sig );
$req->header( 'X-NCMB-Timestamp' => $timestamp );
my $json = '{"immediateDeliveryFlag":true,"target":["ios"],"message":"test"}';
$req->content( $json );

my $lwp = LWP::UserAgent->new();
my $res = $lwp->request( $req );
print $res->content, "\n";

sub getTimestamp {
  my $dt = DateTime->now( time_zone=>'local' );
  return $dt->strftime('%Y-%m-%dT%H:%M:%S.456Z');
}

sub getSignature {
  my $method = $_[0];
  my $endpoint = $_[1];
  my $path = $_[2];
  my $queryString = $_[3];
  my $ak = $_[4];
  my $ck = $_[5];
  my $timestamp = $_[6];
  my $sigMethod = 'HmacSHA256';
  my $sigVer = '2';
  my %headers;
  $headers{'SignatureMethod'} = 'HmacSHA256';
  $headers{'SignatureVersion'} = '2';
  $headers{'X-NCMB-Application-Key'} = $ak;
  $headers{'X-NCMB-Timestamp'} = $timestamp;
  my $strh = '';
  foreach my $key (sort keys %headers) {
    $strh = $strh . '&' . $key . '=' . $headers{$key};
  }
  $strh = substr($strh, 1);
  my $strToSign = $method . "\n" . $endpoint . "\n" . $path . "\n" . $strh;
  print $strToSign . "\n";
  my $sig = hmac_sha256_base64($strToSign, $ck);
  while (length($sig) % 4) {
    $sig .= '=';
  }
  print $sig , "\n";
  return $sig;
}

実行は

  • perl send_push.pl

で OK です
プッシュ通知の内容は my $json で指定しているので適宜変更してください
とりあえずライブラリが正常にインストールされて、NCMB 側でプッシュ通知が送信できる準備ができていれば問題なく登録できるはずです

最後に

とりあえずプッシュ通知が登録できる Perl スクリプトを作成してみました
Perl 標準でインストールされている LWP を使っています

POST の部分を GET に変更すればプッシュの一覧を取得できるのは確認しています
他の API も $path 部分を変更すればコールできると思います ( 動作確認は実施していません )
全然 SDK っぽくないので、ちゃんと作るなら Cpan で配布できるようにモジュール化しないとダメだと思います

3 件のコメント:

  1. クエリストリングのところが空でいいなんて衝撃です。
    NCMBのプッシュ通知のスライド解説を見ても、ここは空でいいとは書いていません。
    自分はてっきりJSON形式にする部分がクエリストリングなのかなと勘違いして、これをバラして署名用バラメータに突っ込んでました。

    返信削除
  2. usotch さん

    動いたということでよかったです
    NCMB は REST-full API でパラメータを送信する際に GET ではクエリストリングとして送信し POST, PUT の場合はリクエストボディとして送信するようです
    確かにこの辺りは詳細に明記していなさそうなので usotch さんのように SDK にない言語で API をコールしようとしたときに迷いそうですね
    自分の場合は一度 Ruby で作成していたからわかっていたという感じでしょうか

    なにせよ動いてよかったです

    返信削除
  3. http://www.slideshare.net/mobilebackend/3-restapi
    38ページ目で署名作成にクエリストリングスが必要と説明があって、尚且つプッシュ通知には関係の無い「where=」とか「count=」の例を示してるんです。
    27ページ目に「プッシュ通知はPOSTメソッドで」と書いてあるので、なんか辻褄が合わないなぁとは思っていたんですが、『自分の調べ方が足りないだけで、プッシュ通知用の引数がどっかに書いてあるのかもしれない。』と思って必死に探したりしてましたTーT

    kakakikikekeさんには感謝しかありません。

    返信削除