Поиск дневниковых записей Google+ и их интеграция с PHP-приложениями

Извлечение сообщений и поиск пользователей в Google+ с помощью API Google+ и PHP

Google+, новая служба социальной сети Google, позволяет всем желающим публиковать новости и сообщения. Разработчики Web-приложений могут получить доступ к этим сообщениям и искать их с помощью API Google+. В этой статье рассматриваются основы API Google+. Примеры демонстрируют, как использовать API Google+ с PHP для создания динамических Web-приложений.

Введение

Google+, новый член семейства социальных сетей, ― очередная попытка Google создать социальную сеть, которая позволяла бы участникам легко обмениваться новостями и файлами и взаимодействовать с друзьями. Похоже, в ней есть все для того, чтобы стать популярной. Судя по сообщениям, по состоянию на декабрь 2011 года у Google+ каждый день появлялось 625 тыс. новых подписчиков и насчитывалось в общей сложности 62 млн пользователей (см. раздел Ресурсы).

Используемые сокращения

  • API: Application programming interface / Интерфейс прикладных программ
  • HTTP: Hypertext Transfer Protocol
  • JSON: JavaScript Object Notation
  • PHP: Hypertext preprocessor

Web-разработчикам есть смысл воспользоваться успехом Google+. Как и многие другие службы Google, Google+ снабжена API для программистов, который позволяет им получить доступ к создаваемой пользователями информации через приложения собственной разработки. Так как API предоставляет выходные данные в формате JSON, его легко интегрировать с большинством инструментов программирования.

В этой статье рассматривается API Google+ Data. В ней показано, как его использовать для извлечения информации из Google+ и ее интеграции в PHP-приложение. (Это увлекательное занятие, так что предупреждаем об опасности впасть в зависимость.)


Основы API

Прежде чем приступить к разработке приложений для службы Google+, нужно понять, как она работает. API работает по протоколу HTTP и ожидает HTTP-запроса к заданной конечной точке. По получении этого запроса сервер API отвечает на него сообщением JSON, содержащим запрашиваемые данные. Затем эти данные можно проанализировать с помощью языка программирования для сервера (такого как PHP или Perl) или клиентского инструментария (например, jQuery или mooTools) и извлекать из них информацию для интеграции в Web-страницу.

Первым делом нужно подготовиться:

  1. Создайте учетную запись Google+.
    1. Войдите в учетную запись Google и по ссылке «+Вы» откройте главное меню, чтобы завести учетную запись Google+.
    2. Перейдите на страницу настройки Google и получите персональный URL-адрес Google Profile, содержащий ваш идентификатор Google ID, как показано на рисунке 1.
    3. Запишите этот ID; он понадобится для некоторых примеров из этой статьи.
    Рисунок 1. URL-адрес Google Profile с Google ID
    URL-адрес Google Profile с Google ID
  2. Активируйте доступ к API для своей учетной записи Google+.
    1. Перейдите к консоли Google API (см. ссылку в разделе Ресурсы) и создайте новый проект.
    2. Активируйте API Google+ для своего нового проекта.
    3. Вы получите автоматически сгенерированный ключ API, который можно использовать для доступа к этому API. Ключ находится на вкладке API Access консоли Google API, как показано на рисунке 2.
    4. Запишите свой ключ API.
    Рисунок 2. Консоль Google API с ключом доступа к API
    Консоль Google API с ключом доступа к API

Доступ к API Google+ можно получить и с помощью идентификатора OAuth. (Обсуждение OAuth выходит за рамки этой статьи.)

Получив Google+ ID и ключ API, можно попробовать обратиться с запросом к API через браузер по адресу https://www.googleapis.com/plus/v1/people/ID/activities/public?key=API-KEY. В этом запросе не забудьте заменить заполнители только что полученными значениями своего идентификатора и ключа API. Ответ на запрос, который можно увидеть в исходном коде результирующей страницы, будет содержать список ваших последних сообщений в Google+. Он выглядит примерно так, как листинг 1. Уникальные идентификаторы стерты.

Листинг 1. Пример Web-канала дневниковых записей из Google+ в формате JSON
{
 "kind": "plus#activityFeed",
 "etag": "ab49djslas22",
 "nextPageToken": "eJxtbiSnOTUova1kyV5Z7y",
 "selfLink": "https://www.googleapis.com/plus/v1/people/ID/activities/public?",
 "nextLink": "https://www.googleapis.com/plus/v1/people/ID/activities/
    public?maxResults=20&pageToken=",
 "title": "Plus Public Activity Feed for John Doe",
 "updated": "2012-01-17T06:05:03.277Z",
 "id": "tag:google.com,2010:/plus/people/ID/activities/public",
 "items": [
  {
   "kind": "plus#activity",
   "etag": "abc",
   "title": "Sleepy at work",
   "published": "2012-01-17T06:05:03.000Z",
   "updated": "2012-01-17T06:05:03.277Z",
   "id": "zab",
   "url": "https://plus.google.com/ID/posts/XgGBBbn",
   "actor": {
    "id": "ID",
    "displayName": "John Doe",
    "familyName": "Doe",
    "givenName": "John",
    "url": "https://plus.google.com/ID",
    "image": {
     "url": "https://lh5.googleusercontent.com/9HzARk/Cxo/photo.jpg?sz=0"
    }
   },
   "verb": "post",
   "object": {
    "objectType": "note",
    "content": "Sleepy at work",
    "originalContent": "",
    "url": "https://plus.google.com/ID/posts/XgGBBbn",
    "replies": {
     "totalItems": 0,
     "selfLink": "https://www.googleapis.com/plus/v1/activities/xys/comments"
    },
    "plusoners": {
     "totalItems": 0,
     "selfLink": "https://www.googleapis.com/plus/v1/activities/xys/people/plusoners"
    },
    "resharers": {
     "totalItems": 0,
     "selfLink": "https://www.googleapis.com/plus/v1/activities/xys/people/resharers"
    }
   },
   "provider": {
    "title": "Google+"
   },
   "access": {
    "kind": "plus#acl",
    "items": [
     {
      "type": "public"
     }
    ]
   }
  },
  {
  ...
  }
 ]
}

API Google+ отвечает на запросы сообщениями JSON, содержащими запрашиваемые данные. Google+ предлагает несколько интересных Web-каналов, в том числе:

  • Web-канал дневниковых записей, содержащий все сообщения, опубликованные конкретным пользователем;
  • канал комментариев, содержащий перечень комментариев пользователей к каждой отдельной дневниковой записи;
  • канал персон, содержащий список пользователей, соответствующих указанным ключевым словам или дневниковым записям.

Для доступа к перечисленныем каналам требуется проверка подлинности с помощью ключа API или идентификатора OAuth.

Сам канал отформатирован как JSON-документ, внешние ключи которого содержат название канала и URL-адреса текущей страницы (а также, если нужно, следующей и предыдущей страниц) результирующего набора. Массив items содержит коллекцию ресурсов. В зависимости от запрашиваемого канала ресурсы могут быть дневниковыми записями, профилями или комментариями. Каждый элемент коллекции содержит дополнительные сведения о ресурсе, в том числе:

  • общедоступный URL-адрес ресурса;
  • тип и идентификатор ресурса;
  • автора;
  • дату публикации.

В зависимости от типа ресурса могут быть включены дополнительные данные, такие как содержание дневниковых записей, описание профиля, фотография автора, количество ответов, пересылок и очков (+1) или вложения и их содержимое. В настоящей статье приведены примеры всех этих данных.

Пока API Google+ доступен только для чтения. Из него можно получать сведения, но операции записи, такие как размещение новых дневниковых записей или комментариев, обновление профилей авторов или их фотографий и удаление дневниковых записей, в настоящее время не поддерживаются.

Использование содержания Google+ в сторонних приложениях регулируется условиями обслуживания Google+. Приложение должно соответствовать Правилам Google+ для разработчиков. Прежде чем погрузиться в разработку, стоит потратить несколько минут на прочтение этих документов, чтобы обеспечить соблюдение всех необходимых правил (см. раздел Ресурсы).


Получение доступа к каналу дневниковых записей

В этом разделе показано, как интегрировать данные, полученные из API Google+, в PHP-приложение. Самый простой способ ― с помощью компонента Zend Framework Zend_Http_Client, который упрощает процесс создания, передачи и обработки HTTP-запросов. В листинге 2 показано, как использовать Zend_Http_Client для передачи запросов к API Google+ и обработки результатов.

Листинг 2. Обработка информации из канала дневниковых записей Google+
<?php
// загрузка классов Zend
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Http_Client');

// определение идентификатора пользователя
$uid = 'YOUR-ID-HERE';

// определение ключа API
$key = 'YOUR-API-KEY-HERE';

try {
  // получение доступа к каналу дневниковых записей
  // расшифровка ответа JSON
  $client = new Zend_Http_Client(
    "https://www.googleapis.com/plus/v1/people/$uid/activities/public?key=$key"
  );
  $response = $client->request('GET'); 
  $result = json_decode($response->getBody());

  // перебор элементов ответа  
  echo '<h1>' . $result->title . '</h1>';
  echo count($result->items) . ' post(s) found. <br/>';
  echo '<ol>';
  foreach ($result->items as $entry) {
    echo '<li>';
    echo '<a href="' . $entry->url . '">' . $entry->title . '</a>';
    echo ' (' . date("d M Y h:i", strtotime($entry->published)) . ')';  
    echo '</li>';
  }
  echo "</ol>";

} catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();
}   
?>

В листинге 2 сначала загружается библиотека классов Zend и инициализируется экземпляр класса Zend_Http_Client. Этот клиент можно использовать для создания и передачи запроса GET к каналу дневниковых записей пользователя через конечную точку API https://www.googleapis.com/plus/v1/people/[ID]/activities/public (как в листинге 1). Обратите внимание, что URL-адрес конечной точки в данном случае должен содержать Google ID пользователя и ключ API, сгенерированный консолью Google API.

Затем ответ на запрос в формате JSON анализируется и преобразуется в PHP-объект с помощью функции PHPjson_decode(), как показано на рисунке 3.

Рисунок 3. PHP-объект, содержащий сведения о дневниковых записях Google+
PHP-объект, содержащий сведения о дневниковых записях Google+

Если сравнить свойства объекта на рисунке 3 с парами ключ/значение документа JSON из листинга 1, то можно заметить соответствие между ними. Теперь легко перебрать массив items объекта, извлечь данные по отдельным дневниковым записям (такие как заголовок, URL и дата публикации) и отформатировать их для отображения на Web-странице.

Пример выходных данных приведен на рисунке 4.

Рисунок 4. Web-страница с дневниковыми записями Google+
Web-страница с дневниковыми записями Google+

Извлечение дневниковых записей и вложений

Исходные данные канала дневниковых записей в листинге 1 содержат дополнительные сведения по каждой публикации, включая метаданные о внедренных ресурсах, таких как видео или фотографии. Так что листинг 2 можно дополнить таким образом, чтобы извлекать и отображать эти дополнительные сведения, как показано в листинге 3.

Листинг 3. Отображение дополнительных данных и внедренных ресурсов из канала дневниковых записей Google+
<!DOCTYPE html 
		 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
		 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Extracting data from a public activity feed</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    </style>
  </head>
		 <body>  
<?php
// загрузка классов Zend
require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Http_Client');

// определение идентификатора пользователя
$uid = 'YOUR-ID-HERE';

// определение ключа API
$key = 'YOUR-API-KEY-HERE';

try {
  // получение доступа к каналу дневниковых записей
  // decode JSON response
  $client = new Zend_Http_Client(
    "https://www.googleapis.com/plus/v1/people/$uid/activities/public?key=$key"
  );
  $response = $client->request('GET'); 
  $result = json_decode($response->getBody());

  // перебор элементов ответа  
  echo '<h1>' . $result->title . ' - ' . count($result->items) . 
    ' post(s) found</h1>';
  echo '<table>';
  foreach ($result->items as $entry) {
    echo '<tr>';
    echo '<td class="photo"><img src="' . $entry->actor->image->url . 
      '" /><br/>';  
    echo '<a href="' . $entry->actor->url . '">'. 
      $entry->actor->displayName . '</a></td><td>';
    if (!empty($entry->title)) {
      echo '<a href="' . $entry->url . '">' . $entry->title . 
        '</a> <br/>';
    }
    if (count($entry->object->attachments)) {
      foreach ($entry->object->attachments as $a) {
        switch ($a->objectType) {
          case 'article':
            echo '<a href="' . $a->url . '">Article: ' . 
              $a->displayName . '</a><br/>';
            break;
          case 'photo':
            echo '<a href="'.$a->fullImage->url.'"><img src="' . 
              $a->image->url . '" /> </a><br/>';
            break;
          case 'video':
            echo '<a href="' . $a->url . '">Video: ' . $a->displayName . 
              '</a><br/><img src="' . $a->image->url . 
              '" /><br/>';
            break;
        }
      }
    }
    echo 'Posted on ' . date("d M Y h:i", strtotime($entry->published));      
    echo '</td></tr><tr><td class=divider colspan=2>
      </td></tr>';
  }
  echo '</table>';  
  } catch (Exception $e) {
  echo 'ERROR:' . $e->getMessage();
}   
?>
  </body>
</html>

Листинг 3 идет на шаг дальше, чем листинг 2. Из каждой публикации извлекается имя и фото автора, которые отображаются вместе с ее содержанием. Для сообщений, содержащих дополнительные вложения, такие как изображения, видео или внешние ссылки, выполняется перебор массива attachments, включенного в каждый элемент, и соответствующий ресурс отображается под содержанием публикации. Пример выходных данных приведен на рисунке 5.

Рисунок 5. Web-страница с сообщениями и вложениями Google+
Web-страница с сообщениями и вложениями Google+

В листинге 4 приведена более интерактивная версия листинга 3, позволяющая вводить идентификатор дневниковой записи и просматривать подробные сведения о ней. В листинге 4 используется другая конечная точка API, https://www.googleapis.com/plus/v1/activities/[ID], которая принимает ID дневниковой записи и возвращает сведения о ней в виде одной записи JSON.

Листинг 4. Интерактивная форма для отображения содержания дневниковых записей Google+
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Retrieving activity details</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    .meta {
      font-style: italic;
    }    
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for activity by ID: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form> 
    <?php
    if (isset($_POST['submit'])) {
      // загрузка классов Zend
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа API
      $key = 'YOUR-API-KEY-HERE';

      $aid = $_POST['q']; 

      try {
        // получение публикации пользователя
        // расшифровка ответа JSON
        $client = new Zend_Http_Client(
          "https://www.googleapis.com/plus/v1/activities/$aid?key=$key"
        );
        $response = $client->request('GET'); 
        $entry = json_decode($response->getBody());

        // перебор элементов ответа  
        // распечатка полей
        echo '<h1>' . $entry->title . '</h1>';
        echo '<table>';
        echo '<tr>';
        echo '<td class="photo"><img src="' . 
          $entry->actor->image->url . '" /></td><td>';  
        if (!empty($entry->title)) {
          echo '<a href="' . $entry->url . '">' . $entry->title . 
            '</a> <br/>';
        }
        if (count($entry->object->attachments)) {
          foreach ($entry->object->attachments as $a) {
            switch ($a->objectType) {
              case 'article':
                echo '<a href="' . $a->url . '">Article: ' . 
                  $a->displayName . '</a><br/>';
                break;
              case 'photo':
                echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                  $a->image->url . '" /> </a><br/>';
                break;
              case 'video':
                echo '<a href="' . $a->url . '">Video: ' . 
                  $a->displayName . '</a><br/><img src="' . 
                  $a->image->url . '" /><br/>';
                break;
            }
          }
        }
        echo '<div class="meta">Posted on ' . 
          date("d M Y h:i", strtotime($entry->published)) . ' by <a href="' . 
          $entry->actor->url . '">'. $entry->actor->displayName . 
          '</a> <br/>';
        echo 'Replies: ' . (int)$entry->replies->totalItems . 
          ' | +1s: ' . (int)$entry->plusoners->totalItems . 
          ' | Reshares: ' . (int)$entry->resharers->totalItems . 
          '</div>';
        echo '</td></tr></table>';

      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }   
    }
    ?>
  </body>
</html>

В листинге 4 добавлена форма ввода, которая позволяет указать идентификатор дневниковой записи. Затем устанавливается связь с конечной точкой Google+ API, и запись извлекается целиком в форме JSON-документа. Она преобразуется в объект PHP и форматируется для отображения, подобно тому, как показано в листинге 3. В листинге 4 используются дополнительные метаданные, прилагаемые к каждой публикации, такие как количество ответов, пересылок и очков (+1), собранных публикацией. Идентификатор дневниковой записи можно извлечь из JSON-документа.

Пример выходных данных приведен на рисунке 6.

Рисунок 6. Web-страница с сообщениями и вложениями Google+
Web-страница с сообщениями и вложениями Google+

Извлечение профилей пользователей

Профили пользователей можно получать так же, как их дневниковые записи. Сначала следует получить идентификатор пользователя Google и включить его в запрос, обращенный к конечной точке API https://www.googleapis.com/plus/v1/people/[ID]. Ответ JSON содержит биографические сведения о пользователе, включая полное имя, фото, краткую биографию и URL-адреса (если есть).

Листинг 5 иллюстрирует этот процесс.

Листинг 5. Интерактивная форма для получения профиля пользователя Google+
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Retrieving user profiles</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for user by ID: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form> 

    <?php
    if (isset($_POST['submit'])) {
      // загрузка классов Zend
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа API
      $key = 'YOUR-API-KEY-HERE';

      $uid = $_POST['q'];

      try {
        // получение публикации пользователя
        // расшифровка ответа JSON
        $client = new Zend_Http_Client(
          "https://www.googleapis.com/plus/v1/people/$uid?key=$key"
        );
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());

        // перебор элементов ответа 
        // распечатка полей
        echo '<h1><img src="' . $result->image->url. '" />' . 
          $result->displayName . '</h1>';
        echo isset($result->tagline) ? '<h2>' . $result->tagline . 
          '</h1>' : '';
        echo isset($result->aboutMe) ? $result->aboutMe . '<br/>' : '';
        if (isset($result->urls) && count($result->urls)) {
        echo '<h3>Links</h3> <ul>';
        foreach ($result->urls as $u) {
          $label = '';
          if ($u->type == 'json') continue;
          if ($u->type == 'profile') $label = 'Google+ Profile: ';
          echo '<li><a href="'. $u->value . '">' . $label . 
            $u->value . '</a></li>';
        }
        echo '</ul>';
        }  

      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }   
    }
    ?>
  </body>
</html>

Листинг 5 аналогичен листингу 4 ― он запрашивает Google ID пользователя и подключается к API для получения информации об этом пользователе. Ответ обычно включает как минимум имя пользователя и URL фотографии (или фото по умолчанию, если нет другого). Если пользователь указал дополнительные сведения о себе, они также будут включены в ответ JSON. Как и прежде, ответ можно преобразовать в объект PHP и отформатировать для отображения в браузере.

На рисунке 7 приведен пример выходных данных листинга 5.

Рисунок 7. Web-страница с профилями пользователей Google+
Web-страница с профилями пользователей Google+

Поиск дневниковых записей

Помимо получения одной публикации или профиля пользователя, API Google+ можно использовать для поиска Web-каналов дневниковых записей по ключевым словам. Этот метод API, доступный в конечной точке https://www.googleapis.com/plus/v1/activities, принимает параметр query, содержащий одно или несколько ключевых слов для поиска. В листинге 6 показан API в контексте нашего PHP-приложения.

Листинг 6. Поиск дневниковых записей по ключевым словам
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Searching public activity feeds</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form>    
    <?php

    if (isset($_POST['submit'])) {
      // загрузка классов Zend
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа API
      $key = 'YOUR-API-KEY-HERE';

      try {
        if (empty($_POST['q'])) {
          throw new Exception('No search term provided');  
        }

        // поиск всех каналов
        $url = "https://www.googleapis.com/plus/v1/activities?key=$key&query=" . 
          urlencode($_POST['q']);
        $client = new Zend_Http_Client($url);
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());

        // перебора возвращенных каналов  
        // отображение результатов
        echo '<h1>' . $result->title . ' - ' . 
          count($result->items) . ' post(s) found</h1>';
        echo '<table>';
        foreach ($result->items as $entry) {
          echo '<tr>';
          echo '<td class="photo"><img src="' . 
            $entry->actor->image->url . '" /><br/>';  
          echo '<a href="' . $entry->actor->url . '">'. 
            $entry->actor->displayName . '</a></td><td>';
          if (!empty($entry->title)) {
            echo '<a href="' . $entry->url . '">' . $entry->title . 
              '</a> <br/>';
          }
          if (count($entry->object->attachments)) {
            foreach ($entry->object->attachments as $a) {
              switch ($a->objectType) {
                case 'article':
                  echo '<a href="' . $a->url . '">Article: ' . 
                    $a->displayName . '</a><br/>';
                  break;
                case 'photo':
                  echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                    $a->image->url . '" /> </a><br/>';
                  break;
                case 'video':
                  echo '<a href="' . $a->url . '">Video: ' . $a->displayName . 
                    '</a><br/><img src="' . $a->image->url . 
                    '" /><br/>';
                  break;
              }
            }
          }
          echo 'Posted on ' . date("d M Y h:i", strtotime($entry->published));      
          echo '</td></tr><tr>
            <td class=divider colspan=2></td></tr>';
        }
        echo '</table>';  
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }              
    }
    ?>
  </body>
</html>

Листинг 6 создает Web-форму, содержащую поле ввода, в которое пользователь может ввести одно или несколько ключевых слов. После отправки формы создается новый экземпляр Zend_Http_Client, и ввод пользователя складывается в запрос GET к конечной точке API. Ответ JSON преобразуется в объект PHP для дальнейшей обработки.

На рисунке 8 приведен пример выходных данных листинга 6.

Рисунок 8. Web-форма для поиска дневниковых записей Google+ по ключевым словам
Web-форма для поиска дневниковых записей Google+ по ключевым словам

По умолчанию каждый результирующий набор, возвращенный API Google+, содержит 10 элементов. API можно заставить возвращать другое количество результатов, добавив в запрос API параметр maxResults и указав значение в интервале от 1 до 20. Каждый документ JSON, возвращаемый API, также содержит свойство nextPageToken, которое можно добавить в строку запроса для извлечения следующей страницы результирующего набора.


Поиск профилей пользователей

API Google+ можно использовать для поиска людей по ключевым словам. Конечная точка API для этого метода: https://www.googleapis.com/plus/v1/people. Как и API для поиска дневниковых записей, конечная точка принимает параметр query, содержащий ключевые слова, и выполняет поиск по ключевым словам из этого параметра.

В листинге 7 приведен вариант листинга 6, предназначенный для поиска людей, вместо дневниковых записей.

Листинг 7. Поиск дневниковых записей по профилю пользователя
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Searching for people</title>
    <style>
    table {
      border-collapse: yes;      
      width: 100%;
    }
    .photo {
      vertical-align: top;
    }
    .posts td:not(:last-child) {
      border-bottom: dashed silver 1px;
    }
    td.divider {
      border-bottom: solid green 2px;    
    }
    td.post {
      padding-bottom: 20px;
    }
    .meta {
      font-style: italic;
    }
    </style>     
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for people by name: <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form>    
    <?php

    if (isset($_POST['submit'])) {
      // загрузка классов Zend
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа API
      $key = 'YOUR-API-KEY-HERE';

      try {
        if (empty($_POST['q'])) {
          throw new Exception('No search term provided');  
        }

        // поиск всех каналов
        $url = "https://www.googleapis.com/plus/v1/people?key=$key&query=" . 
          urlencode($_POST['q']);
        $client = new Zend_Http_Client($url);
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());

        // перебора возвращенных каналов  
        // отображение результатов
        echo '<h1>' . $result->title . ' - ' . count($result->items) . 
          ' user(s) found</h1>';
        echo '<table>';
        foreach ($result->items as $entry) {
          echo '<tr>';
          echo '<td class="photo"><img src="' . $entry->image->url . 
            '" /><br/>';  
          echo '<a href="' . $entry->url . '">'. $entry->displayName . 
            '</a></td><td>';

          // получение трех последних сообщений пользователя 
          $client->setUri("https://www.googleapis.com/plus/v1/people/" . 
            $entry->id . "/activities/public?key=$key&maxResults=3");
          $response = $client->request('GET'); 
          $result2 = json_decode($response->getBody()); 
          echo '<table class="posts">';
          foreach ($result2->items as $entry2) {
            echo '<tr><td class="post">';
            if (!empty($entry2->title)) {
              echo '<a href="' . $entry2->url . '">' . 
                $entry2->title . '</a> <br/>';
            }
            if (count($entry2->object->attachments)) {
              foreach ($entry2->object->attachments as $a) {
                switch ($a->objectType) {
                  case 'article':
                    echo '<a href="' . $a->url . '">Article: ' . 
                      $a->displayName . '</a><br/>';
                    break;
                  case 'photo':
                    echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                      $a->image->url . '" /> </a><br/>';
                    break;
                  case 'video':
                    echo '<a href="' . $a->url . '">Video: ' . 
                      $a->displayName . '</a><br/><img src="' . 
                      $a->image->url . '" /><br/>';
                    break;
                }
              }
            }
            echo '<span class="meta">Posted on ' . 
              date("d M Y h:i", strtotime($entry2->published)) . '</span>';      
            echo '</td></tr>';
          }
          echo '</table>';
          echo '</td></tr><tr>
            <td class=divider colspan=2></td></tr>';
        }
        echo '</table>';
      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }              
    }
    ?>
  </body>
</html>

Листинг 7 интересен тем, что в нем используются два вызова методов API. Во-первых, он запрашивает конечную точку API https://www.googleapis.com/plus/v1/people для поиска профилей пользователей, соответствующих указанным ключевым словам. Затем он выполняет перебор результирующей коллекции. Для каждого профиля извлекается Google ID пользователя и включается во второй запрос к конечной точке API https://www.googleapis.com/plus/v1/people/[ID]/activities/public для получения трех последних сообщений этого пользователя. Как и в листинге 6, каждая публикация сопровождается ссылками на внедренные ресурсы, такие как изображения, видео или внешние статьи.

Результат листинга 7 приведен на рисунке 9.

Рисунок 9. Web-форма для поиска профилей пользователей Google+ по ключевым словам
Web-форма для поиска профилей пользователей Google+ по ключевым словам

Извлечение комментариев к дневниковым записям

Google+ позволяет пользователям размещать дневниковые записи, содержащее сообщения, фотографии, видео и ссылки, которые другие пользователи могут комментировать. Содержание комментариев доступно через канал комментариев каждой дневниковой записи посредством конечной точки API https://www.googleapis.com/plus/v1/activities/[ID]/comments. В листинге 8, который опирается на предыдущий код, показано, как отобразить дневниковые записи и комментарии к ним.

Листинг 8. Отображение комментариев к дневниковым записям
<!DOCTYPE html 
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Retrieving comments</title>
    <style>
    table {
      border-collapse: yes;      
    }
    .photo {
      vertical-align: top;
    }
    td.divider {
      border-bottom: dashed silver 1px;
    }
    .meta {
      font-style: italic;
    }
    </style>
  </head>
  <body>  
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    Search for comments on activity (enter activity ID): 
      <input type="text" name="q" />
    <input type="submit" name="submit" value="Search">
    </form> 
    <?php
    if (isset($_POST['submit'])) {
      // загрузка классов Zend
      require_once 'Zend/Loader.php';
      Zend_Loader::loadClass('Zend_Http_Client');

      // определение ключа API
      $key = 'YOUR-API-KEY-HERE ';

      $aid = $_POST['q']; 

      try {
        // получение веб-канала дневниковых записей
        // расшифровка ответа JSON
        $client = new Zend_Http_Client(
          "https://www.googleapis.com/plus/v1/activities/$aid?key=$key"
        );
        $response = $client->request('GET'); 
        $entry = json_decode($response->getBody());

        // перебор элементов ответа  
        // распечатка полей
        echo '<h1>' . $entry->title . '</h1>';
        echo '<table>';
        echo '<tr>';
        echo '<td class="photo"><img src="' . 
          $entry->actor->image->url . '" /></td><td>';  
        if (!empty($entry->title)) {
          echo '<a href="' . $entry->url . '">' . $entry->title . 
            '</a> <br/>';
        }
        if (count($entry->object->attachments)) {
          foreach ($entry->object->attachments as $a) {
            switch ($a->objectType) {
              case 'article':
                echo '<a href="' . $a->url . '">Article: ' . 
                  $a->displayName . '</a><br/>';
                break;
              case 'photo':
                echo '<a href="'.$a->fullImage->url.'"><img src="' . 
                  $a->image->url . '" /> </a><br/>';
                break;
              case 'video':
                echo '<a href="' . $a->url . '">Video: ' . $a->displayName . 
                  '</a><br/><img src="' . $a->image->url . '" /><br/>';
                break;
            }
          }
        }
        echo '<div class="meta">Posted on ' . 
          date("d M Y h:i", strtotime($entry->published)) . ' by <a href="' . 
          $entry->actor->url . '">'. $entry->actor->displayName . 
          '</a> <br/>';
        echo 'Replies: ' . (int)$entry->replies->totalItems . 
          ' | +1s: ' . (int)$entry->plusoners->totalItems . 
          ' | Reshares: ' . (int)$entry->resharers->totalItems . 
          '</div>';
        echo '</td></tr></table>';

        // получение канала комментариев к дневниковым записям
        $client->setUri(
          "https://www.googleapis.com/plus/v1/activities/$aid/comments?key=$key"
        );
        $response = $client->request('GET'); 
        $result = json_decode($response->getBody());

        // перебор элементов ответа  
        // распечатка полей
        if (count($result->items)) {
          echo '<h3>' . $result->title . '</h3>';
          echo '<ul>';
          foreach ($result->items as $comment) {        
            echo '<li>' . $comment->object->content . 
              '<br/>';
            echo '<span class="meta">Posted on ' . 
              date("d M Y h:i", strtotime($comment->published)) . 
              ' by <a href="' . $comment->actor->url . '">'. 
              $comment->actor->displayName . '</a> </span>';
            echo '</li>';
          }
          echo '</ul>';
        }

      } catch (Exception $e) {
        echo 'ERROR:' . $e->getMessage();
      }   
    }
    ?>
  </body>
</html>

Первая часть листинга 8 напоминает листинг 4. Она принимает идентификатор дневниковой записи, введенный пользователем в Web-форму, и устанавливает соединение с API для получения и отображения сведений из этой записи. Затем подается второй запрос к API для получения доступа к каналу комментариев, который возвращает JSON-документ, содержащий все комментарии, размещенные другими пользователями по поводу этой дневниковой записи. Этот документ JSON анализируется, и содержание каждого комментария, а также время публикации и имя автора добавляется на Web-страницу.

Визуализированный результат показан на рисунке 10.

Рисунок 10. Web-страница с дневниковыми записями Google+ и комментариями к ним
Web-страница с дневниковыми записями Google+ и комментариями к ним

Заключение

API Google+ еще относительно молод и на момент написания статьи поддерживает только операции чтения. Однако, как видно из примеров к этой статье, он предоставляет целый ряд возможностей для интеграции публикаций Google+ в любое Web-приложение. Следует ожидать, что в дальнейшем, по мере расширения службы Google+, API Google+ предложит гораздо больше возможностей. Но и теперь создавать гибридные приложения или специальные интерфейсы к Google+ ― чрезвычайно интересное занятие. Успешного программирования!

Ресурсы

Научиться

Получить продукты и технологии

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML, Open source
ArticleID=858515
ArticleTitle=Поиск дневниковых записей Google+ и их интеграция с PHP-приложениями
publish-date=02192013