twitter-ads
Advanced tools
Comparing version 0.1.1 to 0.1.2
# History | ||
## 0.1.2 | ||
Added support for Twitter TON API. | ||
## 0.1.1 | ||
@@ -4,0 +7,0 @@ Seems stable. |
exports = module.exports = { | ||
API_HOST: 'https://ads-api.twitter.com/', | ||
API_SANDBOX_HOST: 'https://ads-api-sandbox.twitter.com/', | ||
CONFIGURABLE_KEYS: ['api_version', 'sandbox', 'consumer_key', 'consumer_secret', 'access_token', 'access_token_secret'], | ||
TON_API_HOST: 'https://ton.twitter.com/', | ||
CONFIGURABLE_KEYS: ['api_version', 'ton_api_version', 'sandbox', 'consumer_key', 'consumer_secret', 'access_token', 'access_token_secret'], | ||
REQUIRED_KEYS: ['consumer_key', 'consumer_secret', 'access_token', 'access_token_secret'], | ||
REQUIRED_TON_UPLOAD_PARAMS: ['file', 'content_type', 'bucket_name'], | ||
REQUIRED_TON_DOWNLOAD_PARAMS: ['file', 'url'], | ||
STATUS_CODES_TO_ABORT_ON: [400, 401, 403, 404, 406, 410, 422] | ||
}; |
var util = require('util'), | ||
fs = require('fs'), | ||
Sync = require('sync'), | ||
request = require('request'), | ||
moment = require('moment'), | ||
helpers = require('./helpers'), | ||
@@ -12,2 +15,3 @@ constants = require('./constants'); | ||
api_version: '0', | ||
ton_api_version: '1.1', | ||
sandbox: true, | ||
@@ -66,2 +70,133 @@ consumer_key: null, | ||
self._uploadTonChunks = function(fd, chunkSize, url, params, cb) { | ||
Sync(function() { | ||
var fsStats = fs.fstatSync(fd), | ||
chunkNum = 1, | ||
bytesBuffer = new Buffer(chunkSize), | ||
bytesRead = 0, | ||
totalBytesRead = 0, | ||
totalBytes = fsStats.size, | ||
finalLocation = null; | ||
while (totalBytesRead < totalBytes) { | ||
bytesRead = fs.readSync(fd, bytesBuffer, 0, chunkSize, totalBytesRead); | ||
//console.log('Uploading chunk #' + chunkNum + ' (' + totalBytesRead + '-' + ((totalBytesRead + bytesRead) - 1) + '/' + totalBytes + ')'); | ||
var headers = { | ||
'Content-Type': params.content_type, | ||
'Content-Length': bytesRead, | ||
'Content-Range': 'bytes ' + totalBytesRead + '-' + ((totalBytesRead + bytesRead) - 1) + '/' + totalBytes | ||
}; | ||
var requestResult = request.put.sync(null, { | ||
baseUrl: constants.TON_API_HOST, | ||
url: url, | ||
body: bytesBuffer, | ||
headers: headers, | ||
oauth: self._oauthObj | ||
}); | ||
var resp = requestResult, body = {}; | ||
if (Array.isArray(requestResult)) resp = requestResult[0], body = requestResult[1]; | ||
if (resp.statusCode != 308 && resp.statusCode != 201) | ||
throw new Error('Twitter did not accept chunk upload, Should return status code 308 or 201 but instead returned: ' + resp.statusCode); | ||
if (resp.statusCode == 201) finalLocation = constants.TON_API_HOST + resp.headers.location; | ||
totalBytesRead += bytesRead; | ||
chunkNum++; | ||
bytesBuffer = new Buffer(chunkSize); | ||
} | ||
fs.closeSync(fd); | ||
return finalLocation; | ||
}, function(err, result) { | ||
if (err) { | ||
fs.closeSync(fd); | ||
return cb(err); | ||
} | ||
cb(null, result); | ||
}); | ||
}; | ||
self._uploadTonFile = function(params, cb) { | ||
if (!params) throw new Error('TwitterAdsAPI: Parameters must be provided when making TON API call.'); | ||
if (!cb) throw new Error('TwitterAdsAPI: Callback must be provided when making an API call.'); | ||
constants.REQUIRED_TON_UPLOAD_PARAMS.forEach(function(k) { | ||
if (params[k] === undefined) throw new Error(util.format('TwitterAdsAPI: Parameters must include `%s`.', k)); | ||
}); | ||
var defaultExpireTime = moment().utc().add(7, 'days').toDate().toUTCString(); | ||
var fd, fsStats; | ||
try { | ||
fd = fs.openSync(params.file, 'r'); | ||
fsStats = fs.fstatSync(fd); | ||
} catch (e) { | ||
return cb(e); | ||
} | ||
var headers = { | ||
'Content-Length': 0, | ||
'X-TON-Content-Type': params.content_type, | ||
'X-TON-Content-Length': fsStats.size, | ||
'X-TON-Expires': params.expire_time || defaultExpireTime | ||
}; | ||
request.post({ | ||
url: constants.TON_API_HOST + self.config.ton_api_version + '/ton/bucket/' + params.bucket_name + '?resumable=true', | ||
headers: headers, | ||
oauth: self._oauthObj | ||
}, function(err, resp, body) { | ||
if (err) return cb(err); | ||
if (resp.statusCode == 201) { | ||
var urlPathForChunks = resp.headers.location; | ||
var minChunkSize = Number(resp.headers['X-TON-Min-Chunk-Size'.toLowerCase()]); | ||
return self._uploadTonChunks(fd, minChunkSize, urlPathForChunks, params, cb); | ||
} else { | ||
fs.closeSync(fd); | ||
return cb(new Error('TwitterAdsAPI: Twitter TON API returned HTTP status code: ' + resp.statusCode)); | ||
} | ||
}); | ||
}; | ||
self._downloadTonFile = function(params, cb) { | ||
if (!params) throw new Error('TwitterAdsAPI: Parameters must be provided when making TON API call.'); | ||
if (!cb) throw new Error('TwitterAdsAPI: Callback must be provided when making an API call.'); | ||
constants.REQUIRED_TON_DOWNLOAD_PARAMS.forEach(function(k) { | ||
if (params[k] === undefined) throw new Error(util.format('TwitterAdsAPI: Parameters must include `%s`.', k)); | ||
}); | ||
var fd, fsStats; | ||
try { | ||
fd = fs.openSync(params.file, 'w'); | ||
fsStats = fs.fstatSync(fd); | ||
} catch (e) { | ||
return cb(e); | ||
} | ||
request.post({ | ||
url: params.url, | ||
oauth: self._oauthObj | ||
}, function(err, resp, body) { | ||
if (err) return cb(err); | ||
if (resp.statusCode == 200) { | ||
try { | ||
fs.writeSync(fd, body, 0, 'utf-8'); | ||
fs.closeSync(fd); | ||
return body.length; | ||
} catch (e) { | ||
return cb(e); | ||
} | ||
} else { | ||
fs.closeSync(fd); | ||
return cb(new Error('TwitterAdsAPI: Twitter TON API returned HTTP status code: ' + resp.statusCode)); | ||
} | ||
}); | ||
}; | ||
return self; | ||
@@ -94,2 +229,11 @@ } | ||
TwitterAdsAPI.prototype.tonUpload = function(params, cb) { | ||
this._uploadTonFile(params, cb); | ||
}; | ||
TwitterAdsAPI.prototype.tonDownload = function(params, cb) { | ||
this._downloadTonFile(params, cb); | ||
}; | ||
exports = module.exports = TwitterAdsAPI; |
{ | ||
"name": "twitter-ads", | ||
"description": "Twitter Ads API for NodeJS", | ||
"version": "0.1.1", | ||
"version": "0.1.2", | ||
"author": "Talha Asad <talha@fallentech.com>", | ||
@@ -13,3 +13,5 @@ "license": "MIT", | ||
"dependencies": { | ||
"request": "^2.67.0" | ||
"request": "^2.67.0", | ||
"moment": "^2.11.1", | ||
"sync": "^0.2.5" | ||
}, | ||
@@ -24,3 +26,5 @@ "repository": { | ||
"twitter advertising", | ||
"twitter advertising api" | ||
"twitter advertising api", | ||
"twitter ton", | ||
"twitter ton api" | ||
], | ||
@@ -27,0 +31,0 @@ "bugs": { |
@@ -9,3 +9,3 @@ # Twitter Ads API | ||
A simple wrapper for <a href="https://dev.twitter.com/ads/overview">Twitter Ads API</a> in NodeJS. | ||
A simple wrapper for <a href="https://dev.twitter.com/ads/overview">Twitter Ads & TON API</a> in NodeJS. | ||
@@ -62,4 +62,34 @@ ## Installation | ||
## Twitter TON API | ||
```js | ||
T.tonUpload({ | ||
file: './test.txt', | ||
content_type: 'text/plain', | ||
bucket: 'ta_partner' | ||
}, | ||
function(error, location) { | ||
if (error) return console.error(error); | ||
console.log(location); | ||
/* If everything goes okay, | ||
you should get something similar to this: | ||
https://ton.twitter.com/1.1/ton/bucket/ta_partner/2892314386/n3UPAcC02roTP6C | ||
*/ | ||
}); | ||
T.tonDownload({ | ||
file: './test.txt', | ||
url: 'https://ton.twitter.com/1.1/ton/bucket/ta_partner/2892314386/n3UPAcC02roTP6C' | ||
}, | ||
function(error, size) { | ||
if (error) return console.error(error); | ||
console.log(size); | ||
/* If everything goes okay, | ||
you should get something similar to this: | ||
204923 | ||
*/ | ||
}); | ||
``` | ||
## Additional Configurables | ||
* **sandbox (Boolean)** - (Default: true) - Uses sandbox API host. | ||
* **api_version (String)** - (Default: 0) - Ads API version to use. |
Sorry, the diff of this file is not supported yet
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
16738
11
271
93
3
1
+ Addedmoment@^2.11.1
+ Addedsync@^0.2.5
+ Addeddetect-libc@1.0.3(transitive)
+ Addedfibers@5.0.3(transitive)
+ Addedmoment@2.30.1(transitive)
+ Addedsync@0.2.5(transitive)