API Календаря Google - PATCH возвращает 200 OK, но не обновляет событие - PullRequest
2 голосов
/ 25 марта 2012

Я пытаюсь интегрировать календарь моего веб-приложения в Календарь Google. Я успешно аутентифицирую пользователя, могу читать события из Google и удалять события из Google. У меня проблемы с обновлением событий из моего приложения в Google.

Я использую метод PATCH, описанный здесь , так как я хочу изменить только поля, которые я отправляю в вызове API (в отличие от вызова PUT, который требует все поля для события).

Мой код Perl создает объект JSON, представляющий то, что я хочу изменить. Затем я отправляю запрос PATCH в Google, и я получаю статус 200 OK и ресурс события от Google. То, что я получаю обратно, должно быть измененным ресурсом события, но измененные поля не изменяются в ответе. Когда я проверяю в самом Календаре Google, я снова вижу, что событие не изменено.

Я не понимаю, почему я получаю ответ 200 OK вместо ошибки, когда событие не обновляется. Любопытно, что в ответе «обновленное» свойство метки времени было обновлено, а поле сводки - нет.

  my $ua = LWP::UserAgent->new;

  my $url = "https://www.googleapis.com/calendar/v3/calendars/primary/events/${id}?access_token=${access_token}";

  my $resource{"summary"} = "$g{summary}";

  $resource = encode_json(\%resource);

  my $headers = HTTP::Headers->new();
  $headers->header(If_Match => "$etag");

  my $request = HTTP::Request->new('PATCH',$url,$headers,$resource);

  my $response = $ua->request($request);

  my $status = $response->status_line;

  my $result = decode_json($response->decoded_content);

Значение "etag" из результата обновляется, как я ожидаю, что указывает на то, что событие календаря (несколько) изменяется в Google.

Некоторые данные :: Трассировка самосвала:

Запрос:

$VAR1 = bless( {
                 '_content' => '{"summary":"End of season function MODIFIED"}',
                 '_uri' => bless( do{\(my $o = 'https://www.googleapis.com/calendar/v3/calendars/primary/events/<eventID>?access_token=<access_token>')}, 'URI::https' ),
                 '_headers' => bless( {
                                        'if-match' => '<etag>'
                                      }, 'HTTP::Headers' ),
                 '_method' => 'PATCH'
               }, 'HTTP::Request' );

Ответ:

$VAR1 = bless( {
                 '_protocol' => 'HTTP/1.1',
                 '_content' => '{
 "kind": "calendar#event",
 "etag": "<etag>",
 "id": "<eventID>",
 "status": "confirmed",
 "htmlLink": "<suppressed>",
 "created": "2012-03-08T05:06:04.000Z",
 "updated": "2012-03-25T09:18:49.000Z",
 "summary": "End of season function",
 "creator": {
  "email": "<suppressed>"
 },
 "organizer": {
  "email": "<suppressed>"
 },
 "start": {
  "date": "2012-03-24"
 },
 "end": {
  "date": "2012-03-24"
 },
 "iCalUID": "<suppressed>",
 "sequence": 1,
 "reminders": {
  "useDefault": true
 }
}
',
                 '_rc' => '200',
                 '_headers' => bless( {
                                        'connection' => 'close',
                                        'cache-control' => 'no-cache, no-store, max-age=0, must-revalidate',
                                        'date' => 'Sun, 25 Mar 2012 09:18:49 GMT',
                                        'client-ssl-cert-issuer' => '/C=US/O=Google Inc/CN=Google Internet Authority',
                                        'client-ssl-cipher' => 'ECDHE-RSA-RC4-SHA',
                                        'client-peer' => '173.194.72.95:443',
                                        'client-date' => 'Sun, 25 Mar 2012 09:18:49 GMT',
                                        'pragma' => 'no-cache',
                                        'content-type' => 'application/json; charset=UTF-8',
                                        'x-xss-protection' => '1; mode=block',
                                        'server' => 'GSE',
                                        'client-ssl-socket-class' => 'IO::Socket::SSL',
                                        'client-response-num' => 1,
                                        'etag' => '<etag>',
                                        'x-frame-options' => 'SAMEORIGIN',
                                        'x-content-type-options' => 'nosniff',
                                        'client-ssl-cert-subject' => '/C=US/ST=California/L=Mountain View/O=Google Inc/CN=*.googleapis.com',
                                        'expires' => 'Fri, 01 Jan 1990 00:00:00 GMT'
                                      }, 'HTTP::Headers' ),
                 '_msg' => 'OK',
                 '_request' => bless( {
                                        '_content' => '{"summary":"End of season function MODIFIED"}',
                                        '_uri' => bless( do{\(my $o = 'https://www.googleapis.com/calendar/v3/calendars/primary/events/<eventID>?access_token=<access_token>')}, 'URI::https' ),
                                        '_headers' => bless( {
                                                               'user-agent' => 'libwww-perl/6.01',
                                                               'if-match' => '<etag>'
                                                             }, 'HTTP::Headers' ),
                                        '_method' => 'PATCH',
                                        '_uri_canonical' => $VAR1->{'_request'}{'_uri'}
                                      }, 'HTTP::Request' )
               }, 'HTTP::Response' );

Кто-нибудь может увидеть, что я делаю не так? Я уверен, что Google принимает мой запрос PATCH, но по какой-то причине не совсем видит поле, которое я хочу изменить. Я попытался отправить точно такой же объект JSON на их страницу тестирования , и у меня нет проблем с тем, чтобы это работало ...

1 Ответ

3 голосов
/ 25 марта 2012

Я нашел решение чисто методом проб и ошибок - добавление заголовка «Content-Type» в заголовок HTTP, похоже, помогло:

  my $headers = HTTP::Headers->new();
  $headers->header(If_Match => "$etag");
  $headers->header(Content_Type => "application/json");
...