kintone-lambda
var im = require('imagemagick'); | |
var fs = require('fs'); | |
var https = require('https'); | |
var url = require('url'); | |
var querystring = require('querystring'); | |
var path = require('path'); | |
var async = require('async'); | |
const kintoneHost = '<SUBDOMAIN>.cybozu.com'; | |
const appId = <APP_ID>; | |
const apiToken = '<YOUR_API_KEY>'; | |
var getOptions = function(path, method) { | |
return { | |
hostname: kintoneHost, | |
port: 443, | |
path: path, | |
method: method, | |
secureProtocol: 'TLSv1_method', | |
headers: { | |
'X-Cybozu-API-Token': apiToken | |
} | |
}; | |
}; | |
var postProcessResource = function(resource, fn) { | |
var ret = null; | |
if (resource) { | |
if (fn) { | |
ret = fn(resource); | |
} | |
try { | |
fs.unlinkSync(resource); | |
} catch (err) { | |
// Ignore | |
} | |
} | |
return ret; | |
}; | |
var getRecords = function(callback) { | |
console.log('start getRecords'); | |
var params = { | |
"app": appId, | |
"query": 'processed not in ("processed")' | |
}; | |
var query = querystring.stringify(params); | |
var options = getOptions('/k/v1/records.json?' + query, 'GET'); | |
var req = https.request(options, function(res) { | |
console.log('STATUS: ' + res.statusCode); | |
console.log('HEADERS: ' + JSON.stringify(res.headers)); | |
res.setEncoding('utf8'); | |
res.on('data', function(chunk) { | |
console.log('BODY: ' + chunk); | |
if (res.statusCode === 200) { | |
callback(null, JSON.parse(chunk).records); | |
} | |
}); | |
}); | |
req.on('error', function(e) { | |
console.log('problem with request: ' + e.message); | |
callback(e.message); | |
}); | |
req.end(); | |
}; | |
var putRecord = function(id, fileKey, callback) { | |
console.log('start putRecord'); | |
var params = { | |
"app": appId, | |
"id": id, | |
"record": { | |
pdf: { | |
value: [{ | |
fileKey: fileKey | |
}] | |
}, | |
processed: { | |
value: ['processed'] | |
} | |
} | |
}; | |
var json = JSON.stringify(params); | |
var options = getOptions('/k/v1/record.json', 'PUT'); | |
options.headers['Content-Type'] = 'application/json'; | |
var req = https.request(options, function(res) { | |
console.log('STATUS: ' + res.statusCode); | |
console.log('HEADERS: ' + JSON.stringify(res.headers)); | |
res.setEncoding('utf8'); | |
res.on('data', function(chunk) { | |
console.log('BODY: ' + chunk); | |
if (res.statusCode === 200) { | |
callback(null, JSON.parse(chunk)); | |
} | |
}); | |
}); | |
req.on('error', function(e) { | |
console.log('problem with request: ' + e.message); | |
callback(e.message); | |
}); | |
req.write(json); | |
req.end(); | |
}; | |
var getFile = function(file, callback) { | |
console.log('start getFile'); | |
var options = getOptions('/k/v1/file.json?fileKey=' + file.fileKey, 'GET'); | |
var fileName = '/tmp/' + file.fileKey + path.extname(file.name); | |
postProcessResource(fileName); | |
var req = https.request(options, function(res) { | |
console.log('STATUS: ' + res.statusCode); | |
console.log('HEADERS: ' + JSON.stringify(res.headers)); | |
res.on('data', function(chunk) { | |
if (res.statusCode === 200) { | |
console.log(chunk.length + ' chunked'); | |
fs.appendFileSync(fileName, chunk, 'binary'); | |
} | |
}); | |
res.on('end', function() { | |
if (res.statusCode === 200) { | |
callback(null, fileName); | |
} | |
}); | |
}); | |
req.on('error', function(e) { | |
console.log('problem with request: ' + e.message); | |
callback(e.message); | |
}); | |
req.end(); | |
}; | |
var postFile = function(outputFile, callback) { | |
console.log('start postFile'); | |
var options = getOptions('/k/v1/file.json', 'POST'); | |
var boundary = 'afdasfd77a6s234ak3hs7'; | |
options.headers['Content-Type'] = 'multipart/form-data; boundary="' + boundary + '"'; | |
var req = https.request(options, function(res) { | |
console.log('STATUS: ' + res.statusCode); | |
console.log('HEADERS: ' + JSON.stringify(res.headers)); | |
res.on('data', function(chunk) { | |
console.log('BODY: ' + chunk); | |
if (res.statusCode === 200) { | |
callback(null, JSON.parse(chunk)); | |
} | |
}); | |
}); | |
req.on('error', function(e) { | |
console.log('problem with request: ' + e.message); | |
callback(e.message); | |
}); | |
req.write( | |
'--' + boundary + '\r\n' + 'Content-Type: application/octet-stream\r\n' + 'Content-Disposition: form-data; name="file"; filename="images.pdf"\r\n' + 'Content-Transfer-Encoding: binary\r\n\r\n' | |
); | |
stream = fs.createReadStream(outputFile, { | |
bufferSize: 4 * 1024 | |
}); | |
stream.on('data', function(chunk) { | |
req.write(chunk); | |
}); | |
stream.on('end', function() { | |
req.end('\r\n--' + boundary + '--'); | |
}); | |
}; | |
var convert = function(inputFiles, callback) { | |
var args = []; | |
console.log('start converting'); | |
for (var i = 0; i < inputFiles.length; i++) { | |
if (args.length > 0) { | |
args.push('-adjoin'); | |
} | |
args.push(inputFiles[i]); | |
} | |
var outputFile = '/tmp/' + (new Date()).getTime() + '-images.pdf'; | |
args.push(outputFile); | |
console.log(args); | |
im.convert(args, function(err, output) { | |
if (err) { | |
console.log('Convert operation failed:', err); | |
callback(err); | |
} else { | |
console.log('Convert operation completed successfully'); | |
inputFiles.forEach(function(inputFile) { | |
postProcessResource(inputFile); | |
}); | |
callback(null, outputFile); | |
} | |
}); | |
}; | |
var handleRecord = function(record, callback) { | |
var handlers = []; | |
for (var i = 0; i < record.images.value.length; i++) { | |
var ext = path.extname(record.images.value[i].name).toLowerCase(); | |
if (ext == '.jpg' || ext == '.png' || ext == '.jpeg' || ext == '.gif') { | |
handlers.push(getFile.bind(this, record.images.value[i])); | |
} | |
} | |
if (handlers.length === 0) { | |
callback(null, true); | |
return; | |
} | |
async.series(handlers, function(err, files) { | |
if (err || !files) { | |
callback(err); | |
return; | |
} | |
convert(files, function(err, outputFile) { | |
if (err) { | |
callback(err); | |
return; | |
} | |
postFile(outputFile, function(err, file) { | |
if (err || !file) { | |
callback(err); | |
return; | |
} | |
putRecord(record.$id.value, file.fileKey, function(err, res) { | |
if (err) { | |
callback(err); | |
return; | |
} | |
callback(null, true); | |
}); | |
}); | |
}); | |
}); | |
}; | |
exports.handler = function(event, context) { | |
var operation = event.operation; | |
getRecords(function(err, records) { | |
if (err) { | |
context.fail(err); | |
} else { | |
var recs = records.map(function(r) { | |
return handleRecord.bind(this, r); | |
}); | |
async.waterfall(recs, function(err) { | |
console.log('done'); | |
if (err) { | |
context.fail(err); | |
} else { | |
context.succeed(records.length); | |
} | |
}); | |
} | |
}); | |
return; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment