Hangouts API を
使ってみよう

Social Develoers Japan 忘年会 2011

Hangouts API の基礎

Hangoutとは

Hangout を使ってみよう

Hangouts APIとは

Hangouts APIの使い方

  1. ガジェット XML を作成
  2. ガジェット XML を公開
  3. APIs Console で Hangouts API を有効化
  4. 必要に応じてチームメンバを登録
  5. ガジェット XML を登録
  6. Hangout を開始

API 公式サイト
https://developers.google.com/+/hangouts/

ガジェット XML を作成

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="Hello World">
    <Require feature="rpc"/>
    <Require feature="views"/>
  </ModulePrefs>
  <Content type="html">
    <![CDATA[
<!DOCTYPE html>

<script
  src="//hangoutsapi.talkgadget.google.com/hangouts/api/hangout.js?v=0.1"></script>

<h1>Hello World!</h1>

    ]]>
  </Content>
</Module>
          

rpc を有効にする Require タグと、hangout.jsの読み込みがポイント

ガジェット XML を公開

APIs Console で Hangouts API を有効化

チームメンバを登録

現在は開発者向けプレビューのため、チームメンバに
登録したユーザーしかガジェットが使えません。

ガジェット XML を登録し、 Hangout 開始

Hello World ガジェット

Google+ プロフィールの取得

Profile ガジェット

アプリケーションの初期化

gapi.hangout.onApiReady.add(function(e) {
  if(e.isApiReady) {
    // 起動時の参加者の状態を取得
    updateParticipants(gapi.hangout.getParticipants());

    // 以降の参加者の状態変更を追跡
    gapi.hangout.onParticipantsChanged.add(function(e) {
      updateParticipants(e.participants);
    });
  }
});
          

onApiReady イベントが発行される前は、
Hangouts の独自 API が正しく動作しません。

参加者情報は Participant インスタンスの構造体です。

makeRequest を jQuery Deferred でラップ

function makeRequest(url, arg, params) {
  var df = $.Deferred();
  params = params || {};
  params[gadgets.io.RequestParameters.CONTENT_TYPE] =
    gadgets.io.ContentType.JSON;
  gadgets.io.makeRequest(url, function(response) {
    if((response.errors || []).length <= 0 &&
       (200 == response.rc || response.rc == 201)) {
        df.resolve(response, arg);
    } else {
      df.reject(response, arg);
    }
  }, params);
  return df;
}
          

Google+ APIの呼び出し

function updateParticipants(participants) {
  // ...
  for(var id in participants) {
    var participant = participants[id];
    if(participant.gplusId) {
      var url =
        'https://www.googleapis.com/plus/v1/people/' +
        encodeURIComponent(participant.gplusId) +
        '?key=' + encodeURIComponent('__apikey__');
      makeRequest(url, id).done(receivePerson);
    }
  }
}

function receivePerson(response, extra) {
  // response.data にパース済みのレスポンスが格納されている
}
          

リアルタイムのステート共有

Plus Shot ガジェット

共有ステートの更新

var dataUpdates = {};
var dataRemoves = [];

function createBullet(bullet) {
  dataUpdates['b|' + bullet.id] = gadgets.json.stringify(
    { x:bullet.x||0, y:bullet.y||0, rot:player.rot||0 });
}

function removeBullet(bullet) {
  dataRemoves.push('b|' + bullet.id);
}

function redrawScreen() {
  // ...
  gapi.hangout.data.submitDelta(dataUpdates, dataRemoves);
  dataUpdates = {};
  dataRemoves = [];
}
          

共有ステートの変更を追跡

function updateEnemies(e) {
  var state = e.state;
  for(var id in state) {
    var parts = id.split('|');
    if(parts[0] == 'p') {
      // 他のプレイヤーの状態を更新
    } else if(parts[0] == 'b'){
      // 他のプレイヤーの弾を作成
    }
  }
}

gapi.hangout.onApiReady.add(function(e) {
  if(e.isApiReady) {
    gapi.hangout.data.onStateChanged.add(updateEnemies);
    // ...
  }
});
          

アバター画像の設定

function updateParticipants(participants) {
  $.each(participants, function() {
    if(this.hasAppEnabled) {
      // ...
      gapi.hangout.av.setAvatar(
        this.id,
        'http://example.com/path/to/player' + this.index + '.png');
    }
  });
  g_players = newPlayers;
};
          

アバター指定を解除するときはclearAvaterを使う。

マイク入力レベルを取得

var shot       = false;
var prevVolume = 0;
function volumesChange(e) {
  var volume = e.volumes[gapi.hangout.getParticipantId()];
  if(volume >= 5 && prevVolume < 3) {
    shot = true;
  }
  prevVolume = volume;
};

gapi.hangout.onApiReady.add(function(e) {
  if(e.isApiReady) {
    gapi.hangout.av.onVolumesChanged.add(volumesChange);
    // ...
  }
});
          

そのほかの機能

などなど…

まとめ

ぜひお試しください!

ご清聴ありがとうございました!