Итак, вроде бы чтение данных о контактах в 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. Так что предложение дельное, но требуется Ваша помощь, уважаемые читатели. Как синхронизировать Контакты с Твитером?
Contact:=TGoogleContact.Create(Loginer.Auth,GmailContact);
Переменная или указатель GmailContact где она описывается или от куда берется ?)
GmailContact — это строка — ваш email на GMail.com, например anyemail@gmail.com
спасибо… а как можно проверить в классе TGoogleContact произошла ли ошибка при считывание контактов или групп ?
Пока никак нельзя про ошибку узнать. модуль дописывается
Во время выполнения кода
Contact.RetriveContacts;
я получаю следующий XML:
Token invalid
Token invalid
Error 401
Что это ? И как с этим бороться…?
классный компонент, а не подскажите как с его помощью включить поддержку POP3
Так POP3 — это вам в конкретно в настройки GMail надо лезть. Контакты здесь не причём
Большое спасибо, просто я не особо сталкивался с вопросами с подобными вопросами, и чегото не получаться.
вы посмотрите какие методы используются в данном случае и все станет понятно !