2014年11月13日木曜日

smtpapi-ruby:サロゲートペア対応したよ

smtpapi-rubyサロゲートペア対応を入れてみました。

smtpapi-rubyはrubyでSendGridのx-smtpapiヘッダにセットする値を生成するためのライブラリです。x-smtpapiヘッダの値にはJSON文字列をセットするのですが、非ASCII文字はUnicodeエスケープする必要があります。で、さらにコードポイント0x10000以降の文字についてはサロゲートペアを使って符号化してあげる必要があります。
今回の対応で、x-smtpapi内(ありがちなのがSubstitutionとかSectionとかで文字を置換するケース)でサロゲートペアが必要な文字が文字化けせずにちゃんとメールが送れるようになったよ、っていうのが今回の記事の内容です。

早速試しに送ってみます。

ゴチャゴチャと読めない部分4文字がサロゲートペアが必要な文字列です。なんて読むのかはわかりませんが。けして文字化けしたわけじゃありません。というわけでSubstitutionの値として設定してもちゃんと置換してくれることが確認できました。

各文字のコードポイント 
0x291B0   
0x291B1   
0x291D3   
0x291D4   

やり方はわかったので他の言語のライブラリもやってみようかな。はたして使ってくれるが世界で何人いるかわかりませんが。

2014年11月12日水曜日

Mashup Battle 2ndSTAGE(Mashup Awards 10)参加してきました

はじめに

2014/11/8に開催されたMashup Battle 2ndSTAGE(MA10)に参加してきました。まなみさんに「ブログ書いてねー☆」とのお言葉をいただいたから、というわけではないですが、自分が参加したMAのイベントの振り返りも交えつつ書きます。

MAには今年初参加という新参者ですが、2ndSTAGEはとにかく楽しいイベントでした。API提供側という立場での参加だったので、今回は気楽なノリで参加したつもりだったのですが、会場に行ってみたら投票権がある、というのは完全に不意打ちでした。(50以上のプレゼン全部見なきゃいけないのかよ!みたいな。すみませんw)
でも、実際プレゼンが始まると楽しい、楽しい。あっという間の8時間でした。一般参加はできないイベントなので、参加させていただいて本当にありがとうございました。


プレゼン見てみなきゃわからない

今回のイベントに至るまで、多くの作品は事前にある程度オンラインで見て、それぞれの内容をなんとなく把握していたつもりでしたが、作者が自分の言葉で語るアツいプレゼンのインパクトは大きいですね。全然違った見え方をした(そして、本当の意味がようやく理解できた気がした)作品がいくつもありました。
あと、MA関連のハッカソン・アイデアソンに参加した際、一度実際に見ていた作品もいくつかあったわけですが、その多くが新しい機能を追加してきていて、同じ作品のはずなのにこれまた違った見え方ができました。

ちょっと振り返り

今年は、以下の関連イベントに参加しました。
(自分は作る立場ではなかったわけですが)ハッカソンは短い時間でモノを作り上げるあの緊張感とワクワク感がたまりません。個人的には最初に各自が考えたアイデアを他の参加者に(ある意味ドヤ顔で)説明するあの時間帯が一番好きです。

その他感じたこと

その他思いつく限りバラバラっと。
  • 2ndSTAGEで、アイデアソン・ハッカソンでお会いした方と再会できて嬉しかった
  • 直接サポートさせていただいた作品のうち5つが2ndSTAGEに進出、さらにFinalSTAGEに進出した作品もあってこれまた嬉しかった
  • 2ndSTAGEプレゼン当日のAM4時にサポートしていた作品の作者さまからAPIに関するヘルプ依頼がきてプレゼンが終わる瞬間までハラハラ。。。
  • 発表のたびに進化していく作品の凄さ
  • テーマ性のあるハッカソンで評価される作品と、テーマ性のない2ndSTAGEで評価される作品の違い。その両方で勝ち残っていくことの難しさ
  • MAって総合格闘技
  • MA事務局の素晴らしい進行と(恐らく大変であろう)事前準備に感心
  • (API提供側の立場として)APIの使い所の説明の難しさ
  • (同じく)短い時間でストレスなくAPIを使いこなしていただくための情報の準備の重要性
  • 一応、仕事で参加していることになってますが、97%くらいは個人的な楽しみで参加してます
  • 参加させてもらえて家族に感謝
あんまりまとまりありませんが、そんな感じです。
FinalSTAGE(と、その後の懇親会)が今から楽しみです。

    2014年10月5日日曜日

    Herokuボタンをつけてみた

    ちょっと前に作ったSendGrid-ReversiというサンプルアプリにHerokuボタンを付けてみました。


    デプロイが簡単に行えて楽しかったのでメモします。

    app.jsonという名前のファイルを適切なフォーマットで書いてプロジェクトルートに置いときます。そのうえで、README.mdあたりにHerokuボタンを貼り付けておけば準備完了です。

    app.jsonを見ると何となく分かるように、今回はAPP_URLとPARSE_HOSTという2つのパラメータがデプロイ時に必要になります。
    また、アドオンとしてmongohqとsendgridをいれてあります。これを入れておくと勝手にアドオンが追加されて環境変数に追加されるアクセス情報を使って各アドオンが利用できるようになります。

    この状態で上記リポジトリのREADME.md内のHerokuボタンを選択すると次のような画面が表示されます(Herokuアカウント持っていることが前提)。


    今回のアプリは、SendGridのParse Webhookを利用します。APP_URLにはWebhookのPOST先URLのルートを指定する必要があります。Herokuの場合、App Nameを指定しないと自動で名前がふられるため、このタイミングではAPP_URLが確定できません。これだと困るので、App Nameを指定した上で、その結果確定するこのアプリケーションURLをAPP_URLに設定するのが一番単純です。(アプリのURLを取得できればこんな冗長なパラメータは不要になるはずですが、取得方法があるのかはわかりませんでした)
    例えば、

    • App Name:abcd
    • APP_URL:abcd.herokuapp.com

    みたいな感じです。
    一方、PARSE_HOSTは、メール受信用のドメインです。手っ取り早く設定するのであれば、こちらの「5分間アプローチ」を参照します。サブドメインは未使用であればなんでもOKです。

    アプリケーション起動時にSendGridとMongoDB周りの設定を自動的に行なうようにしてあるので、細かな設定は一切不要です。

    一点注意ですが、内部で使用しているSendGridのEvent Webhookは設定変更後動作が有効になるまでに数分はかかるみたいです。デプロイ後すぐにゲーム開始しようとしてもうまくいきません。デプロイ後はコーヒー一杯くらい飲んで待っておくと良いと思います。

    Herokuマジすげー。

    2014年10月2日木曜日

    sendgrid4rを作ってみた

    SendGridのWeb API v3が公開されたのでsendgrid4rというgemを作ってみました。

    sendgrid4rはとりあえずSendGridのWeb API v3”だけ”をサポートしたライブラリです。今後v2をサポートするかどうかはわかりません。
    v3はちょっと前に公開されたTemplate Engine APIを含むRESTfulな新しいAPI群です。
    v3が出たからといってv2がすぐにdeprecateになるわけではないようです。
    というのも、今のところv3は、v2と被る機能(v2を置き換える機能)を提供していません。
    現時点で、以下の機能がありますが、今後もどんどん機能が追加されていく雰囲気を感じます。実はここに載っている機能の他にも、一瞬公開されてすぐに非公開にされた機能があります。公式ドキュメントの更新履歴をよく見るとわかると思います。

    • Advanced Suppression Manager(ASM)
    • IP Management
    • Enforced TLS(Settings)
    • Template Engine

    ASMは高度なUnsubscribeリスト機能で(特にマーケティングメール系の)色んな種類のメールの配信停止を個別に制御したい場合に使う機能
    IP Managementは送信するメールの種類毎に複数のIPアドレスを駆使して、メールの到達率を可能な限り高めたい場合に使う機能
    Enforced TLSは平文でメールが配送される経路を排除する場合に使う機能
    Template Engineは複数のテンプレートの管理をデザイナ側に移譲する場合に使う機能
    って感じでしょうか。

    そういえば一応、今回のsendgrid4rの設計思想的なものをメモしておきます。忘れっぽいので。

    今回目指したのは、以下の3点です。
    1. 機能追加を簡単に行えるようにしたかった
    2. APIのI/Fは全てSendGrid4r::Clientのインスタンスメソッドとして提供したかった
    3. ClientインスタンスごとにSendGridの認証情報を分離したかった

    v3は頻繁に機能追加されることが予想されるため、機能追加を簡単にするため、各サブ機能はmoduleとして実装して、これをClientクラスにincludeすることにしました。
    そうなった場合、各moduleにどうやって認証情報を渡すのかというと、Clientクラスのインスタンスのプロパティに認証情報をもたせるとmoduleから普通にアクセスできました。
    moduleってjavaでいうところのpublic static class的なものかと思っていたので、includeしたインスタンスのプロパティにアクセスできるというのが意外でした。
    ついでにmoduleには名前空間的な意味もあるみたいで、なんかこう、今までのjava的な頭からすると単純に置き換えることができないものなんだな、と感じました。

    ただ、この作りが最適かどうかはわかりません。Ruby初心者なので。Rubyのデザインパターンをいろいろ調べてみましたが、グッと来るパターンが見つからず結果このような実装となりました。
    もっといい方法があるよ的なまさかりがあれば是非ぶん投げて欲しい初秋の時分、何卒よろしくお願い申し上げる次第でございます。


    2014年8月31日日曜日

    Travis-CIで環境変数を使う

    前回紹介したSendGrid-ReversiでTravis-CIを使った際に気になった箇所のメモを残します。
    Travis-CIを使うためにはプロジェクト内に.travis.ymlという名前のファイルが必要です。とりあえず、リポジトリトップ下に置いてポチポチ設定すればいいみたいです。

    今回はこんな感じにしてみました。
    language: ruby
    rvm:
      - "2.0.0"
    #  - "2.1.0"
    env:
      - RACK_ENV=test
    services:
      - mongodb
    before_script:
      - bundle install
    script:
    - bundle exec rspec
    

    それぞれの詳細はTravis-CIのドキュメントを見ればよいのでポイントだけ。

    実行環境のバージョン指定は一つだけにしてみる

    実行環境としてRubyを使っており、通常複数バージョン指定できるのですが、今回はバージョンを一つだけ(上の例だと"2.0.0"だけ)に限定してみました。
    これは、テストケースでSendGrid APIを使っている関係上、複数環境でテストをするとテストが並列実行されてしまい、SendGridがテストケースの想定していない状態になってしまい失敗(テンプレート削除のテスト中にテンプレート作っちゃったり)するためです。実行環境毎のテストをシーケンシャルに走らせるためのオプションを見つけられなかったのですが、そんなのあるんですかね?
    SendGrid環境も分けるようにしないといけないんでしょうか。それはちょっとキツイなー、と。

    晒したくない情報は.travis.ymlではなくSettingsを使う

    環境変数は「env:」配下に書いておけばよいのですが、パブリックなリポジトリにアップされた .travis.ymlファイルは公開されてしまうため、晒したくない情報(サービスへのログイン情報など)は書けません。
    今回、SendGridへのアクセスを行なうテストケースがあったので、そういった情報をどこに置くかが問題となりました。調べてみるとそういう情報は「Settings」に書けってTravis-CIのヘルプに書いてありました。Settingsはリポジトリ毎に設定できます。
    .travis.ymlに書くのと同様、キーと値の組合せで書きますが、「Display value in build logs」をOFFにしておくと、非公開な環境変数として利用することができます。

    RACK_ENV=testを使ってみる

    この環境変数は、Rackアプリをプロダクションとかステージングみたいな感じで環境を切り替える時に使う変数みたいです。
    今回のアプリケーション内でこの環境変数を使っているのは、Mainクラスのconfigure部分(内部でSendGridの初期化を実行している)で、プロダクションのときだけconfigureするようにしています。
    こうしておいて、RACK_ENV=testにすると、rspecでテストケースが実行されるたびにconfigureが実行されてしまうのを避けることができました。

    module Reversi
      class Main < Sinatra::Base
        configure :production do
          begin
            settings = Settings.new
            Configure.init_sendgrid(settings)
          rescue => e
            puts e.backtrace
            puts e.inspect
          end
        end
    

    さいごに

    ほかにもMongoDB使ったり、テスト前に実行されるbefore_scriptでbundle installしていたりします。
    ちょっと前までは「CIなにそれうまいの」状態でしたが、テストツールと同様、一度使ってしまうと、もう不安で不安で使わない状態には戻れませんね。麻薬みたいな効果があります。

    2014年8月30日土曜日

    SendGridをゲームプラットフォームとして使ってみました

    きっかけ

    SendGridには多くのAPIがあって、どれをどういう風に使うのかがピンときていませんでした。で、自分含めそんな人向けに、SendGridのAPIをできるだけ多く使ってそれぞれの使い所をイメージしやすいモノを作ってみようと思いできあがったのがこのアプリケーションです。

    できること

    メールを介してオセロができます。
    ソースコードはこちらで公開しています。

    中で何をやっているか

    こんな感じで動作します。

    • 0:アプリケーション初回起動時
      • Web API/Template Engine APIを使ってSendGridの設定を自動的に変更します。設定が自動化されると、設定手順をドキュメント化する手間が減って楽ですよね。
        • SendGrid上にTemplateを作成します
        • Event Notificationを設定してEvent Webhookを有効化します
        • Parse Webhookを設定、有効化します
        • Click Trackingを有効化します
    • 1:ゲームの開始
      • Parse Webhook機能に設定したアドレスにメール(件名に相手プレイヤーのアドレスを設定)を送るとSendGridは受信したメールを解析して、Reversi Web AppにPOSTします。POSTを受けたアプリケーションはMongoDB上にゲームデータを生成します。
      • アプリケーションはSendGrid経由で各プレイヤーにメッセージおよびゲームボードのメールを送ります。
    • 2:クリック
      • ゲームボードのメール上で石を置きたい場所をクリックすると、クリックイベントがSendGridからReversi Web AppにPOSTされます。ここではEvent WebhookとClick Tracking機能を使っています。
      • クリックイベントはGETでアプリケーションに直接アクセスしても良いのですが、Click Trackingは元URLを隠ぺいするので、今回のアプリではなりすましを防ぐ意味合いがあります。(本当は単に使いたかっただけで、理由は後付です)

    テキストメール

    このアプリでは、マルチパートでテキストメールにも対応しています。
    対応してみてテキストメール死ねって思いました。


    その他

    Ruby

    プログラミング言語を何にしようかと思いましたが、この人を見つけてRubyにしてみました。というわけで目下勉強中です。

    Sinatra

    RubyでWebフレームワークと言えばRailsですが、Railsの入門書読んでて眠くなったのでSinatraで作ってみました。

    MongoDB

    MongoDBをちゃんと使ったことがなかったので使ってみました。代わりにSQLiteでもいいと思います。MongoDBだとSQLが使えないので、ちょっと学習する必要はありますが、オブジェクトをそのまま保存できるので、シンプルでコード量を減らせます。実際、楽でした。

    RSpec

    テストフレームワークとしてrspecとrack-testを使ってみました。RubyのWebフレームワークでテストと言えばこのあたりが一般的なんですかね?ググったらいっぱいヒットしたので使ってみました。よくわかりませんが。

    Travis-CI

    「今どきCIツールは普通に使うよね」ってぐらいの空気を感じるのでとりあえず使ってみました。GitHubにpushするとテストして結果を通知するだけです。しかし、JenkinsとかTravis-CIってなんでヒゲのオッサンなんでしょうね。どうせ2次元にするなら女の子にした方がいいと思います。

    sendgrid_ruby

    一応、お仕事で作ったライブラリを有効活用できました。たまたまです。

    sendgrid_template_engine_ruby

    Rubyの練習用に作ったライブラリを有効活用してみました。これもたまたまです。使ってみてはじめて「こんな使い方をするんだなぁ」って認識しました。

    さいごに

    こんなのでAPIの使い所が伝わったのでしょうか?よくわかりませんが。公開してみて嬉しかったのが、GitHubでStarを付けてくれたのがGridderばかりということでした。
    今回、色々はじめてのことが多かったので、自分の中で再利用できるようにそれぞれ個別のネタとして記事をまとめていこうと思います。とりあえず、今回はこの辺で。

    2014年7月16日水曜日

    SendGrid Template Engine APIのRuby gemを作ってみた

    Rubyの練習用にSendGridのTemplate Engine APIをラップするgemを作ってみました。

    Template Engine APIはSendGridが提供するAPIのうち現時点で最も新しいAPIで、JSONベースのRESTfulなWeb APIです。エンドポイントURLを見てわかるように、

    https://api.sendgrid.net/v3/resources

    バージョン3だそうです。今までのAPIはだいたいver2ぐらいでした。これまでのAPIは、基本的にJSONとXML両方をサポートしていましたが、v3以降はJSONのみサポートします。さらばWeb Services、XMLってことなんでしょうね。それでいいと思います。
    他に新しい要素としては、

    • 基本認証で認証
    • HTTPSのみサポート
    • Rate Limitsの導入
    • Paginationの導入

    といったあたりがあげられます。

    認証が基本認証になったことで、認証パラメータの扱いが標準的になり、curlとの親和性が高まって扱いが楽になりました。もちろん、標準的なRestクライアントなライブラリでも扱いが楽です。
    Rate Limitsは一定時間にリクエストを呼び出せる回数を制限する機能です。応答に、X-RateLimit-*といったヘッダがついてくるので、これを見るとあと何回APIをコールできるのかを知ることができるようです。
    Paginationは取得開始位置を指定してレコード取得することができる機能です。大量レコードを扱うAPIで重宝しそうです。現時点で公開されているTemplate Engine APIではサポートされていないようですが。

    ドキュメントの内容を眺めていると、今後SendGridのAPIはこのv3ベースに移行していくんじゃないかな、という雰囲気が感じられます。既存のAPIをv3ベースで実装し直すかどうかはわかりませんが、少なくとも今後提供される新しいAPIはv3ベースになるのでしょう。

    APIの分量も適度に少なくてラッパ実装の練習用には最適でした。