UsefulWeb/AmoCRM

Возвращает пустой ответ

neizerth opened this issue · 13 comments

возможно это другая ошибка но, все же. Сначала работало нормально, первые сутки, потом вот. Код который я бросал ранее, все еще актуален и не менялся.

image

Вот кстати место где возникает ошибка. Походу ничего не приходит из API. Судя по всему. В чем может быть проблема?
image

При переинициализации (удалении старого токена вручную и повторной авторизации через ссылку) все работает корректно на текущий момент.

Но то что API отваливается само по себе конечно плоховато

Originally posted by @westprophet in #33 (comment)

@westprophet нужна детальная информация об ответе на запрос. Получится выложить в консоль?

@neizerth конечно, я прямо сейчас выложу

@neizerth вот.

Что вывожу по коду.
image

{
  info: <ref *1> IncomingMessage {
    _readableState: ReadableState {
      objectMode: false,
      highWaterMark: 16384,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: [],
      flowing: true,
      ended: true,
      endEmitted: true,
      reading: false,
      sync: true,
      needReadable: false,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: false,
      destroyed: false,
      defaultEncoding: 'utf8',
      awaitDrainWriters: null,
      multiAwaitDrain: false,
      readingMore: true,
      decoder: null,
      encoding: null,
      [Symbol(kPaused)]: false
    },
    readable: false,
    _events: [Object: null prototype] {
      end: [Array],
      data: [Function: onResponseData]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: true,
      _SNICallback: null,
      servername: 'redwest.amocrm.ru',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'redwest.amocrm.ru',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [ClientRequest],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 7503,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    httpVersionMajor: 1,
    httpVersionMinor: 1,
    httpVersion: '1.1',
    complete: true,
    headers: {
      server: 'nginx',
      date: 'Thu, 18 Feb 2021 19:01:11 GMT',
      'content-type': 'application/problem+json',
      'transfer-encoding': 'chunked',
      connection: 'close',
      'set-cookie': [Array],
      expires: 'Thu, 19 Nov 1981 08:52:00 GMT',
      'cache-control': 'no-store, no-cache, must-revalidate',
      pragma: 'no-cache',
      'x-request-id': 'd140522bac3dc46882dc48f183e82282',
      'x-runtime-generated': '0.229'
    },
    rawHeaders: [
      'Server',
      'nginx',
      'Date',
      'Thu, 18 Feb 2021 19:01:11 GMT',
      'Content-Type',
      'application/problem+json',
      'Transfer-Encoding',
      'chunked',
      'Connection',
      'close',
      'Set-Cookie',
      'session_id=****; path=/; domain=.amocrm.ru; secure; HttpOnly',
      'Expires',
      'Thu, 19 Nov 1981 08:52:00 GMT',
      'Cache-Control',
      'no-store, no-cache, must-revalidate',
      'Pragma',
      'no-cache',
      'X-Request-Id',
      'd140522bac3dc46882dc48f183e82282',
      'X-Runtime-Generated',
      '0.229'
    ],
    trailers: {},
    rawTrailers: [],
    aborted: false,
    upgrade: false,
    url: '',
    method: null,
    statusCode: 401,
    statusMessage: 'Unauthorized',
    client: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      secureConnecting: true,
      _SNICallback: null,
      servername: 'redwest.amocrm.ru',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'redwest.amocrm.ru',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [ClientRequest],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 7503,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _consuming: false,
    _dumped: false,
    req: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: [TLSSocket],
      _header: 'POST /api/v4/leads/unsorted/forms HTTP/1.1\r\n' +
        'Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImp0aSI6IjJiNTFiYmY3N2E5YTMwYTNmZTg0ZmE2Y2I2YmY3NGU2ZTU3NDA5NWRkZmFmMjJhNzk4MzdlZTljNGFiNTAwNWMxZDlkMGZlOTFhYTI3ZmRjIn0.eyJhdWQiOiJkZGVhNTU4NS0wYTI5LTQ5OTgtODg4Ny02NzZjNDg5MDFkOTIiLCJqdGkiOiIyYjUxYmJmNzdhOWEzMGEzZmU4NGZhNmNiNmJmNzRlNmU1NzQwOTVkZGZhZjIyYTc5ODM3ZWU5YzRhYjUwMDVjMWQ5ZDBmZTkxYWEyN2ZkYyIsImlhdCI6MTYxMzUwNjA4NiwibmJmIjoxNjEzNTA2MDg2LCJleHAiOjE2MTM1OTI0ODYsInN1YiI6IjY0MzAyMTMiLCJhY2NvdW50X2lkIjoyOTA5Njg1MSwic2NvcGVzIjpbInB1c2hfbm90aWZpY2F0aW9ucyIsImNybSIsIm5vdGlmaWNhdGlvbnMiXX0.nIPL5ZFssyHUQxkjsaVh4ssKymPdrGCJXBCJImCJ-TvGodQDh8kOF2F9Hc7HTs6d_pwTV0SBXoGYcffJqfgewsMw4okBZ_SfFlHiOLAVnxnrcu1Cg_1kaJfCzafRcmcEoZ8uNRBlrh6yFQFO-efuW-Ojjyu7Sg6KtUhVC6J7H7YD3ZkQiYeGilow_dmO5uLktdjic44PaVINXdELNVgSRNkRwEROKc18vjBp3YWuL1vHLK-3AHBoG1L2pjP-0fqloXhPF2EW4LRqi7q2zHf0lpXNyKonMNVOUZYe03CasOvt3IrM0UGjLBKqmNb-GuW2zNZeoDhYb7R6Z31GW9bPww\r\n' +
        'Content-Type: application/json\r\n' +
        'Content-Length: 1185\r\n' +
        'Host: redwest.amocrm.ru\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _onPendingData: [Function: noopPendingOutput],
      agent: [Agent],
      socketPath: undefined,
      method: 'POST',
      maxHeaderSize: undefined,
      insecureHTTPParser: undefined,
      path: '/api/v4/leads/unsorted/forms',
      _ended: true,
      res: [Circular *1],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    [Symbol(kCapture)]: false
  },
  data: {
    title: 'Unauthorized',
    type: 'https://httpstatus.es/401',
    status: 401,
    detail: 'Неверный логин или пароль'
  }
}

В data пишет:
data: { title: 'Unauthorized', type: 'https://httpstatus.es/401', status: 401, detail: 'Неверный логин или пароль' }

Такое ощущение, что токен отозван

@neizerth вполне вероятно, ибо если я удалю токен вручную и попробую еще раз пройти авторизацию через ссылку все будет работать примерно сутки.

@neizerth такое ощущение что обновление токена автоматически не происходит.

@westprophet Да, похоже. Разберусь

@neizerth я прошу прощения, если можно как можно раньше, у меня пошли клиенты и API отваливается :-) Если я могу помочь, дайте знать. Очень нужно срочно.

headers: {
      server: 'nginx',
      date: 'Thu, 18 Feb 2021 19:01:11 GMT',
      'content-type': 'application/problem+json',
      'transfer-encoding': 'chunked',
      connection: 'close',
      'set-cookie': [Array],
      expires: 'Thu, 19 Nov 1981 08:52:00 GMT',
      'cache-control': 'no-store, no-cache, must-revalidate',
      pragma: 'no-cache',
      'x-request-id': 'd140522bac3dc46882dc48f183e82282',
      'x-runtime-generated': '0.229'
    },

@westprophet судя по заголовкам, проблема в expires.

Работе с ней посвящено несколько функций:

handleToken( response ) {

isRequestExpired() {

Проблема скорее тут. Буду рад MR'у, но до выходных вряд ли успею сам взяться

@neizerth во всяком случае буду очень рад, если у Вас получится сделать. Я в Вас верю!

@neizerth такое ощущение что обновление токена автоматически не происходит.

При получении токена - его expires - как раз сутки.
В работе скрипта есть два случая:

1 кейс
Работаем со скриптом → на какое-то время оставили → токен протух
Запускаем скрипт → setToken() → там this._isConnected становится falseconnectIfNeeded() не даёт рефрешить токен отправляя на connect()

Чтобы не ждать когда ребята найдут решение можно принудительно рефрешить каждый раз:
crm.connection.setToken(_MY_SHINY_TOKEN_).refreshToken();

2 кейс
Когда вы запустили в продакшн эта ситуация не возникнет.
Потому что: токен протух → перед запросом вызывается connectIfNeeded() → и в этот момент this._isConnected пока ещё true — поэтому после проверки isRequestExpired() выполняется refreshToken() и всё продолжает работать.

При явном вызове этого метода в develop режиме. Приложение нормально обновляет токен и в конце вызывает событие newToken которое записывает в файл новый токен.

При работе приложения в product режиме - срабатывает событие beforeRefreshToken и дальше ничего не происходит. Подозреваю что _request возращает неудачную попытку, а так как в коде метода refreshToken не прописан метод catch для promise запроса к серверу то возможно что новый токен просто не записывается в файл так как срабатывает событие catch вместо then.

  refreshToken() {
    this.triggerEvent( 'beforeRefreshToken', this );
    const {
        client_id,
        client_secret,
        redirect_uri,
      } = this._options,
      token = this.getToken();
    if ( !token ) {
      console.log('no token');
      return Promise.reject( 'no token' );
    }
    const { refresh_token } = token,
      data = {
        client_id,
        client_secret,
        redirect_uri,
        refresh_token,
        grant_type: 'refresh_token',
      };

    return this._request.post( schema.auth.token, data )
      .then( response => {
    
        this.handleToken( response );

        return response;
        
      })

Запускается приложение в demon через пакет pm2.

Сразу исключаю что токен был не свежий так как перед этим я повторно провел инициализацию через ссылку и получил свежий токен который записался в файл. И сразу же я перезапустил сервер и вызвал refreshToken. Который вот по сути не работает на Production.

Самостоятельно не получилось настроить адекватную работу пакета. Все так же через несколько дней API отваливается. Пробовал принудительно запрашивать новый токен по таймеру каждые 2 часа, но как я писал выше просто не срабатывает событие newToken и новый токен просто не перезаписывается в файл.

Использую пакет в CMS Strapi. И данная проблема возникает только когда запускаешь production!
В development - проблемы по идее не должно возникать.
Strapi в production запускается с помощью pm2.

К сожалению физически нет столько времени разбираться в особенностях работы пакета. Заявка на этот баг висит уже давно. У кого возникла подобная проблема - пишите. Возможно вместе решим эту как мне кажется маленькую но важную проблему.

Если будет новая информация - выложу сюда.