уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.

Итак, вроде бы чтение данных о контактах в Google доделано. Пока на Google Code модуль выкладывать не буду — выложу в блоге для того, чтобы все заинтересованные в развитии проекта люди могли проверить работу, указать ошибки, недочеты и т.д. Сегодня рассмотрим небольшой пример работы с Контактами из Delphi, а также подведем небольшие итоги работы коллективного разума :)

Google Contacts. Общие сведения

Итак, у Вас есть аккаунт в GMail. Для доступа к контактам Вам необходимо зайти в GMail и в меню выбрать «Контакты». В чём, на мой взгляд, выигрывает сервис Google по сравнению с другими аналогичными сервисами?
Во-первых, в Google Contacts можно хранить намного больше информации о человеке, чем, например в той же адресной книге Mail.ru или Yandex. Помимо адресов электронной почты можно сохранить, например, номера телефонов, почтовые адреса, сведения об организации в которой работает человек и т.д.
Во-вторых, используя только Google Contacts можно получать не только информацию по отдельному человеку, но и выстраивать сеть взаимоотношений человека с другими людьми, которые есть в Ваших контактах. Для этого у каждого контакта можно заполнить список «Пользователь»:

После небольшого анализа данных можно выстроить, например всю сеть взаимоотношений пользователя: с кем он общается, с кем общаются его друзья и т.д. Но, сегодня мы не об этом. Сегодня мы рассмотрим пример получения данных о контактах.

Google Contacts. Классы обработки Contacts Feed

Ещё в момент, когда я писал модуль по работе с Календарями Google, был разработан модуль GDataCommon.pas, содержащий необходимые классы и методы обработки общих для всех API Google узлов вида gd:xxx. Его мы сегодня будем использовать для обработки фида Контактов. Также, для работы с XML воспользуемся библиотекой NativeXML и для получения данных от сервера библиотекой Synapse, ну и для аутентификации в сервисах Google используем компонент (или класс — как будет Вам угодно) GoogleLogin.
Что содержит фид Контактов Google? Авторизовавшись и отправив GET-запрос по адресу:

http://www.google.com/m8/feeds/contacts/userEmail/full

мы получим XML-документ, содержащий сведения обо всех Контактах пользователя, а точнее по первым 25 контактам. О том как получить все контакты я рассказывал здесь.
Как Вы, наверное, уже в курсе — все контакты можно разбивать на несколько групп. При этом один и тот же контакт может содержаться в нескольких группах, например, в группах «Друзья» и «Коллеги». Также при группировке контактов мы можем создавать собственный группы. Поэтому, чтобы не перегружать фид Контактов информацией и дать в руки разработчиков удобный инструмент для обработки данных, Google Contacts API в основном фиде содержит только ссылки на группы, в которых содержится контакт:

А вся информация о группах содержится во втором фиде, получение которого осуществляется тем же запросом GET по адресу:
http://www.google.com/m8/feeds/groups/UserEmail/full
Таким образом, в Delphi можно выделить два класса для работы с контактами:
1. Класс, содержащий информацию по контакту: имя, почта, телефон и т.д.
2. Класс, содержащий информацию по группе.
Класс TContact, содержащий информацию по контакту выглядит следующим образом:

type
  TGoogleContact = class;
  TContactGroup = class;
 
  TContact = class
  private
    FEtag: string;
    FId: string;
    FUpdated: TDateTime;
    FTitle: TTextTag;
    FContent:TTextTag;
    FLinks:TList;
    FName: TgdName;
    FNickName: TcpNickname;
    FBirthDay: TcpBirthday;
    FOrganization: TgdOrganization;
    FEmails: TList;
    FPhones: TList;
    FPostalAddreses: TList;
    FEvents : TList;
    FRelations: TList;
    FUserFields: TList;
    FWebSites: TList;
    FGroupMemberships: TList;
    FIMs:TList;
    FOwner: TGoogleContact;
    function GetPrimaryEmail: string;
    procedure SetPrimaryEmail(aEmail:string);
    function GetName : TgdName;
    function GetOrganization:TgdOrganization;
  public
    constructor Create(byNode: TXMLNode; aOwner: TGoogleContact=nil);
    procedure ParseXML(Node: TXMLNode);
    function RetriveImage:TJPEGImage;
    function FindEmail(const aEmail:string; out Index:integer):TgdEmail;
    property Owner: TGoogleContact read FOwner write FOwner;
    property Etag: string read FEtag write FEtag;
    property Id: string read FId write FId;
    property Updated: TDateTime read FUpdated write FUpdated;
    property Title: TTextTag read FTitle write FTitle;
    property Content:TTextTag read FContent write FContent;
    property Links:TList read FLinks write FLinks;
    property Name: TgdName read GetName write FName;
    property NickName: TcpNickname read FNickName write FNickName;
    property BirthDay: TcpBirthday read FBirthDay write FBirthDay;
    property Organization: TgdOrganization read GetOrganization write FOrganization;
    property Emails: TList read FEmails write FEmails;
    property Phones: TList read FPhones write FPhones;
    property PostalAddreses: TList read FPostalAddreses write FPostalAddreses;
    property Events : TList read FEvents write FEvents;
    property Relations: TList read FRelations write FRelations;
    property UserFields: TList read FUserFields write FUserFields;
    property WebSites: TList read FWebSites write FWebSites;
    property GroupMemberships: TList read FGroupMemberships write FGroupMemberships;
    property IMs:TList read FIMs write FIMs;
    property PrimaryEmail:string read GetPrimaryEmail write SetPrimaryEmail;
end;

Соответственно класс TContactGroup выглядит так:

  TContactGroup = class
  private
    FEtag: string;
    Fid: string;
    FLinks: TList;
    FUpdate: TDateTime;
    FTitle: TTextTag;
    FContent: TTextTag;
    FSystemGroup: TcpSystemGroup;
  public
    constructor Create(const ByNode: TXMLNode);
    procedure ParseXML(Node: TXmlNode);
    property Etag: string read FEtag write FEtag;
    property id: string read Fid write Fid;
    property Links: TList read FLinks write FLinks;
    property Update: TDateTime read FUpdate write FUpdate;
    property Title: TTextTag read FTitle write FTitle;
    property Content: TTextTag read FContent write FContent;
    property SystemGroup: TcpSystemGroup read FSystemGroup write FSystemGroup;
end;

И, наконец, класс для обработки всех данных по контактам

TGoogleContact:
TGoogleContact = class
  private
    FAuth: string; //AUTH для доступа к API
    FEmail:string; //обязательно GMAIL!
    FGroups: TList;
    FContacts: TList;
    function GetNextLink(aXMLDoc:TNativeXml):string;
    function GetContactsByGroup(GroupName:string):TList;
    function GroupLink(const aGroupName:string):string;
  public
    constructor Create(const aAuth,aEmail: string);
    function RetriveGroups:integer;
    function RetriveContacts: integer;
    property Groups: TList read FGroups write FGroups;
    property Contacts:TList read FContacts write FContacts;
    property ContactsByGroup[GroupName:string]:TList read GetContactsByGroup;
 end;

Расписывать каждое поле классов, думаю, не имеет смысла, та как Вы можете скачать и изучить модуль GContacts.pas, а рассмотреть пример работы с классом стоит.

Google Contacts. Пример работы с классами

Итак, реализуем следующий алгоритм:
1. Зайти в аккаунт
2. Получить сведения о контактах и группах
3. Вывести информацию о контактах, содержащихся в определенной группе.
Первый пункт подробно описан в этом посте, поэтому скажу только, что имя переменной, содержащей всю необходимую информацию для дальнейшей работы с контактами — Loginer. Поэтому сразу переходим ко второму пункту.
Размещаем на главной форме приложения следующие компоненты:
ListBox, StatusBar, ComboBox. Теперь в любом обработчике, например, какой-либо кнопки пишем:

var i:integer;
begin
  if Loginer.Login()=lrOk then //аутентификация прошла успешно
    begin
      //создаем класс
      Contact:=TGoogleContact.Create(Loginer.Auth,GmailContact);
      //получаем сведения о группах
      StatusBar1.Panels[1].Text:=IntToStr(Contact.RetriveGroups);
      //получаем сведения о контактах
      StatusBar1.Panels[3].Text:=IntToStr(Contact.RetriveContacts);
      ListBox1.Items.Clear;
      //заполняем список именами контактов
      for i:=0 to Contact.Contacts.Count - 1 do
        begin          
          if Contact.Contacts[i].Title.Value='' then
            if Contact.Contacts[i].PrimaryEmail<>'' then
              ListBox1.Items.Add(Contact.Contacts[i].PrimaryEmail)
            else
              ListBox1.Items.Add('NoName Contact')
          else
              ListBox1.Items.Add(Contact.Contacts[i].Title.Value)
        end;
      //заполняем ComboBox сведениями о группах
      ComboBox1.Items.Clear;
      ComboBox1.Items.Add('Все');
      for i:=0 to Contact.Groups.Count - 1 do
        ComboBox1.Items.Add(Contact.Groups[i].Title.Value);
      ComboBox1.ItemIndex:=1;
    end;
end;

Как видите — всё просто. Если отбросить всю работы с компонентами на форме, то второй пункт нашего алгоритма укладывается аккурат в три строки кода:

Contact:=TGoogleContact.Create(Loginer.Auth,GmailContact);
Contact.RetriveGroups; 
Contact.RetriveContacts;

Теперь, когда оба фида получены и обработаны можно делить все контакты по группам, например так:

List:=Contact.ContactsByGroup[ComboBox1.Items[ComboBox1.ItemIndex]];

В качестве аргумента в методе ContactsByGroup используется имя группы. Результат выполнения — список всех контактов, содержащихся в группе.
Наконец, чтобы получить информацию по контакту, достаточно найти его в списке Contacts. Так можно вывести все номера телефонов контакта в список ComboBox3:

  ComboBox3.Items.Clear;
  for I := 0 to Contact.Contacts[j].Phones.Count - 1 do
    ComboBox3.Items.Add(Contact.Contacts[j].Phones[i].Text);
  if ComboBox3.Items.Count>0 then ComboBox3.ItemIndex:=0;
  ComboBox4.Items.Clear;

Вот и вся работа с контактами, доступная на данном этапе разработки. Можете скачать необходимые для работы модули и попробовать поработать со своими контактами в Google (ссылка в конце поста).
А я подведу небольшой итог работы нашего коллективного разума в Google Moderator. Итак, был задан вопрос: «Какую программу написать в Delphi, чтобы использовать её для работы в Интернет?»
Лидером по голосам является предложение: «»контакты или органайзер :-) , и что бы программа могла синхронизироваться со всеми известными сервисами … (google, evernote, twitter etc)»», оставленное пользователем Fet$. В целом мне это предложение тоже нравится, тем более, что сейчас я как раз и работаю над контактами. Единственный момент, которые меня сейчас несколько настораживает — это синхронизация с Twitter. Пока просто не могу представить как однозначно определить, что контакт в Google и Twitter относятся к одному человеку, т.к. Twitter не выдает информацию по email. Так что предложение дельное, но требуется Ваша помощь, уважаемые читатели. Как синхронизировать Контакты с Твитером?

Скачать исходник: Исходники —> API онлайн-сервисов —> Google API
0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
9 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Fet$
Fet$
03/05/2010 18:10

Contact:=TGoogleContact.Create(Loginer.Auth,GmailContact);

Переменная или указатель GmailContact где она описывается или от куда берется ?)

Fet$
Fet$
03/05/2010 23:24

спасибо… а как можно проверить в классе TGoogleContact произошла ли ошибка при считывание контактов или групп ?

Fet$
Fet$
04/05/2010 06:32

Во время выполнения кода

Contact.RetriveContacts;

я получаю следующий XML:

Token invalid

Token invalid
Error 401

Что это ? И как с этим бороться…?

Nicolay
Nicolay
19/05/2010 23:32

классный компонент, а не подскажите как с его помощью включить поддержку POP3

Nicolay
Nicolay
20/05/2010 17:22

Большое спасибо, просто я не особо сталкивался с вопросами с подобными вопросами, и чегото не получаться.

Fet$
Fet$
20/05/2010 17:55

вы посмотрите какие методы используются в данном случае и все станет понятно !