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

Чуть больше недели назад я писал про чтение данных о контактах Google через Google API. Сегодня я расскажу о том как вносить изменения в сведения о контакте. В данной части работы с API от нас требуется не только обеспечить добавление или внесение изменений в какие-либо сведения о контакте, но, также и обеспечить целостность данных.

Для того, чтобы внести изменения в информацию о каком-либо контакте в GMail нам необходимо, как минимум:
1. Знать ETag изменяемой записи и правильно его расположить в запросе
2. Знать адрес ссылки (узел Link) на который необходимо отправить PUT-запрос
3. Обеспечить наличие в XML-документе необходимых узлов.
Кстати, эти же пункты необходимо соблюдать и при добавлении нового контакта. Рассмотрим всё по порядку.

1. Работа с ETag.

Вообще, работа с Google API мне напоминает некое подобие конструктора лего — есть куча деталей, которые можно расположить в определенном порядке, чтобы получить в результате игрушку. Только в нашем случае, мы должны получить запись в адресной книге. Как и деталь в конструкторе ETag может располагаться в разных частях запроса:
1. Непосредственно в XML-документе. При этом Etag включается в документа как атрибут gd:etag корневого узла entry.
2. В заголовках запроса PUT к серверу. В этом случае Etag должен быть расположен в заголовке If-Match.
При расположении ETag в атрибутах XML необходимо учесть следующее обстоятельство: ETag содержит символы ««» и в документе они должны выглядеть также, т.е. не должны заменяться на &qout и т.д. Поэтому, на мой взгляд, более безопасно и просто читать и записывать ETag следующим образом: при чтении данных искать атрибут gd:etag и сохранять его значение в переменной, а при отправке данных — включать ETag в заголовки. Так нам не придётся лишний раз следить за тем, чтобы ETag отправился правильно.

2. Ссылка для редактирования контакта

Про узлы link я уже писал не раз, поэтому подробно останавливаться на данно вопросе не будем. Скажу только , что для изменения текстовой информации нам необходимо найти узел с атрибутом rel=»edit».

3. Формируем запрос, содержащий минимальный набор данных.

Я немного поэкспериментировал со своей адресной книгой GMail и определил тот минимум данных, который необходимо записать в XML-документ, чтобы сервер не вернул ошибку.  Итак, наш документ должен содержать:

1. Все пространства имен (в атрибутах узла entry), а именно:

xmlns=»http://www.w3.org/2005/Atom»
xmlns:gd=»http://schemas.google.com/g/2005″
xmlns:gContact=»http://schemas.google.com/contact/2008″

2. Узел ID со значением, определенным при чтении данных о контакте
3. Узлы link со следующими атрибутами rel: edit,http://schemas.google.com/contacts/2008/rel#photo, self
4. Как минимум один узел gContact:groupMembershipInfo с атрибутом rel содержащим ссылку на системных группу «Все контакты»

Ну и хотя бы какой-то узел, содержащий видимую информацию контакта, например адрес e-mail или блога.

Вот тот минимум, который сервер Google принимает безоговорочно.

Для примера приведу небольшой листинг процедуры отправки данных в Google. Пример основан на работе с классом, который я рассматривал здесь.

procedure TContact.UpdateInfo;
var Doc: TNativeXml;
    I: Integer;
    url:string;
begin
 Doc:=TNativeXml.Create; //создаем новый документ
 Doc.EncodingString:='utf-8';
 Doc.CreateName('entry');//добавляем корневой узел
{добавляем пространства имен}
 for i := 0 to High(clNameSpaces) do
    Doc.Root.WriteAttributeString(contactNameSpaces[i, 0], contactNameSpaces[i, 1]);
 Doc.Root.NodeNew('id').ValueAsString:=Fid;//добавляем id
 for I := 0 to Self.FLinks.Count - 1 do //добавляем все ссылки
   begin
     if LowerCase(Self.FLinks[i].Rel)='edit' then
       url:=Self.FLinks[i].Href;
     Self.FLinks[i].AddToXML(Doc.Root);
   end;
 for I := 0 to Self.FEmails.Count - 1 do //добавляем адреса почты
   Self.FEmails[i].AddToXML(Doc.Root);
 for I := 0 to GroupMemberships.Count - 1 do //добавляем членство в группах
   GroupMemberships[i].AddToXML(Doc.Root);
 with THTTPSend.Create do //отправка данных
   begin
     Headers.Add('GData-Version: 3.0.');
     Headers.Add('Authorization: GoogleLogin auth=' + Self.FOwner.FAuth);
     MimeType := 'application/atom+xml';
     Headers.Add('If-Match: '+Self.Etag);
     Doc.SaveToStream(Document);
     if HTTPMethod('PUT',url) then
       begin
         //сохраняем ответный - внем может содержаться описание ошибки
         Document.SaveToFile('response.xml');
       end
     else
       ShowMessage(IntToStr(ResultCode))
   end;
end;

Здесь в процедуре я использовал NativeXML для формирования документа и Synapse для отправки данных на сервер.
И напоследок несколько замечаний по работе с контактами:
1. Для того, чтобы обеспечивать сохранность данных о контакте gmail Вы обязаны включать в отправляемый XML-документ все данные, которые были ранее получены. Ислючением могут быть узлы update (дата обновления контакта) и category (категория элемента entry). Все остальные данные — постовые адреса, телефоны, почта и т.д. и т.п. должны включаться в запрос иначе при обновлении все не объявленные данные будут удалены.
2. Иногда брэндмауэр может блокировать PUT-запрос. Если вдруг вы столкнулись с такой проблемой, то достаточно включить в заголовки запись X-HTTP-Method-Override: PUT и отправлять данные POST-запросом.

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
0 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии