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

Итак, как и говорил ранее, сегодня я решил вытащить из черновиков блога и немного доработать статью, посвященную работе с API социальной Сети «ВКонтакте«. В принципе, REST Client Library, о которой я уже рассказывал не раз, вполне сгодится для работы с любой социальной сетью или онлайн сервисом, которые предоставляют нам в распоряжение API. Но «ВКонтакте», всё же из всех мне известных социальных сетей (за исключением, наверное, Twitter) является самой популярной в России, поэтому с ней и попробуем поработать, используя в работе Delphi XE6. Ну, а чтобы было ещё более занимательно, попробуем написать небольшое приложение для Android. Кому потребуется приложение для Windows и VCL, думаю легко разберется в том, какие модули следует подключить  в uses, а какие наоборот — убрать.

1. Создаем свое приложение «ВКонтакте» и пробуем авторизовать пользователя.

Для начала работы с API «ВКонтакте» необходимо создать новое приложение и получить необходимые данные для авторизации пользователей. Для этого заходим на страницу разработчиков и жмем вверху страницы кнопку «Создать приложение«:

Android_VK_1

 

Далее придумываем нашему приложению название и задаем тип приложения — «Standalone-приложение«:

Android_VK_2

 

Жмем кнопку «Подключить приложение» после чего вам предложат подтвердить свое действие, выслав на мобильный телефон проверочный код. После подтверждения Вам станет доступно изменение настроек приложения:

Android_VK_3

 

Переходим на вкладку «Настройки» и запоминаем ID приложения и Защищенный ключ:

Android_VK_4

 

Теперь можно переходить к Delphi XE6 и попробовать реализовать авторизацию пользователя.

Запускаем Delphi XE6, создаем новый проект для мобильных устройств и на главную форму бросаем компоненты, покзанные на рисунке ниже:

Android_VK_5

 

Сейчас нам нужны будут следующие компоненты: TButtonTRESTClientTRESTRequestTRESTResponse и TOAuth2Authenticator. Клик по кнопке TButton будет вызывать процесс авторизации пользователя. Для начала, напишем процедуру авторизации пользователя.

Все необходимые данные для авторизации я определил как константы:

const
  cAppID = '427ххххх';
  cAppKey = '94ххххххххххххххххххххххp';
  cEndPoint = 'https://oauth.vk.com/authorize';

Теперь необходимо вызвать форму для авторизации пользователя «ВКонтакте» и получить Access Token. Как это делать я достаточно подробно рассказывал в самоё первой статье по REST Client Library. Подключаем в uses модуль REST.Authenticator.OAuth.WebForm.FMX и определяем следующую переменную:

type
  TForm1 = class(TForm)
    [...]
  private
    WebForm: Tfrm_OAuthWebForm;
  public
    { Public declarations }
  end;

Напомню, что Tfrm_OAuthWebForm — это форма, на которой расположен компонент TWebBrowser с помощью которого пользователь заходит на сайт, чтобы ввести свои логин/пароль и получить доступ для приложения к каким-либо данным своего аккаунта. Соответственно нам, как разработчикам, эта форма необходима, как минимум, для того, чтобы «отловить» редирект на специальный URL, который будет содержать необходимый нам Access Token. Для управления редиректами у Tfrm_OAuthWebForm определено сразу два события:

type
  TOAuth2WebFormRedirectEvent = procedure(const AURL: string; var DoCloseWebView : boolean) of object;
 
  property OnBeforeRedirect: TOAuth2WebFormRedirectEvent read FOnBeforeRedirect write FOnBeforeRedirect;
  property OnAfterRedirect: TOAuth2WebFormRedirectEvent read FOnAfterRedirect write FOnAfterRedirect;

Нам необходим обработчик события OnAfterRedirect. Напишем его:

type
  TForm1 = class(TForm)
   [...]
  private
    WebForm: Tfrm_OAuthWebForm;
    procedure AfterRedirect(const AURL: string; var DoCloseWebView : boolean);
    [...]
  public
    { Public declarations }
  end;
 
procedure TForm1.AfterRedirect(const AURL: string; var DoCloseWebView: boolean);
var i:integer;
    Str: string;
    Params: TStringList;
begin
  i:=pos('#access_token=',AURL);
  if (i>0) and (OAuth2Authenticator1.AccessToken=EmptyStr) then
    begin
      Str:=AURL;
      Delete(Str,1,i);
      Params:=TStringList.Create;
      try
        Params.Delimiter:='&';
        Params.DelimitedText:=Str;
        OAuth2Authenticator1.AccessToken:=Params.Values['access_token'];
        OAuth2Authenticator1.AccessTokenExpiry:=IncSecond(Now,StrToInt(Params.Values['expires_in']));
      finally
        Params.Free;
      end;
      WebForm.Close;
    end;
end;

Таким образом, после редиректа мы проверяем есть ли в URL подстрока #access_token= и, если такая строка имеется, то вытаскиваем из URL данные по Access Token и время его жизни — значение параметра expires_in.

Обратите внимание, что данные для доступа к API мы записываем сразу в компонент TOAuth2Authenticator1

Теперь нам необходимо создать форму, определить обработчик OnAfterRedirect и в нужный момент показать эту форму пользователю.
Что касается создания/уничтожения объекта формы, то это можно сделать где вам удобно. Для примера, я создаю форму авторизации в OnCreate главной формы, а уничтожаю, соответственно, в OnDestroy:

procedure TForm1.FormCreate(Sender: TObject);
begin
  WebForm:=Tfrm_OAuthWebForm.Create(nil);
  WebForm.OnAfterRedirect:=AfterRedirect;
end;
 
procedure TForm1.FormDestroy(Sender: TObject);
begin
  WebForm.Free;
end;

Процедуру авторизации пользователя напишем следующим образом:

type
  TForm1 = class(TForm)
    [...]
  private
    WebForm: Tfrm_OAuthWebForm;
    procedure AfterRedirect(const AURL: string; var DoCloseWebView : boolean);
    procedure Auth;
  public
    { Public declarations }
  end;
 
procedure TForm1.Auth;
begin
  OAuth2Authenticator1.AccessToken:=EmptyStr;
  OAuth2Authenticator1.ClientID:=cAppID;
  OAuth2Authenticator1.ClientSecret:=cAppKey;
  OAuth2Authenticator1.ResponseType:=TOAuth2ResponseType.rtTOKEN;
  OAuth2Authenticator1.AuthorizationEndpoint:=cEndPoint;
  WebForm.ShowWithURL(OAuth2Authenticator1.AuthorizationRequestURI);
end;

Здесь мы, опять же, используем компонент TOAuth2Authenticator — записываем в него данные нашего приложения (ID и секретный ключ), а также получаем URL, по которому необходимо перейти пользователю для авторизации.

Здесь стоит особое внимание обратить на следующую строку:

OAuth2Authenticator1.ResponseType:=TOAuth2ResponseType.rtTOKEN;

Здесь мы указываем какой тип ответа от сервера нам требуется и, в соответствии с этим параметром компонент будет формировать результат функции AuthorizationRequestURI. Если поле ResponseType оставить со значением по умолчанию (TOAuth2ResponseType.rtCode), то наш обработчик OnAfterRedirect окажется бесполезным, а вместо ключа доступа к API мы всегда будем получать на экране сообщение от VK вида:

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

Теперь вызываем метод Auth в обработчике OnClick кнопки и можем проверить наше приложение на каком-нибудь Android-устройстве:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Auth;
end;

Вот так будет выглядеть окно авторизации пользователя в запущенном приложении:
Screenshot_2014-04-28-01-56-31
Сразу после авторизации окно закроется и можно будет использовать API «ВКонтакте», что называется, на полную катушку.

2. Использование API «ВКонтакте»

Конечно, сегодня мы весь API «ВКонтакте» не переберем. Да и цели такой у меня не стоит. А вот некоторые моменты по работе с методами API рассмотрим.

С тем, как вызывать методы API вы можете ознакомиться на странице: http://vk.com/dev/api_requests.

Список всех доступных методов предоставлен на странице: http://vk.com/dev/methods

Вначале попробуем использовать какой-нибудь простенький метод. Например, в API есть довольно интересный метод — setOffline, который помечает текущего пользователя как offline. Метод доступен только приложениям с типом Standalone. Для вызова этого и других методов API и получения ответов сервера у нас на имеются следующие компоненты:

  • RESTClient1: TRESTClient;
  • RESTRequest1: TRESTRequest;
  • RESTResponse1: TRESTResponse;

Чтобы выполнять запросы к API определим у компонента RESTClient1 свойство BaseURL — для «ВКонтакте» это свойство должно содержать следующий URL — https://api.vk.com/method. 

У компонента RESTRequest1 необходимо выставить следующие значения свойств:

  • Client = RESTClient1
  • Response  = RESTResponse1

Теперь попробуем вызвать метод  account.setOffline API ВКонтакте и вывести результат в ListBox. Добавим на форму приложения ещё одну кнопку и напишем для неё такой обработчик OnClick:

procedure TForm1.Button2Click(Sender: TObject);
begin
  RESTRequest1.Resource:='account.setOffline';
  RESTRequest1.Method:=TRESTRequestMethod.rmGET;
  RESTRequest1.Execute;
  ListBox1.Items.Add(RESTResponse1.Content)
end;

Теперь можно запустить приложение и проверить ответ сервера при вызове метода setOffline:
Screenshot_2014-05-24-19-30-31

Соответствующим образом можно вызывать и другие методы API. Если же нам необходимо разобрать ответ сервера, то для этого можно воспользоваться свойством JSONValue компонента TRESTResponse.

Книжная полка

Описание: Книга рассчитана на подготовленного пользователя ПК, желающего самостоятельно научиться программировать и разрабатывать приложения и базы данных в среде Delphi. Опытные программисты смогут использовать издание как справочник. В тексте подробно описаны более 80 компонентов VCL, функции Object Pascal и Win32 API.
купить книгу delphi на ЛитРес
Автор: Юрий Магда
Описание: Описаны общие подходы к программированию приложений MS Office. Даны программные методы реализации функций MS Excel, MS Word, MS Access и MS Outlook в среде Delphi.
купить книгу delphi на ЛитРес

0 0 голоса
Рейтинг статьи
уважаемые посетители блога, если Вам понравилась, то, пожалуйста, помогите автору с лечением. Подробности тут.
Подписаться
Уведомить о
40 Комментарий
Межтекстовые Отзывы
Посмотреть все комментарии
Mifody
Mifody
26/05/2014 17:13

Отмечусь :). Сразу говорю, про REST Client Library ничего не знаю, может оно и автоматом настраивается, тогда практически весь коммент можно отнести к флуду :))). Все нижесказанное именно для Standalone, ибо с другим не работал. основной список параметров для получения токена client_id=APP_ID&scope=PERMISSIONS& redirect_uri=REDIRECT_URI&display=DISPLAY&v=API_VERSION&response_type=token «пробегусь» по основным значениям (которых не заметил в статье) REDIRECT_URI — надо задать https://oauth.vk.com/blank.html PERMISSIONS — если хочется не только читать, но и постить (а иногда и для «читать»), обязательно надо настраивать права доступа. Естественно не усердствовать, чтоб пользователя в панику не вводить. API_VERSION — указывать обязательно. Они в последнее время частенько играются и обновляют версию. Можно… Подробнее »

Mifody
Mifody
26/05/2014 18:48
Ответить на  Vlad

не знаю не знаю, меня индя практически наглухо отучила от «умных» библиотек :))).
кстати, если боль/мень серьезно не писал еще под VK, очень рекомендую чекать на ошибки результат ;), особенно на #6, «превышение частоты запросов». Ибо у всех, кто под контакт начинает писать — она частенько выскакивает :).

Хотяяяя, чему я «грешный» тебя учу :))))

Артем
Артем
12/07/2014 20:59

Привет. Как то странно, подуль REST.Authenticator.OAuth.WebForm.FMX не находит если активировать android SDK, если же поставить REST.Authenticator.OAuth.WebForm.FMX или REST.Authenticator.OAuth.WebForm.win при компиляции в win32 или под iOS, то все в норме. Не подскажете как решить проблему?

ypatidisioannis
ypatidisioannis
19/07/2014 16:26

Hello,

Is it possible to download this sample code?

Maybe can you send it to me through email?

Many Thanks
Ioannis

Владимир Тютимов

А как после авторизации на сайте, выйти из него?

Владимир Тютимов
Ответить на  Vlad

Да, спасибо, уже разобрался.
Но вот появилась другая проблема. Отправляю сообщение (берется из Memo), но на сайт приходить абракадабра. Дело понятно в кодировке. Смотрю кодировку страницы Вк. Получаем windows-1251. Выставляю в компоненте RESTRequest вместо UTF-8 windows-1251. И ничего не вышло из этого успешного. Как правильно настроить кодировку?

Владимир Тютимов
Ответить на  Vlad

Спасибо, прочитаю.

Владимир Тютимов
Ответить на  Vlad

Я так и не разобрался, как мне перевести текст из Мемо и отправить его в ВК. Ведь я не могу в параметр запроса включить массив байт, а из массива конвертировать могу только обратно в UnicodeString. Очень сильно прошу помочь.

Владимир Тютимов
Ответить на  Vlad

Оба варианта приводят к одному и тому же. В сообщении приходит абракадабра. А может настройки RESTClient и RESTRequest нужно поменять. У них ведь есть свойства: AcceptCharset, FallbackCharsetEncoding.
У меня установлены следующие параметры:
для RESTClient: AcceptCharset: windows-1251, *;q=0.8, FallbackCharsetEncoding: UTF-8
для RESTRequest: windows-1251, *;q=0.8

Владимир Тютимов
Ответить на  Vlad

Мне нужно отправить сообщение из программы в ВК. Я отправляю. Когда заходишь через браузер в ВК сообщение показывается абракадаброй. Перепробовал разные варианты перекодировки все равно одно и тоже. Английские буквы нормально доходят.

Владимир Тютимов
Ответить на  Vlad

Огромное спасибо!

trackback

[…] заметка по мотивам обсуждения предыдущей статьи на тему использования API ВКонтакте в Delphi.  Чтобы […]

trackback

[…] я уже писал неоднократно и по-разному — кратко, подробно, подробно и с картинками, но, как показывает мой […]

trackback

[…] дам ссылку на статью где про это рассказывается — вот она. Отмечу только, […]

kidrock
kidrock
24/11/2014 18:11

Уважаемый, Vlad, не могли бы прислать выложить проект целиком?

kidrock
kidrock
24/11/2014 23:33
Ответить на  Vlad

Я новичок в Delphi у меня всё рушится на строке
» if (i>0) and (OAuth2Authenticator1.AccessToken=EmptyStr) then»
Я так понимаю, что ругается он на знак амперсанда. Я удалил условие (i>0) и следующая ошибка у меня вылезла на строке:
«Params.Delimiter:=’&’;»
Как бы мне избавиться от этой проблемы?

Mifody
Mifody
25/11/2014 00:59
Ответить на  kidrock

Мньдя, без обид, но уж слишком «новичек» чтоб в такое лезть.
1. амперсанды лезут в HTML где есть спец символы. Посмотрите, у Вас ведь заменилось слово с авмерсандом на знак «меньше»
2. что за ошибка в строке «Params.Delimeder = …»?

чес слова, дальше будет хуже, «слизать» под чистую код не получится :). Даже еслиб Vlad дал все сырцы. В API еще есть маленькй «вагончик» тонкостей ;)

kidrock
kidrock
28/11/2014 18:22
Ответить на  Mifody

Да нет, никто не говорит про слизать. Просто есть конкретная задача, которую интересно делать. Просто, взяв, этот код, я начал его компилировать и у меня полезли ошибки там где есть знак амперсанда. В этом и непонимание, как у Влада всё собирается, а у меня нет.

Mifody
Mifody
28/11/2014 19:43
Ответить на  Mifody

kidrock — ответе на один вопрос «а должен ли быть этот апостроф?»
чес слово, тяжко Вам будет

кстати, посмотрите свое сообщение выше после строки «Я новичок в Delphi у меня всё рушится на строке». И сравните — то же самое у Вас в делфях или нет?

Александр Гвоздев

Пытаюсь сделать такое под Windows в FM но при запуске WebForm в ней нечего нет кроме кнопки Close. Как исправить?

Григорий
Григорий
23/04/2015 14:39

Что означает «if (i>0)»? Делфи ругается…

Канат
Канат
21/05/2015 19:11

Помогите пожалуйста, есть код
curl -X GET
-H ‘application-id : 42BB8529-901B-C64E-FF8E-782D215D9000’
-H ‘secret-key : CAB59AE0-D1CD-0F1B-FF14-CC8B18866D00’
http://api.backendless.com/v1/data/ChatUser

Как правильно написать запрос REST и получит ответ любая помощь.
Спасибо

Дмитрий
Дмитрий
23/08/2015 20:22

Спасибо за статью! Но вот как после авторизации на сайте, выйти из него? Так и не разобрался.

Mifod
Mifod
24/08/2015 17:43
Ответить на  Дмитрий

Что значит «выйти»? Если снести сессию на сервере (если оно там конечно вообще храниться) — то имитация Logout браузера.
Если просто чтоб при следующем запросе попросило пароль — запрос без куков.

З.Ы. Лично мне, ни разу не понадобилось «выйти» из авторизации через Logout

Дмитрий
Дмитрий
25/08/2015 01:54
Ответить на  Mifod

Да как раз и нужен запрос без куков. Но как сделать используя WebBrowser? Уже мозг сломал.

Дмитрий
Дмитрий
25/08/2015 04:25
Ответить на  Vlad

Спасибо за вариант. Я делал тоже самое только вручную. Теперь автоматизирую

Иван
Иван
02/07/2016 21:54

При сборке ругается на эти строки:
property OnBeforeRedirect: TOAuth2WebFormRedirectEvent read FOnBeforeRedirect write FOnBeforeRedirect;
property OnAfterRedirect: TOAuth2WebFormRedirectEvent read FOnAfterRedirect write FOnAfterRedirect;

Можете помочь?

Александр Вяземский

Автор, я делал как вы только под пк а не под андроид и вылазит куча ошибок. Можно с вами как то связаться что бы в ЛС?