declare
    l_refresh_token varchar2(4000) := :G_REFRESH_TOKEN;
    l_response clob;
    l_response_json json_object_t;
    l_access_token varchar2(4000);
    l_expires_in_sec number;
    C_CRED_OAUTH2 constant varchar2(20) := 'GOOGLE_DRIVE_CRED';
    C_CRED_BASIC  constant varchar2(20) := 'GOOGLE_OIDC_BASIC';
begin
    apex_web_service.clear_request_headers;
    apex_web_service.set_request_headers('Content-Type','application/x-www-form-urlencoded',p_reset => false);
    l_response := apex_web_service.make_rest_request(
        p_url => 'https://oauth2.googleapis.com/token'
        ,p_http_method => 'POST'
        ,p_body => 'grant_type=refresh_token' || chr(38) || 'refresh_token=' || l_refresh_token
        ,p_credential_static_id => C_CRED_BASIC
    );
    l_response_json  := json_object_t.parse(l_response);
    /* アクセス・トークンのアップデート */
    l_access_token   := l_response_json.get_string('access_token');
    l_expires_in_sec := l_response_json.get_number('expires_in');
    if l_access_token is not null then
        apex_credential.set_session_token(
            p_credential_static_id => C_CRED_OAUTH2
            ,p_token_type          => APEX_CREDENTIAL.C_TOKEN_ACCESS
            ,p_token_value         => l_access_token
            ,p_token_expires       => (sysdate + l_expires_in_sec/86400)
        );
        apex_debug.info('Access Token is updated by %s', substr(l_access_token, 1,20));
    else
        apex_debug.info('Access Token is not updated.');
    end if;
    /*
     * Googleの場合、リフレッシュ・トークンに有効期限がなく、アクセス・トークンのリフレッシュ時に
     * 再発行もされない模様。
     */
end;