В качестве примера использования API в Delphi рассмотрим как получить список всех счётчиков, зарегистрированных в аккаунте Метрики, а также получим информацию по любому из доступных счётчиков.
Прежде, чем начнем рассматривать тему, рекомендую Вам ознакомиться с постом “Авторизация в сервисах Яндекс. Используем логин и пароль.” так как именно этот способ мы сегодня будем использовать для работы с API.
Шаг №1 Регистрируем нового клиента API
Для регистрации нового клиента для работы с API Метрики необходимо перейти по этой ссылке и заполнить необходимые поля, например, следующим образом:
Жмем кнопку “Создать” и Яндекс перенаправляет нас на страницу с информацией по клиенту. Здесь для нас главное – запомнить ID клиента, т.к. без него нас не допустят к авторизации:
Теперь приступим реализации мечт задач.
Шаг №2. Авторизуемся в Метрике и получаем Token
Так как способов авторизации в Яндекс для настольных приложений как минимум два (раз и два), то я решил создать отдельный небольшой класс для авторизации в котором, по мере возможностей буду реализовывать возможность использования обоих способов.
Заготовка для класса получилась следующая:
type TAuthorizer = class private FAuthorized: boolean; FLogin: string; FPassword: string; FClientId: string; FOAuthToken: string; FServerResponse: string; procedure SetLogin(const Value: string); procedure SetPassword(const Value: string); public constructor Create; destructor Destroy; override; procedure Authorize; property Authorized: boolean read FAuthorized; property OAuthToken: string read FOAuthToken; property ClientID: string read FClientId write FClientId; property Login: string read FLogin write SetLogin; property Password: string read FPassword write SetPassword; property ServerResponse: string read FServerResponse; end;
Login и Password — это логин и пароль для доступа к аккаунту Яндекс.
ClientId — ID нашего клиента для авторизации
OAuthToken — токен, который мы получим в ходе авторизации и будем использовать для доступа к методам API
ServerResponse — ответ сервера (код и статус). Это свойство я добавил на всякий случай, для отладки работы класса, думаю, что в последствии надобность в нем отпадет.
Authorized — True указывает на то, что в процессе выполнения метода Authorize был получен токен, т.е. можно смело приступать к использованию методов API;
Для работы с HTTP-протоколом я, как всегда использовал Synapse. Признаюсь, было желание сделать работу с этим модулем доступной более широкому кругу пользователей Delphi и использовать в работе Indy, но потом решил, что те кому надо без проблем перепишут всего 1 метод класса и получат то, что хочется – хоть с Indy, хоть с ICS. Ну, а метод сам по себе довольно простой:
procedure TAuthorizer.Authorize; var Params: TStringStream; begin //если не определен ID, то авторизация 100% проваливается - генерируем исключение if Length(FClientId)=0 then raise Exception.Create(rsErrClientID); //cParams = 'grant_type=password&client_id=%s&username=%s&password=%s'; Params := TStringStream.Create(Format(cParams, [FClientId, FLogin, FPassword])); try with THTTPSend.Create do begin Document.LoadFromStream(Params); //cAuthURL = 'https://oauth.yandex.ru/token'; if HTTPMethod('POST', cAuthURL) then begin FAuthorized := (ResultCode = 200); if FAuthorized then begin Params.LoadFromStream(Document); //парсим токен, используя регулярные выражения Delphi XE FOAuthToken := TRegEx.Match(Params.DataString, '"access_token": "(.*)"').Groups.Item[1].Value; end end else FAuthorized := false; end finally Params.Free; end; end;
Теперь у нас есть класс с помощью которого мы будем авторизовываться в Метрике. Переходим к следующему шагу – пишем класс для работы с API.
Шаг №3. Класс для работы с API Яндекс.Метрика
Итак, теперь кратко о том, что представляет из себя API Яндекс.Метрики. Во-первых, API довольно большой и, если сравнивать его с теми же API Google, то по объему он примерно как Google Calendar API. То есть за один день переложить его на рельсы Delphi, как, например, API Спеллера нам не удастся. Поэтому будем реализовывать то, что потребуется поэтапно.
Во-вторых, API может возвращать (а также и принимать) данные в двух форматах: XML и JSON. Что касается форматов, какой использовать и, чем парсить ответы – дело сугубо личное и, если с HTTP-протоколом все выглядит относительно легко в плане переносимости, то с API я решил ограничиться тем, что класс будет выдавать в качестве результатов обычную строку (string), содержащую ответ API, а выбор инструмента для парсинга останется за конечным пользователем модуля – хотите, заносите строку в NativeXML и формируйте XML-документ, хотите – используйте SuperObject и парсите ответы в формате JSON.
API может принимать GET, POST, PUT и DELETE-запросы.
Сегодня рассмотрим организацию работы с GET-запросами и научимся получать данные по счётчикам.
Создаем следующие типы данных:
type TOutputFormat = (tfXML, tfJSON);//формат ответа TCounterPermission = (no_premission, own, view, edit);//уровень доступа к счётчику TCounterType = (no_type, simple, partner);//тип счётчика type TYandexMetrica = class private FAuthorizer: TAuthorizer;//объект для авторизации в API FOutputFormat: TOutputFormat;//формат выходных данных function GETCommand(Method: string; Params: TStringList): string;//метод для отправки GET-запроса procedure SetOutputFormat(const Value: TOutputFormat); public constructor Create; destructor Destroy; override; {Возвращает список существующих счетчиков, доступных пользователю.} function GetCounters(Params: TStringList): string; overload; function GetCounters(CounterType: TCounterType; CounterPremission: TCounterPermission; ulogin:string=''; field: string='') : string; overload; {Возвращает информацию об указанном счетчике} function GetCounter(id: integer; field:string=''): string; property Authorizer: TAuthorizer read FAuthorizer write FAuthorizer; property OutputFormat: TOutputFormat read FOutputFormat write SetOutputFormat; end;
Любой запрос к API может иметь следующий формат:
<тип_метода> http://api-metrika.yandex.ru/<имя_метода>.<формат_результата>?<параметры>
В зависимости от того, какой метод мы будем использовать (GET, POST и т.д.) будет зависеть работа с классами в Synapse, поэтомя я решил для каждого типа запрос сделать отдельный универсальный метод отправки данных и получения результата. Например, для GET-запроса — это метод GETCommand, который выглядит следующим образом:
function TYandexMetrica.GETCommand(Method: string; Params: TStringList): string; var URL, ParamsStr, outFormat: string; i: integer; Data: TStringStream; begin if not FAuthorizer.Authorized then Exit; if Params <> nil then begin Params.Delimiter := '&'; ParamsStr := Params.DelimitedText; end; outFormat := GetEnumName(TypeInfo(TOutputFormat), ord(OutputFormat)); outFormat := Copy(outFormat, 3, Length(outFormat) - 2); URL := Format(cApiURL, [Method, LowerCase(outFormat), FAuthorizer.OAuthToken]); if Length(ParamsStr) > 0 then URL := URL + '&' + ParamsStr; Data := TStringStream.Create; try with THTTPSend.Create do begin if HTTPMethod('GET', URL) then begin Data.LoadFromStream(Document); Result := Data.DataString; end else raise Exception.Create('Ошибка отправки запроса'); end; finally Data.Free; end; end;
В этом методе используется следующая константа:
cApiURL = 'http://api-metrika.yandex.ru/%s.%s?oauth_token=%s';
Создав этот метод мы теперь можем использовать любые методы API, которые поддерживают передачу параметров, через GET-запросы. В качестве примера, рассмотрим метод получения списка счётчиков:
function TYandexMetrica.GetCounters(Params: TStringList): string; begin Result := GETCommand('counters', Params); end;
Или его overload-версию с указанием необходимых параметров:
function TYandexMetrica.GetCounters(CounterType: TCounterType; CounterPremission: TCounterPermission; ulogin, field: string): string; var Params: TStringList; begin Params := TStringList.Create; try if CounterPremission <> no_premission then Params.Add('permission=' + GetEnumName(TypeInfo(TCounterPermission), ord(CounterPremission))); if CounterType<>no_type then Params.Add('type=' + GetEnumName(TypeInfo(TCounterType), ord(CounterType))); if Length(ulogin)>0 then Params.Add('ulogin='+ulogin); if Length(field)>0 then Params.Add('field='+field); Result:=GetCounters(Params); finally Params.Free; end; end;
Как видите, в обоих случаях я никак не использую Synapse в явном виде — вся работа с библиотекой осталась в GETCommand, а значит перенести код под работу с другой библиотекой становится намного проще — надо будет подправить всего один метод вместо трех. Ещё один пример использования GETCommand — получение информации по конкретному счётчику, здесь параметр Method:string для GETCOmmand формируеся немного иначе:
function TYandexMetrica.GetCounter(id:integer; field: string): string; var Method: string; Params: TStringList; begin Method:=Format('counter/%d',[id]);//формируем параметр Method Params:=TStringList.Create; try if Length(field)>0 then Params.Add('field='+field); Result:=GETCommand(Method,Params);//получаем ответ finally Params.Free; end; end;
Теперь остается только рассмотреть небольшой примерчик работы с модулем.
Шаг №4. Пример использования модуля для работы с API Яндекс.Метрика в Delphi
Создадим новое приложение в Delphi, которое будет выглядеть, например, так:
По клику на кнопке “Авторизация” мы:
1. Пробуем авторизоваться
2. Если авторизация прошла успешно, то выводим на форму значение токена и читаем данные по зарегистрированным счётчикам. Ответ выводим в Memo.
Код обработчика OnClick:
procedure TForm2.Button1Click(Sender: TObject); var Auth: TAuthorizer; Metric: TYandexMetrica; begin Metric := TYandexMetrica.Create; try Metric.Authorizer.Login := Edit1.Text; Metric.Authorizer.Password := Edit2.Text; //авторизуемся Metric.Authorizer.Authorize; if Metric.Authorizer.Authorized then begin Label4.Caption:=Metric.Authorizer.OAuthToken; //устанавливаем формат выходных данных Metric.OutputFormat := tfJSON; //выводим ответ Memo1.Text := Metric.GetCounters(nil);//(запрос без параметров) end; finally Metric.Destroy; end; end;
В результате выполнения мы получим ответ в формате JSON, который будет содержать информацию по всем зарегистрированным счётчикам, которая будет включать в себя только данные по умолчанию, т.е. URL и название сайта, логин владельца, тип доступа, ID счётчика и его статус. Теперь мы можем подключить к проекту любую библиотеку для работы с JSON в Delphi и представить все полученные данные в удобном виде, но это уже, как я сказал выше, зависит от того какое у кого мировоззрение и с чем каждый из нас привык больше работать.
Книжная полка
Описание: Рассмотрены практические вопросы по разработке клиент-серверных приложений в среде Delphi 7 и Delphi 2005 с использованием СУБД MS SQL Server 2000, InterBase и Firebird. Приведена информация о теории построения реляционных баз данных и языке SQL. Освещены вопросы эксплуатации и администрирования СУБД.
|
||
Название: О чем не пишут в книгах по Delphi
Описание: Рассмотрены малоосвещенные вопросы программирования в Delphi. Описаны методы интеграции VCL и API. Показаны внутренние механизмы VCL и приведены примеры вмешательства в эти механизмы. Рассмотрено использование сокетов в Delphi: различные режимы их работы, особенности для протоколов TCP и UDP и др.
|
Супер спасибо!
Доброго времени суток! Пытаюсь осуществить данное приложение на основе Вашего кода.
Выдает ошибку [DCC Error] YandexMetrica.pas(95): E2233 Property ‘Match’ inaccessible here,
в процедуре procedure TAuthorizer.Authorize; в строке: FOAuthToken := TRegExpr.Match(Params.DataString,…
+ 2 ошибки [DCC Error] YandexMetrica.pas(95): E2066 Missing operator or semicolon,
в строке …(Params.DataString,'»access_token»: «(.*)»‘).Groups.Item[1].Value;
+ ошибка [DCC Fatal Error] Unit1.pas(7): F2063 Could not compile used unit ‘YandexMetrica.pas’
(unit1 — юнит созданный с формой)
Напишите пожалуйста,если можете, что может быть не так ) Заранее спасибо!
Извиняюсь, только сейчас увидел сверху надпись, что Яндекс изменил авторизацию, наверно из-за этого выдает ошибки…)
Ivan, аналогично — извиняюсь, что сразу не ответил (занят сейчас просто торба). Вы, скорее всего правы — ошибка может быть из-за смены методов авторизации. Если подождете недельку-другую — сможем вместе разобраться
Добрый день.
А подскажите пожалуйста, эта компонента живая.
Я попробовал ее использовать с YMetrics, но не проходит авторизация?
Добрый день. Скорее всего, что не работает уже. Надо авторизацию переписывать