mixi Graph API Sample for Delphi

はじめに

これは Delphi Advent Calendar 2012の12/4の記事になります。
この記事では、mixi Graph APIDelphiから扱うサンプルコードについて書いています。

事前準備

mixi Graphi API を利用するためには、mixi Developer Centerから個人パートナー登録の必要があります。
登録の際、身分証明のため携帯もしくはスマートフォンのメールアドレスとクレジットカード認証が求められます。(利用にお金がかかるわけではなく、あくまで信用を保証するためです。)
さらに、Graph APIを利用するサービスの登録をPartner Dashboardから登録します。登録が完了すると、Consumer KeyとConsumer Secretが発行されます。これらはサンプルプログラムを動かす際に必要になります。
またサービス登録時にリダイレクトURLの入力が求められます。これはサンプルプログラムを動作させる際に必要になりますので、同一性を保ってください。

Graph API利用の流れ

今回、mixi Graph APIを利用してmixi上のプロフィール情報の取得を目指します。
そのためには以下の手順が必要になります。

  1. 認可とAuthorization Codeの入手
  2. アクセストークンの入手
  3. APIアクセスによるプロフィール情報の取得


詳細については以下のドキュメントを参照ください。
http://developer.mixi.co.jp/connect/mixi_graph_api/api_auth/

サンプルコード

ここまでDelphiには無関係の内容を書いてきましたが、いよいよDelphiのコードについて述べていきます。

mixi Graph APIではhttpsでの通信やJSONのパースが求められます。これらを実現するために、今回のサンプルコードでは以下のライブラリを利用しています。
サンプルコードを実行する場合は以下のライブラリを事前に入手しておいてください。

以下はプロフィール情報を取得するためのコードになります。
実際に動作させる場合は、各自、CONSUMER_KEY、CONSUMER_SECRET、REDIRECT_URIを書き換えてください。

MixiGraphAPI.dpr
program MixiGraphAPI;

{$APPTYPE CONSOLE}


{%DotNetAssemblyCompiler 'libeay32.dll'}
{%DotNetAssemblyCompiler 'ssleay32.dll'}

uses
    SysUtils,
    Classes,
    IdHttp,
    IdSSLOpenSSL,
    IdSSLOpenSSLHeaders in 'lib\IdSSLOpenSSLHeaders.pas',
    superobject in 'lib\superobject.pas',
    superxmlparser in 'lib\superxmlparser.pas';

var
    http: TIdHttp;
    params: TStringList;
    ssl: TIdSSLIOHandlerSocketOpenSSL;
    token_res, profile_res, code, profile_endpoint: String;
    token_json, profile_json: ISuperObject;

const
    CONSUMER_KEY = '[YOUR CONSUMER KEY]';
    CONSUMER_SECRET = '[YOUR CONSUMER SECRET]';
    REDIRECT_URI = '[YOUR REDIRECT URI]';

    HTTP_TIMEOUT = 300;
    TOKEN_ENDPOINT = 'https://secure.mixi-platform.com/2/token';
    API_ENDPOINT = 'http://api.mixi-platform.com/2';
begin
    WriteLn('Please input redirest url''s "code" parameter :');
    ReadLn(code);

    if ( code = '' ) then
    begin
        Exit;
    end;


    http := TIdHttp.Create;
    ssl := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    params := TStringList.Create;

    try
        //SSLの設定
        ssl.SSLOptions.Method := sslvTLSv1;
        ssl.SSLOptions.Mode := sslmUnassigned;
        ssl.SSLOptions.VerifyMode := [];
        ssl.SSLOptions.VerifyDepth := 0;

        //Timeoutを設定しないとエラーになる
        http.ReadTimeout := HTTP_TIMEOUT;
        http.ConnectTimeout := HTTP_TIMEOUT;
        http.IOHandler := ssl;

        //Token取得用のリクエストパラメータの設定
        params.Values['grant_type'] := 'authorization_code';
        params.Values['client_id'] := CONSUMER_KEY;
        params.Values['client_secret'] := CONSUMER_SECRET;
        params.Values['code'] := code;
        params.Values['redirect_uri'] := REDIRECT_URI;

        //Tokenのリクエストを取得
        token_res := http.Post(TOKEN_ENDPOINT, params);

        //レスポンスのJSONをパースしてaccess_tokenを取り出す
        token_json := SO(token_res);

        //プロフィールの取得
        profile_endpoint := API_ENDPOINT
            + '/people/@me/@self?oauth_token='
            + token_json['access_token'].AsString;

        profile_res := http.Get(profile_endpoint);
        profile_json := SO(profile_res)['entry'];

        //プロフィールの表示
        WriteLn('id:' + profile_json['id'].AsString);
        WriteLn('displayName:' + Utf8ToAnsi(profile_json['displayName'].AsString)); //文字化け対策
        WriteLn('profileUrl:' + profile_json['profileUrl'].AsString);
        WriteLn('thumbnailUrl:' + profile_json['thumbnailUrl'].AsString);
    finally
        http.Free;
        ssl.Free;
        params.Free;
    end;
end.

コードの解説

以下では、サンプルコードのポイントとなる部分を説明していきます。

Graph APIhttps越しにアクセスする必要があります。そのため、http通信を行うIndyだけではなく、Indy OpenSSL 0.9.8h IntraWeb Editionに含まれるIdSSLOpenSSLHeaders.pasが必要になります。
Indy OpenSSL 0.9.8h IntraWeb EditionにはIdSSLOpenSSLHeaders9.pasとIdSSLOpenSSLHeaders10.pasが入っています。これは自身のIndyの環境に合わせてどちらかを選択し、IdSSLOpenSSLHeaders.pasにリネームしてください。

httpsで通信するために以下のように設定します。

    //SSLの設定
    ssl.SSLOptions.Method := sslvTLSv1;
    ssl.SSLOptions.Mode := sslmUnassigned;
    ssl.SSLOptions.VerifyMode := [];
    ssl.SSLOptions.VerifyDepth := 0;

    //Timeoutを設定しないとエラーになる
    http.ReadTimeout := HTTP_TIMEOUT;
    http.ConnectTimeout := HTTP_TIMEOUT;
    http.IOHandler := ssl;

ReadTimeoutとConnectTimeoutを指定し忘れると通信時にエラーになるので注意してください。
その後、アクセストークンを取得するためのエンドポイントを叩く際に必要なリクエストパラメータをTStringListのオブジェクトで組み立てます。

    //Token取得用のリクエストパラメータの設定
    params.Values['grant_type'] := 'authorization_code';
    params.Values['client_id'] := CONSUMER_KEY;
    params.Values['client_secret'] := CONSUMER_SECRET;
    params.Values['code'] := code;
    params.Values['redirect_uri'] := REDIRECT_URI;

codeには https://mixi.jp/connect_authorize.pl?client_id=[CONSUMER KEY]&scope=r_profile にアクセスして得られるAuthorization codeを渡しています。
REDIRECT_URIはサービス登録時に入力したリダイレクトURLを指定します。
そして、先ほど組み立てたリクエストパラメータでエンドポイントを叩きます。

    //Tokenのリクエストを取得
    token_res := http.Post(TOKEN_ENDPOINT, params);

ここでGraph APIを利用するためのアクセストークンが含まれたレスポンスが取得されました。レスポンスはJSONで返されますので、このJSONをパースしてアクセストークンを取り出します。

    //レスポンスのJSONをパースしてaccess_tokenを取り出す
    token_json := SO(token_res);

今回、JSONのパースにsuperobjectを利用していますが、JSONパーサーであればどれでも構いません。

ここまででようやくGraph APIにアクセスするためのアクセストークンが取得できました。
今度は取得したアクセストークンでプロフィールにアクセスするためのエンドポイントを叩きます。

    //プロフィールの取得
    profile_endpoint := API_ENDPOINT
        + '/people/@me/@self?oauth_token='
        + token_json['access_token'].AsString;

    profile_res := http.Get(profile_endpoint);

こうしてプロフィール情報のレスポンスが取得できました。このレスポンスは先ほどのアクセストークンの場合と同様JSONなので、またJSONをパースしてやります。

    profile_json := SO(profile_res)['entry'];

パースしたJSONからIDやニックネームなどを取り出して表示してみます。

    //プロフィールの表示
    WriteLn('id:' + profile_json['id'].AsString);
    WriteLn('displayName:' + Utf8ToAnsi(profile_json['displayName'].AsString)); //文字化け対策
    WriteLn('profileUrl:' + profile_json['profileUrl'].AsString);
    WriteLn('thumbnailUrl:' + profile_json['thumbnailUrl'].AsString);

実行結果

$ MixiGraphAPI.exe
Please input redirest url's "code" parameter :
995399df4ce4ecfe3bf286bb09ff77e0352bc152
id:okdj3abnf34ap
displayName:ソタ
profileUrl:http://mixi.jp/show_friend.pl?uid=okdj3abnf34ap
thumbnailUrl:http://profile.img.mixi.jp/photo/user/okdj3abnf34ap_2040732542.jpg

まとめ

mixi Graph APIを利用するDelphiのサンプルコードを紹介しました。
今回利用したのはプロフィール情報だけでしたが、同様の手順でAPIのエンドポイントを変えれば写真やつぶやきなども扱えます。

今回のサンプルコードをgithubに上げています。もし興味がありましたらご参照ください。

https://github.com/sota2502/MixiGraphAPIForDelphi