Итак, вроде бы чтение данных о контактах в Google доделано. Пока на модуль выкладывать не буду - выложу в блоге для того, чтобы все заинтересованные в развитии проекта люди могли проверить работу, указать ошибки, недочеты и т.д. Сегодня рассмотрим небольшой пример работы с Контактами из 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<TEntryLink>; FName: TgdName; FNickName: TcpNickname; FBirthDay: TcpBirthday; FOrganization: TgdOrganization; FEmails: TList<TgdEmail>; FPhones: TList<TgdPhoneNumber>; FPostalAddreses: TList<TgdStructuredPostalAddress>; FEvents : TList<TcpEvent>; FRelations: TList<TcpRelation>; FUserFields: TList<TcpUserDefinedField>; FWebSites: TList<TcpWebsite>; FGroupMemberships: TList<TcpGroupMembershipInfo>; FIMs:TList<TgdIm>; 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<TEntryLink> 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<TgdEmail> read FEmails write FEmails; property Phones: TList<TgdPhoneNumber> read FPhones write FPhones; property PostalAddreses: TList<TgdStructuredPostalAddress> read FPostalAddreses write FPostalAddreses; property Events : TList<TcpEvent> read FEvents write FEvents; property Relations: TList<TcpRelation> read FRelations write FRelations; property UserFields: TList<TcpUserDefinedField> read FUserFields write FUserFields; property WebSites: TList<TcpWebsite> read FWebSites write FWebSites; property GroupMemberships: TList<TcpGroupMembershipInfo> read FGroupMemberships write FGroupMemberships; property IMs:TList<TgdIm> read FIMs write FIMs; property PrimaryEmail:string read GetPrimaryEmail write SetPrimaryEmail; end;
Соответственно класс TContactGroup выглядит так:
TContactGroup = class private FEtag: string; Fid: string; FLinks: TList<TEntryLink>; 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<TEntryLink> 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<TContactGroup>; FContacts: TList<TContact>; function GetNextLink(aXMLDoc:TNativeXml):string; function GetContactsByGroup(GroupName:string):TList<TContact>; function GroupLink(const aGroupName:string):string; public constructor Create(const aAuth,aEmail: string); function RetriveGroups:integer; function RetriveContacts: integer; property Groups: TList<TContactGroup> read FGroups write FGroups; property Contacts:TList<TContact> read FContacts write FContacts; property ContactsByGroup[GroupName:string]:TList<TContact> 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. Так что предложение дельное, но требуется Ваша помощь, уважаемые читатели. Как синхронизировать Контакты с Твитером?
Кстати, работа коллективного разума не закончена - она продолжается, так, что можете , голосовать за понравившиеся и т.д. Как знать, может окажется, что именно Ваша идея осуществиться в будущем ;)
Файлы для загрузки:
Contacts API(28.54 KB)
Интересуетесь фотографией? Обязательно посетите любительский фотоблог с красивыми фотографиями природы.
Для тех, кто интересуется все креативным и интересным могу посоветовать посетить блог с коротким названием "Web". В этом блоге можно посмотреть видео, например о том как сделать конверт для компакт-дисков из куска бумаги или посмотреть фотографии комбинированных ключей-сувениров и т.д.
----------------------
| Делись! | Загружай! | Плюсуй! |
| | |









03 мая 2010 в 6:10 пп
Contact:=TGoogleContact.Create(Loginer.Auth,GmailContact);
Переменная или указатель GmailContact где она описывается или от куда берется ?)
03 мая 2010 в 11:05 пп
GmailContact — это строка — ваш email на GMail.com, например anyemail@gmail.com
03 мая 2010 в 11:24 пп
спасибо… а как можно проверить в классе TGoogleContact произошла ли ошибка при считывание контактов или групп ?
04 мая 2010 в 6:32 дп
Во время выполнения кода
Contact.RetriveContacts;
я получаю следующий XML:
Token invalid
Token invalid
Error 401
Что это ? И как с этим бороться…?
04 мая 2010 в 9:03 дп
Пока никак нельзя про ошибку узнать. модуль дописывается
19 мая 2010 в 11:32 пп
классный компонент, а не подскажите как с его помощью включить поддержку POP3
20 мая 2010 в 12:21 пп
Так POP3 — это вам в конкретно в настройки GMail надо лезть. Контакты здесь не причём
20 мая 2010 в 5:22 пп
Большое спасибо, просто я не особо сталкивался с вопросами с подобными вопросами, и чегото не получаться.
20 мая 2010 в 5:55 пп
вы посмотрите какие методы используются в данном случае и все станет понятно !