account-activity-dashboard icon indicating copy to clipboard operation
account-activity-dashboard copied to clipboard

Unable to add new subscription.

Open vverma508 opened this issue 6 years ago • 12 comments

I think after latest changes from twitter, add subscription if throwing error. Please help.

Error: Callback URL not approved for this client application. Approved callback URLs can be adjusted in your application settings at Strategy.parseErrorResponse (d:\VSCodeWorkSapce\account-activity-dashboard-master\node_modules\passport-twitter\lib\strategy.js:206:12) at Strategy.OAuthStrategy._createOAuthError (d:\VSCodeWorkSapce\account-activity-dashboard-master\node_modules\passport-oauth1\lib\strategy.js:393:16) at d:\VSCodeWorkSapce\account-activity-dashboard-master\node_modules\passport-oauth1\lib\strategy.js:244:41 at d:\VSCodeWorkSapce\account-activity-dashboard-master\node_modules\oauth\lib\oauth.js:543:17 at passBackControl (d:\VSCodeWorkSapce\account-activity-dashboard-master\node_modules\oauth\lib\oauth.js:397:13) at IncomingMessage. (d:\VSCodeWorkSapce\account-activity-dashboard-master\node_modules\oauth\lib\oauth.js:409:9) at emitNone (events.js:111:20) at IncomingMessage.emit (events.js:208:7) at endReadableNT (_stream_readable.js:1064:12) at _combinedTickCallback (internal/process/next_tick.js:138:11) at process._tickCallback (internal/process/next_tick.js:180:9)

vverma508 avatar Oct 04 '18 09:10 vverma508

Found this,

https://twittercommunity.com/t/action-required-sign-in-with-twitter-users-must-whitelist-callback-urls/105342

vverma508 avatar Oct 04 '18 09:10 vverma508

This is documented in the README - see step 6. You need to whitelist your callback URLs on the developer dashboard. If you've made sure that your URLs are indeed whitelisted then the subscription calls should work. I'm not able to reproduce this error myself.

andypiper avatar Oct 05 '18 14:10 andypiper

I have same error with this, although I have whitelisted callback URLs as follows.

https://my-own-dashboard.herokuapp.com/callbacks/addsub
https://my-own-dashboard.herokuapp.com/callbacks/removesub

I wonder if I have written wrong URLs or something. (Other functionalities include command line example scripts work well.)

jk-park avatar Oct 12 '18 07:10 jk-park

I've also been running into this issue, any solution?

ArchieJG avatar Nov 01 '18 10:11 ArchieJG

newer

This is my app config, the callback urls have been whitelisted but I get the same error as @vverma508 when trying to add a subscription

ArchieJG avatar Nov 01 '18 10:11 ArchieJG

While #6 is considered, you can fix it by adding your full domain url to the callback for subscriptions add/remove.

Edit app.js near line 99 and change to something like this:

callbackURL: 'https://your.app.domain/callbacks/addsub`

Same for removesub.

guumaster avatar Nov 01 '18 11:11 guumaster

So I edited the app.js to use the full domain and it sort of worked, it took me to the sign in page on twitter to authorise the application but then redirected to an error page that said "Client application is not permitted to access this user's webhook subscriptions" I've pasted the logs below from the redirect (I replaced sensitive info with ***)

{ StatusCodeError: 401 - "{\"errors\":[{\"code\":348,\"message\":\"Client application is not permitted to access this user's webhook subscriptions.\"}]}"
    at new StatusCodeError (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/errors.js:32:15)
    at Request.plumbing.callback (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/plumbing.js:104:33)
    at Request.RP$callback [as _callback] (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at Request.self.callback (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1094:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
  name: 'StatusCodeError',
  statusCode: 401,
  message:
   '401 - "{\\"errors\\":[{\\"code\\":348,\\"message\\":\\"Client application is not permitted to access this user\'s webhook subscriptions.\\"}]}"',
  error:
   '{"errors":[{"code":348,"message":"Client application is not permitted to access this user\'s webhook subscriptions."}]}',
  options:
   { url:
      'https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json',
     oauth:
      { consumer_key: '***********************',
        consumer_secret: '**************************************',
        token: '*************************************',
        token_secret: '***************************************' },
     resolveWithFullResponse: true,
     method: 'POST',
     callback: [Function: RP$callback],
     transform: undefined,
     simple: true,
     transform2xxOnly: false },
  response:
   IncomingMessage {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: false,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: true,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     _events:
      { end: [Array],
        close: [Array],
        data: [Function],
        error: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers:
      { 'cache-control':
         'no-cache, no-store, must-revalidate, pre-check=0, post-check=0',
        connection: 'close',
        'content-disposition': 'attachment; filename=json.json',
        'content-length': '118',
        'content-type': 'application/json; charset=utf-8',
        date: 'Thu, 01 Nov 2018 11:37:03 GMT',
        expires: 'Tue, 31 Mar 1981 05:00:00 GMT',
        'last-modified': 'Thu, 01 Nov 2018 11:37:03 GMT',
        pragma: 'no-cache',
        server: 'tsa_f',
        'set-cookie': [Array],
        'strict-transport-security': 'max-age=631138519',
        'x-connection-hash': 'e8f5181b4855f4a7504120edf7256264',
        'x-content-type-options': 'nosniff',
        'x-frame-options': 'SAMEORIGIN',
        'x-response-time': '131',
        'x-xss-protection': '1; mode=block; report=https://twitter.com/i/xss_report' },
     rawHeaders:
      [ 'cache-control',
        'no-cache, no-store, must-revalidate, pre-check=0, post-check=0',
        'connection',
        'close',
        'content-disposition',
        'attachment; filename=json.json',
        'content-length',
        '118',
        'content-type',
        'application/json; charset=utf-8',
        'date',
        'Thu, 01 Nov 2018 11:37:03 GMT',
        'expires',
        'Tue, 31 Mar 1981 05:00:00 GMT',
        'last-modified',
        'Thu, 01 Nov 2018 11:37:03 GMT',
        'pragma',
        'no-cache',
        'server',
        'tsa_f',
        'set-cookie',
        'personalization_id="v1_nIE2pGKHytAaPWHYTbxVWA=="; Expires=Sat, 31 Oct 2020 11:37:03 GMT; Path=/; Domain=.twitter.com',
        'set-cookie',
        'guest_id=v1%3A154107222313615891; Expires=Sat, 31 Oct 2020 11:37:03 GMT; Path=/; Domain=.twitter.com',
        'strict-transport-security',
        'max-age=631138519',
        'x-connection-hash',
        'e8f5181b4855f4a7504120edf7256264',
        'x-content-type-options',
        'nosniff',
        'x-frame-options',
        'SAMEORIGIN',
        'x-response-time',
        '131',
        'x-xss-protection',
        '1; mode=block; report=https://twitter.com/i/xss_report' ],
     trailers: {},
     rawTrailers: [],
     aborted: false,
     upgrade: false,
     url: '',
     method: null,
     statusCode: 401,
     statusMessage: 'Authorization Required',
     client:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     _consuming: true,
     _dumped: false,
     req:
      ClientRequest {
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: true,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [TLSSocket],
        connection: [TLSSocket],
        _header:
         'POST /1.1/account_activity/all/dev/subscriptions.json HTTP/1.1\r\nhost: api.twitter.com\r\nAuthorization: OAuth oauth_consumer_key="********************",oauth_nonce="*************************",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1541072223",oauth_token="*****************************",oauth_version="1.0",oauth_signature="Ef1lwfGVZ7dUYkDrsZWsjrj%2FtKc%3D"\r\ncontent-length: 0\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'POST',
        path: '/1.1/account_activity/all/dev/subscriptions.json',
        _ended: true,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     request:
      Request {
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        resolveWithFullResponse: true,
        method: 'POST',
        readable: true,
        writable: true,
        explicitMethod: true,
        _qs: [Querystring],
        _auth: [Auth],
        _oauth: [OAuth],
        _multipart: [Multipart],
        _redirect: [Redirect],
        _tunnel: [Tunnel],
        _rp_resolve: [Function],
        _rp_reject: [Function],
        _rp_promise: [Promise],
        _rp_callbackOrig: undefined,
        callback: [Function],
        _rp_options: [Object],
        headers: [Object],
        setHeader: [Function],
        hasHeader: [Function],
        getHeader: [Function],
        removeHeader: [Function],
        localAddress: undefined,
        pool: {},
        dests: [],
        __isRequestRequest: true,
        _callback: [Function: RP$callback],
        uri: [Url],
        proxy: null,
        tunnel: true,
        setHost: true,
        originalCookieHeader: undefined,
        _disableCookies: true,
        _jar: undefined,
        port: 443,
        host: 'api.twitter.com',
        path: '/1.1/account_activity/all/dev/subscriptions.json',
        httpModule: [Object],
        agentClass: [Function],
        agent: [Agent],
        _started: true,
        href:
         'https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json',
        req: [ClientRequest],
        ntick: true,
        response: [Circular],
        originalHost: 'api.twitter.com',
        originalHostHeaderName: 'host',
        responseContent: [Circular],
        _destdata: true,
        _ended: true,
        _callbackCalled: true },
     toJSON: [Function: responseToJSON],
     caseless: Caseless { dict: [Object] },
     body:
      '{"errors":[{"code":348,"message":"Client application is not permitted to access this user\'s webhook subscriptions."}]}' } }

ArchieJG avatar Nov 01 '18 11:11 ArchieJG

While #6 is considered, you can fix it by adding your full domain url to the callback for subscriptions add/remove.

Edit app.js near line 99 and change to something like this:

callbackURL: 'https://your.app.domain/callbacks/addsub`

Same for removesub.

This works well for both add and remove. Thanks.

jk-park avatar Nov 02 '18 05:11 jk-park

So I edited the app.js to use the full domain and it sort of worked, it took me to the sign in page on twitter to authorise the application but then redirected to an error page that said "Client application is not permitted to access this user's webhook subscriptions" I've pasted the logs below from the redirect (I replaced sensitive info with ***)

{ StatusCodeError: 401 - "{\"errors\":[{\"code\":348,\"message\":\"Client application is not permitted to access this user's webhook subscriptions.\"}]}"
    at new StatusCodeError (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/errors.js:32:15)
    at Request.plumbing.callback (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/plumbing.js:104:33)
    at Request.RP$callback [as _callback] (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at Request.self.callback (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1094:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
  name: 'StatusCodeError',
  statusCode: 401,
  message:
   '401 - "{\\"errors\\":[{\\"code\\":348,\\"message\\":\\"Client application is not permitted to access this user\'s webhook subscriptions.\\"}]}"',
  error:
   '{"errors":[{"code":348,"message":"Client application is not permitted to access this user\'s webhook subscriptions."}]}',
  options:
   { url:
      'https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json',
     oauth:
      { consumer_key: '***********************',
        consumer_secret: '**************************************',
        token: '*************************************',
        token_secret: '***************************************' },
     resolveWithFullResponse: true,
     method: 'POST',
     callback: [Function: RP$callback],
     transform: undefined,
     simple: true,
     transform2xxOnly: false },
  response:
   IncomingMessage {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: false,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: true,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     _events:
      { end: [Array],
        close: [Array],
        data: [Function],
        error: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers:
      { 'cache-control':
         'no-cache, no-store, must-revalidate, pre-check=0, post-check=0',
        connection: 'close',
        'content-disposition': 'attachment; filename=json.json',
        'content-length': '118',
        'content-type': 'application/json; charset=utf-8',
        date: 'Thu, 01 Nov 2018 11:37:03 GMT',
        expires: 'Tue, 31 Mar 1981 05:00:00 GMT',
        'last-modified': 'Thu, 01 Nov 2018 11:37:03 GMT',
        pragma: 'no-cache',
        server: 'tsa_f',
        'set-cookie': [Array],
        'strict-transport-security': 'max-age=631138519',
        'x-connection-hash': 'e8f5181b4855f4a7504120edf7256264',
        'x-content-type-options': 'nosniff',
        'x-frame-options': 'SAMEORIGIN',
        'x-response-time': '131',
        'x-xss-protection': '1; mode=block; report=https://twitter.com/i/xss_report' },
     rawHeaders:
      [ 'cache-control',
        'no-cache, no-store, must-revalidate, pre-check=0, post-check=0',
        'connection',
        'close',
        'content-disposition',
        'attachment; filename=json.json',
        'content-length',
        '118',
        'content-type',
        'application/json; charset=utf-8',
        'date',
        'Thu, 01 Nov 2018 11:37:03 GMT',
        'expires',
        'Tue, 31 Mar 1981 05:00:00 GMT',
        'last-modified',
        'Thu, 01 Nov 2018 11:37:03 GMT',
        'pragma',
        'no-cache',
        'server',
        'tsa_f',
        'set-cookie',
        'personalization_id="v1_nIE2pGKHytAaPWHYTbxVWA=="; Expires=Sat, 31 Oct 2020 11:37:03 GMT; Path=/; Domain=.twitter.com',
        'set-cookie',
        'guest_id=v1%3A154107222313615891; Expires=Sat, 31 Oct 2020 11:37:03 GMT; Path=/; Domain=.twitter.com',
        'strict-transport-security',
        'max-age=631138519',
        'x-connection-hash',
        'e8f5181b4855f4a7504120edf7256264',
        'x-content-type-options',
        'nosniff',
        'x-frame-options',
        'SAMEORIGIN',
        'x-response-time',
        '131',
        'x-xss-protection',
        '1; mode=block; report=https://twitter.com/i/xss_report' ],
     trailers: {},
     rawTrailers: [],
     aborted: false,
     upgrade: false,
     url: '',
     method: null,
     statusCode: 401,
     statusMessage: 'Authorization Required',
     client:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     _consuming: true,
     _dumped: false,
     req:
      ClientRequest {
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: true,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [TLSSocket],
        connection: [TLSSocket],
        _header:
         'POST /1.1/account_activity/all/dev/subscriptions.json HTTP/1.1\r\nhost: api.twitter.com\r\nAuthorization: OAuth oauth_consumer_key="********************",oauth_nonce="*************************",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1541072223",oauth_token="*****************************",oauth_version="1.0",oauth_signature="Ef1lwfGVZ7dUYkDrsZWsjrj%2FtKc%3D"\r\ncontent-length: 0\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'POST',
        path: '/1.1/account_activity/all/dev/subscriptions.json',
        _ended: true,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     request:
      Request {
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        resolveWithFullResponse: true,
        method: 'POST',
        readable: true,
        writable: true,
        explicitMethod: true,
        _qs: [Querystring],
        _auth: [Auth],
        _oauth: [OAuth],
        _multipart: [Multipart],
        _redirect: [Redirect],
        _tunnel: [Tunnel],
        _rp_resolve: [Function],
        _rp_reject: [Function],
        _rp_promise: [Promise],
        _rp_callbackOrig: undefined,
        callback: [Function],
        _rp_options: [Object],
        headers: [Object],
        setHeader: [Function],
        hasHeader: [Function],
        getHeader: [Function],
        removeHeader: [Function],
        localAddress: undefined,
        pool: {},
        dests: [],
        __isRequestRequest: true,
        _callback: [Function: RP$callback],
        uri: [Url],
        proxy: null,
        tunnel: true,
        setHost: true,
        originalCookieHeader: undefined,
        _disableCookies: true,
        _jar: undefined,
        port: 443,
        host: 'api.twitter.com',
        path: '/1.1/account_activity/all/dev/subscriptions.json',
        httpModule: [Object],
        agentClass: [Function],
        agent: [Agent],
        _started: true,
        href:
         'https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json',
        req: [ClientRequest],
        ntick: true,
        response: [Circular],
        originalHost: 'api.twitter.com',
        originalHostHeaderName: 'host',
        responseContent: [Circular],
        _destdata: true,
        _ended: true,
        _callbackCalled: true },
     toJSON: [Function: responseToJSON],
     caseless: Caseless { dict: [Object] },
     body:
      '{"errors":[{"code":348,"message":"Client application is not permitted to access this user\'s webhook subscriptions."}]}' } }

I am facing the same problem. error code 348 pops up right after the twitter app oauth window is redirected back

mainakchhari avatar Jan 11 '19 22:01 mainakchhari

So I edited the app.js to use the full domain and it sort of worked, it took me to the sign in page on twitter to authorise the application but then redirected to an error page that said "Client application is not permitted to access this user's webhook subscriptions" I've pasted the logs below from the redirect (I replaced sensitive info with ***)

{ StatusCodeError: 401 - "{\"errors\":[{\"code\":348,\"message\":\"Client application is not permitted to access this user's webhook subscriptions.\"}]}"
    at new StatusCodeError (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/errors.js:32:15)
    at Request.plumbing.callback (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/plumbing.js:104:33)
    at Request.RP$callback [as _callback] (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at Request.self.callback (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (/home/squawk/Documents/Elixir/Phoenix/account-activity-dashboard/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1094:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
  name: 'StatusCodeError',
  statusCode: 401,
  message:
   '401 - "{\\"errors\\":[{\\"code\\":348,\\"message\\":\\"Client application is not permitted to access this user\'s webhook subscriptions.\\"}]}"',
  error:
   '{"errors":[{"code":348,"message":"Client application is not permitted to access this user\'s webhook subscriptions."}]}',
  options:
   { url:
      'https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json',
     oauth:
      { consumer_key: '***********************',
        consumer_secret: '**************************************',
        token: '*************************************',
        token_secret: '***************************************' },
     resolveWithFullResponse: true,
     method: 'POST',
     callback: [Function: RP$callback],
     transform: undefined,
     simple: true,
     transform2xxOnly: false },
  response:
   IncomingMessage {
     _readableState:
      ReadableState {
        objectMode: false,
        highWaterMark: 16384,
        buffer: BufferList { head: null, tail: null, length: 0 },
        length: 0,
        pipes: null,
        pipesCount: 0,
        flowing: true,
        ended: true,
        endEmitted: true,
        reading: false,
        sync: false,
        needReadable: false,
        emittedReadable: false,
        readableListening: false,
        resumeScheduled: false,
        emitClose: true,
        destroyed: false,
        defaultEncoding: 'utf8',
        awaitDrain: 0,
        readingMore: false,
        decoder: null,
        encoding: null },
     readable: false,
     _events:
      { end: [Array],
        close: [Array],
        data: [Function],
        error: [Function] },
     _eventsCount: 4,
     _maxListeners: undefined,
     socket:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     connection:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     httpVersionMajor: 1,
     httpVersionMinor: 1,
     httpVersion: '1.1',
     complete: true,
     headers:
      { 'cache-control':
         'no-cache, no-store, must-revalidate, pre-check=0, post-check=0',
        connection: 'close',
        'content-disposition': 'attachment; filename=json.json',
        'content-length': '118',
        'content-type': 'application/json; charset=utf-8',
        date: 'Thu, 01 Nov 2018 11:37:03 GMT',
        expires: 'Tue, 31 Mar 1981 05:00:00 GMT',
        'last-modified': 'Thu, 01 Nov 2018 11:37:03 GMT',
        pragma: 'no-cache',
        server: 'tsa_f',
        'set-cookie': [Array],
        'strict-transport-security': 'max-age=631138519',
        'x-connection-hash': 'e8f5181b4855f4a7504120edf7256264',
        'x-content-type-options': 'nosniff',
        'x-frame-options': 'SAMEORIGIN',
        'x-response-time': '131',
        'x-xss-protection': '1; mode=block; report=https://twitter.com/i/xss_report' },
     rawHeaders:
      [ 'cache-control',
        'no-cache, no-store, must-revalidate, pre-check=0, post-check=0',
        'connection',
        'close',
        'content-disposition',
        'attachment; filename=json.json',
        'content-length',
        '118',
        'content-type',
        'application/json; charset=utf-8',
        'date',
        'Thu, 01 Nov 2018 11:37:03 GMT',
        'expires',
        'Tue, 31 Mar 1981 05:00:00 GMT',
        'last-modified',
        'Thu, 01 Nov 2018 11:37:03 GMT',
        'pragma',
        'no-cache',
        'server',
        'tsa_f',
        'set-cookie',
        'personalization_id="v1_nIE2pGKHytAaPWHYTbxVWA=="; Expires=Sat, 31 Oct 2020 11:37:03 GMT; Path=/; Domain=.twitter.com',
        'set-cookie',
        'guest_id=v1%3A154107222313615891; Expires=Sat, 31 Oct 2020 11:37:03 GMT; Path=/; Domain=.twitter.com',
        'strict-transport-security',
        'max-age=631138519',
        'x-connection-hash',
        'e8f5181b4855f4a7504120edf7256264',
        'x-content-type-options',
        'nosniff',
        'x-frame-options',
        'SAMEORIGIN',
        'x-response-time',
        '131',
        'x-xss-protection',
        '1; mode=block; report=https://twitter.com/i/xss_report' ],
     trailers: {},
     rawTrailers: [],
     aborted: false,
     upgrade: false,
     url: '',
     method: null,
     statusCode: 401,
     statusMessage: 'Authorization Required',
     client:
      TLSSocket {
        _tlsOptions: [Object],
        _secureEstablished: true,
        _securePending: false,
        _newSessionPending: false,
        _controlReleased: true,
        _SNICallback: null,
        servername: 'api.twitter.com',
        alpnProtocol: false,
        authorized: true,
        authorizationError: null,
        encrypted: true,
        _events: [Object],
        _eventsCount: 8,
        connecting: false,
        _hadError: false,
        _handle: null,
        _parent: null,
        _host: 'api.twitter.com',
        _readableState: [ReadableState],
        readable: false,
        _maxListeners: undefined,
        _writableState: [WritableState],
        writable: false,
        allowHalfOpen: false,
        _sockname: null,
        _pendingData: null,
        _pendingEncoding: '',
        server: undefined,
        _server: null,
        ssl: null,
        _requestCert: true,
        _rejectUnauthorized: true,
        parser: null,
        _httpMessage: [ClientRequest],
        write: [Function: writeAfterFIN],
        [Symbol(res)]: [TLSWrap],
        [Symbol(asyncId)]: 824,
        [Symbol(lastWriteQueueSize)]: 0,
        [Symbol(timeout)]: null,
        [Symbol(kBytesRead)]: 1033,
        [Symbol(kBytesWritten)]: 443,
        [Symbol(connect-options)]: [Object] },
     _consuming: true,
     _dumped: false,
     req:
      ClientRequest {
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        output: [],
        outputEncodings: [],
        outputCallbacks: [],
        outputSize: 0,
        writable: true,
        _last: true,
        chunkedEncoding: false,
        shouldKeepAlive: false,
        useChunkedEncodingByDefault: true,
        sendDate: false,
        _removedConnection: false,
        _removedContLen: false,
        _removedTE: false,
        _contentLength: 0,
        _hasBody: true,
        _trailer: '',
        finished: true,
        _headerSent: true,
        socket: [TLSSocket],
        connection: [TLSSocket],
        _header:
         'POST /1.1/account_activity/all/dev/subscriptions.json HTTP/1.1\r\nhost: api.twitter.com\r\nAuthorization: OAuth oauth_consumer_key="********************",oauth_nonce="*************************",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1541072223",oauth_token="*****************************",oauth_version="1.0",oauth_signature="Ef1lwfGVZ7dUYkDrsZWsjrj%2FtKc%3D"\r\ncontent-length: 0\r\nConnection: close\r\n\r\n',
        _onPendingData: [Function: noopPendingOutput],
        agent: [Agent],
        socketPath: undefined,
        timeout: undefined,
        method: 'POST',
        path: '/1.1/account_activity/all/dev/subscriptions.json',
        _ended: true,
        res: [Circular],
        aborted: undefined,
        timeoutCb: null,
        upgradeOrConnect: false,
        parser: null,
        maxHeadersCount: null,
        [Symbol(isCorked)]: false,
        [Symbol(outHeadersKey)]: [Object] },
     request:
      Request {
        _events: [Object],
        _eventsCount: 5,
        _maxListeners: undefined,
        resolveWithFullResponse: true,
        method: 'POST',
        readable: true,
        writable: true,
        explicitMethod: true,
        _qs: [Querystring],
        _auth: [Auth],
        _oauth: [OAuth],
        _multipart: [Multipart],
        _redirect: [Redirect],
        _tunnel: [Tunnel],
        _rp_resolve: [Function],
        _rp_reject: [Function],
        _rp_promise: [Promise],
        _rp_callbackOrig: undefined,
        callback: [Function],
        _rp_options: [Object],
        headers: [Object],
        setHeader: [Function],
        hasHeader: [Function],
        getHeader: [Function],
        removeHeader: [Function],
        localAddress: undefined,
        pool: {},
        dests: [],
        __isRequestRequest: true,
        _callback: [Function: RP$callback],
        uri: [Url],
        proxy: null,
        tunnel: true,
        setHost: true,
        originalCookieHeader: undefined,
        _disableCookies: true,
        _jar: undefined,
        port: 443,
        host: 'api.twitter.com',
        path: '/1.1/account_activity/all/dev/subscriptions.json',
        httpModule: [Object],
        agentClass: [Function],
        agent: [Agent],
        _started: true,
        href:
         'https://api.twitter.com/1.1/account_activity/all/dev/subscriptions.json',
        req: [ClientRequest],
        ntick: true,
        response: [Circular],
        originalHost: 'api.twitter.com',
        originalHostHeaderName: 'host',
        responseContent: [Circular],
        _destdata: true,
        _ended: true,
        _callbackCalled: true },
     toJSON: [Function: responseToJSON],
     caseless: Caseless { dict: [Object] },
     body:
      '{"errors":[{"code":348,"message":"Client application is not permitted to access this user\'s webhook subscriptions."}]}' } }

I am facing the same problem. error code 348 pops up right after the twitter app oauth window is redirected back

It was a permissions issue. https://twittercommunity.com/t/getting-error-code-348-while-trying-to-add-subscription/101796 solved it for me. Thanks!

mainakchhari avatar Jan 11 '19 22:01 mainakchhari

The Solution is so easy, Just Follow The Given Steps:

1.Go to Your Code File -> Open app.js file 2.Find And Update this line:

Before:

app.get('/subscriptions/add', passport.authenticate('twitter', {
  callbackURL: '/callbacks/addsub'
}));

/**
 * Starts Twitter sign-in process for removing a user subscription
 **/
app.get('/subscriptions/remove', passport.authenticate('twitter', {
  callbackURL: '/callbacks/removesub'
}));

After: Just add your ngrok link to the callbackurl like shown below

app.get('/subscriptions/add', passport.authenticate('twitter', {
  callbackURL: 'https://18161ccd3a7f.ngrok.io/callbacks/addsub'
}));
/**
 * Starts Twitter sign-in process for removing a user subscription
 **/
app.get('/subscriptions/remove', passport.authenticate('twitter', {
  callbackURL: 'https://18161ccd3a7f.ngrok.io/callbacks/removesub'
}));

Make Sure You Have Whitelisted Your Callback Urls in Twitter Developer Account

  1. https://d38193955539.ngrok.io/callbacks/addsub
  2. https://d38193955539.ngrok.io/callbacks/removesub
  3. https://18161ccd3a7f.ngrok.io/twitter/webhook

faraz66 avatar Oct 16 '20 09:10 faraz66

or ask to re-open PR #6 that fix this issue properly.

guumaster avatar Oct 16 '20 11:10 guumaster