1 | async = require 'async'
|
2 | GoogleAPIAdminSDK = require "#{__dirname}/google_api_admin_sdk"
|
3 | url = require 'url'
|
4 | quest = require 'quest'
|
5 | MailParser = (require 'mailparser').MailParser
|
6 | http_parser = require 'http-string-parser'
|
7 | _ = require 'underscore'
|
8 | retry = require 'retry'
|
9 |
|
10 | class Batch
|
11 | constructor: (google_opts) ->
|
12 | @queries = []
|
13 | @google_api = new GoogleAPIAdminSDK google_opts
|
14 |
|
15 | go: (queries, cb) ->
|
16 | return cb null, [] if queries.length is 0
|
17 |
|
18 | async.waterfall [
|
19 | (cb_wf) =>
|
20 | @google_api.tokeninfo (err, result) =>
|
21 | if err?
|
22 | @google_api.request_refresh_token cb_wf
|
23 | else
|
24 | cb_wf null, null
|
25 | (dontcare, cb_wf) =>
|
26 | boundary = '===============7330845974216740156=='
|
27 | request_body = _.map(queries, (query) ->
|
28 | pathname = (url.parse query._opts.uri).pathname
|
29 | method = query._opts.method?.toUpperCase() ? "GET"
|
30 | body = "\n--#{boundary}\nContent-Type: application/http\n\n#{method} #{pathname} HTTP/1.1"
|
31 | if (query._opts.json? and query._opts.json isnt true)
|
32 | content_body = JSON.stringify query._opts.json
|
33 | body += "\nContent-Type: application/json"
|
34 | body += "\ncontent-length: #{content_body.length}"
|
35 | body += "\n\n#{content_body}"
|
36 | body
|
37 | ).join('') + "\n--#{boundary}--"
|
38 |
|
39 | options =
|
40 | method: 'post'
|
41 | uri: "https://www.googleapis.com/batch"
|
42 | body: request_body
|
43 | headers:
|
44 | Authorization: "Bearer #{@google_api.options.token.access}"
|
45 | 'content-type': "multipart/mixed; boundary=\"#{boundary}\""
|
46 |
|
47 | operation = retry.operation { maxTimeout: 3 * 60 * 1000, retries: 15 }
|
48 | operation.attempt ->
|
49 | quest options, (err, res, body) ->
|
50 | return null if res.statusCode is 503 and operation.retry(new Error(""))
|
51 | cb_wf err, res, body
|
52 | (res, body, cb_wf) =>
|
53 | unless res.statusCode is 200
|
54 | return cb_wf new Error "Batch API responded with code #{res.statusCode}"
|
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 | mail_parser = new MailParser()
|
61 | mail_parser.end "Content-type: #{res.headers['content-type']}\r\n\r\n#{body}"
|
62 | mail_parser.on 'end', (mail) ->
|
63 | cb_wf null, _(mail.attachments).map (result) ->
|
64 | parsed_response = http_parser.parseResponse result.content.toString()
|
65 | parsed_response.body = JSON.parse parsed_response.body if parsed_response.body
|
66 | parsed_response.statusCode = +parsed_response.statusCode
|
67 | parsed_response
|
68 | ], cb
|
69 |
|
70 | module.exports = Batch
|