{"action":"created","comment":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments/75479201","id":75479201,"diff_hunk":"@@ -0,0 +1,919 @@\n+/*!\n+ * Copyright 2016 Google Inc. All Rights Reserved.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ *      http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+/*!\n+ * @module speech\n+ */\n+\n+'use strict';\n+\n+var arrify = require('arrify');\n+var async = require('async');\n+var common = require('@google-cloud/common');\n+var concat = require('concat-stream');\n+var extend = require('extend');\n+var format = require('string-format-obj');\n+var googleProtoFiles = require('google-proto-files');\n+var fs = require('fs');\n+var is = require('is');\n+var nodeutil = require('util');\n+var request = require('request');\n+var through = require('through2');\n+var duplexify = require('duplexify');\n+var PKG = require('../package.json');\n+\n+/**\n+ * @type {module:storage/file}\n+ * @private\n+ */\n+var File = require('@google-cloud/storage').File;\n+\n+/**\n+ * @type {module:common/grpc-service}\n+ * @private\n+ */\n+var GrpcService = common.GrpcService;\n+\n+/**\n+ * @type {module:speech/operation}\n+ * @private\n+ */\n+var Operation = require('./operation.js');\n+\n+/**\n+ * @type {module:common/util}\n+ * @private\n+ */\n+var util = common.util;\n+\n+var ENDPOINTER_EVENT_UNSPECIFIED = 'ENDPOINTER_EVENT_UNSPECIFIED';\n+var START_OF_SPEECH = 'START_OF_SPEECH';\n+var END_OF_SPEECH = 'END_OF_SPEECH';\n+var END_OF_AUDIO = 'END_OF_AUDIO';\n+var END_OF_UTTERANCE = 'END_OF_UTTERANCE';\n+\n+/**\n+ * The [Cloud Speech API](https://cloud.google.com/speech/docs) enables easy\n+ * integration of Google speech recognition technologies into developer\n+ * applications. Send audio and receive a text transcription from the Cloud\n+ * Speech API service.\n+ *\n+ * @constructor\n+ * @alias module:speech\n+ *\n+ * @classdesc\n+ * <p class=\"notice\">\n+ *   **This is a Beta release of the Cloud Speech API.** This feature is not\n+ *   covered by any SLA or deprecation policy and may be subject to backward-\n+ *   incompatible changes.\n+ * </p>\n+ *\n+ * To learn more about the Speech API, see the\n+ * [Getting Started guide](https://cloud.google.com/speech/docs/getting-started).\n+ *\n+ * @resource [Getting Started]{@link https://cloud.google.com/speech/docs/getting-started}\n+ * @resource [Speech Best Practices]{@link https://cloud.google.com/speech/docs/best-practices}\n+ *\n+ * @param {object} options - [Configuration object](#/docs).\n+ *\n+ * @example\n+ * var gcloud = require('google-cloud')({\n+ *   keyFilename: '/path/to/keyfile.json',\n+ *   projectId: 'grape-spaceship-123'\n+ * });\n+ *\n+ * var speech = gcloud.speech();\n+ */\n+function Speech(options) {\n+  if (!(this instanceof Speech)) {\n+    options = util.normalizeArguments(this, options);\n+    return new Speech(options);\n+  }\n+\n+  var config = {\n+    baseUrl: 'speech.googleapis.com',\n+    projectIdRequired: false,\n+    service: 'speech',\n+    protoServices: {\n+      Speech: {\n+        path: googleProtoFiles.speech.v1beta1,\n+        service: 'cloud.speech',\n+        apiVersion: 'v1beta1'\n+      },\n+      Operations: {\n+        path: googleProtoFiles('longrunning', 'operations.proto'),\n+        service: 'longrunning',\n+        apiVersion: undefined\n+      }\n+    },\n+    scopes: [\n+      'https://www.googleapis.com/auth/cloud-platform'\n+    ],\n+    userAgent: PKG.name + '/' + PKG.version\n+  };\n+\n+  GrpcService.call(this, config, options);\n+}\n+\n+nodeutil.inherits(Speech, GrpcService);\n+\n+Speech.endpointerTypes = {\n+  ENDPOINTER_EVENT_UNSPECIFIED: ENDPOINTER_EVENT_UNSPECIFIED,\n+  START_OF_SPEECH: START_OF_SPEECH,\n+  END_OF_SPEECH: END_OF_SPEECH,\n+  END_OF_AUDIO: END_OF_AUDIO,\n+  END_OF_UTTERANCE: END_OF_UTTERANCE\n+};\n+\n+/**\n+ * Perform synchronous speech-recognition: receive results after all audio has\n+ * been sent and processed.\n+ *\n+ * This is an advanced API method that requires a raw\n+ * [`SyncRecognizeRequest`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.SyncRecognizeRequest)\n+ * object. If that doesn't sound like what you're looking for,\n+ * you'll probably appreciate {module:speech#syncDetect}.\n+ *\n+ * @resource [`SyncRecognize` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.Speech.SyncRecognize}\n+ * @resource [`SyncRecognizeRequest` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.SyncRecognizeRequest}\n+ *\n+ * @param {object} syncRecognizeRequest - A `SyncRecognizeRequest` object. See\n+ *     [`SyncRecognizeRequest`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.SyncRecognizeRequest).\n+ * @param {object} syncRecognizeRequest.config - A\n+ *     `RecognitionConfig` object. See [`RecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig).\n+ * @param {string} syncRecognizeRequest.config.encoding - Encoding of audio data\n+ *     sent in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.encoding`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {number} syncRecognizeRequest.config.sampleRate - Sample rate in Hertz\n+ *     of the audio data sent in all RecognitionAudio messages. See\n+ *     [`RecognitionConfig.sampleRate`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {string=} syncRecognizeRequest.config.languageCode - See\n+ *     [`RecognitionConfig.languageCode`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `\"en-US\"`.\n+ * @param {number=} syncRecognizeRequest.config.maxAlternatives - See\n+ *     [`RecognitionConfig.maxAlternatives`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `1`.\n+ * @param {boolean=} syncRecognizeRequest.config.profanityFilter - See\n+ *     [`RecognitionConfig.profanityFilter`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {string[]=} syncRecognizeRequest.config.speechContext - See\n+ *     [`RecognitionConfig.speechContext`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `[]`.\n+ * @param {object} syncRecognizeRequest.audio - A `RecognitionAudio` object.\n+ *     See [`RecognitionAudio`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionAudio).\n+ * @param {buffer} syncRecognizeRequest.audio.content - The audio data bytes\n+ *     encoded as specified in `RecognitionConfig`.\n+ * @param {string} syncRecognizeRequest.audio.uri - URI that points to a file\n+ *     that contains audio data bytes as specified in `RecognitionConfig`.\n+ *     Currently, only Google Cloud Storage URIs are supported, which must be\n+ *     specified in the following format: `gs://bucket_name/object_name`.\n+ * @param {function} callback - The callback function.\n+ * @param {?error} callback.err - An error returned while making this request.\n+ * @param {object[]} callback.results - Array of speech recognition results. See\n+ *     [`SpeechRecognitionResult`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.SpeechRecognitionResult).\n+ * @param {object} callback.apiResponse - Raw API response. See\n+ *     [`SyncRecognizeResponse`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#syncrecognizeresponse).\n+ *\n+ * @example\n+ * //-\n+ * // <h3>Send raw audio</h3>\n+ * //-\n+ * var fs = require('fs');\n+ *\n+ * fs.readFile('./system-test/data/bridge.raw', function (err, rawAudio) {\n+ *   // See the link in the parameters for `SyncRecognizeRequest`.\n+ *   var syncRecognizeRequest = {\n+ *     config: {\n+ *       encoding: 'LINEAR16',\n+ *       sampleRate: 16000\n+ *     },\n+ *     audio: {\n+ *       content: rawAudio\n+ *     }\n+ *   };\n+ *\n+ *   speech.recognize(\n+ *     syncRecognizeRequest,\n+ *     function(err, results, apiResponse) {\n+ *       console.log(results);\n+ *       console.log(results === apiResponse.results); // true\n+ *     }\n+ *   );\n+ * });\n+ *\n+ * //-\n+ * // <h3>Specify URI to audio file</h3>\n+ * //-\n+ * // See the link in the parameters for `SyncRecognizeRequest`.\n+ * var syncRecognizeRequest = {\n+ *   config: {\n+ *     encoding: 'LINEAR16',\n+ *     sampleRate: 16000\n+ *   },\n+ *   audio: {\n+ *     uri: 'gs://your-bucket-name/bridge.raw'\n+ *   }\n+ * };\n+ *\n+ * speech.recognize(\n+ *   syncRecognizeRequest,\n+ *   function(err, results, apiResponse) {\n+ *     console.log(results);\n+ *     console.log(results === apiResponse.results); // true\n+ *   }\n+ * );\n+ */\n+Speech.prototype.recognize = function(reqOpts, callback) {\n+  var self = this;\n+  var protoOpts = {\n+    service: 'Speech',\n+    method: 'syncRecognize'\n+  };\n+\n+  this.request(protoOpts, reqOpts, function(err, apiResponse) {\n+    if (err) {\n+      callback(err, null, apiResponse);\n+      return;\n+    }\n+    var response = new self.protos.Speech.SyncRecognizeResponse(apiResponse);\n+    callback(null, response, apiResponse);\n+  });\n+};\n+\n+/**\n+ * Detect speech from an audio file.\n+ *\n+ * <h4>API simplifications</h4>\n+ *\n+ * This method returns a simplified response. For the response in the original\n+ * format, review the `apiResponse` argument your callback receives.\n+ *\n+ * @param {string|module:storage/file} file - The source file to run the\n+ *     detection on. It can be either a local file path, a remote file URL, a\n+ *     Cloud Storage URI, or a gcloud File object.\n+ * @param {object} recognitionConfig - A\n+ *     `RecognitionConfig` object. See [`RecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig).\n+ * @param {string} recognitionConfig.encoding - Encoding of audio data\n+ *     sent in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.encoding`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {number} recognitionConfig.sampleRate - Sample rate in Hertz\n+ *     of the audio data sent in all RecognitionAudio messages. See\n+ *     [`RecognitionConfig.sampleRate`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {string=} recognitionConfig.languageCode - See\n+ *     [`RecognitionConfig.languageCode`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `\"en-US\"`.\n+ * @param {number=} recognitionConfig.maxAlternatives - See\n+ *     [`RecognitionConfig.maxAlternatives`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `1`.\n+ * @param {boolean=} recognitionConfig.profanityFilter - See\n+ *     [`RecognitionConfig.profanityFilter`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {string[]=} recognitionConfig.speechContext - See\n+ *     [`RecognitionConfig.speechContext`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `[]`.\n+ * @param {function} callback - The callback function.\n+ * @param {?error} callback.err - An error returned while making this request.\n+ * @param {object[]} callback.syncRecognizeResponse -\n+ *     `SyncRecognizeResponse` objects. See\n+ *     [`SyncRecognizeResponse`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#syncrecognizeresponse).\n+ * @param {object} callback.apiResponse - Raw API response. See\n+ *     [`SyncRecognizeResponse`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#syncrecognizeresponse).\n+ *\n+ * @example\n+ * //-\n+ * // <h3>Run speech detection over a local file</h3>\n+ * //-\n+ * speech.detect('./bridge.raw', {\n+ *   encoding: 'LINEAR16',\n+ *   sampleRate: 16000\n+ * }, function(err, result, apiResponse) {\n+ *   //   result = {\n+ *   //     results: [\n+ *   //       {\n+ *   //         alternatives: [\n+ *   //           {\n+ *   //             transcript: \"...\",\n+ *   //             confidence: 0.88\n+ *   //           }\n+ *   //         ]\n+ *   //       }\n+ *   //     ]\n+ *   //   }\n+ * });\n+ *\n+ * //-\n+ * // <h3>Run speech detection over a remote file</h3>\n+ * //\n+ * // *Note: This is not an officially supported feature of the Speech API. Our\n+ * // library will make a request to the URL given, and send that upstream.*\n+ * //-\n+ * var file = 'https://your-domain.com/files/bridge.raw';\n+ * speech.detect(file, {\n+ *   encoding: 'LINEAR16',\n+ *   sampleRate: 16000\n+ * }, function(err, result, apiResponse) {});\n+ *\n+ * //-\n+ * // <h3>Run speech detection over a file in Cloud Storage</h3>\n+ * //-\n+ * var file = 'gs://your-bucket-name/bridge.raw';\n+ * speech.detect(file, {\n+ *   encoding: 'LINEAR16',\n+ *   sampleRate: 16000\n+ * }, function(err, result, apiResponse) {});\n+ */\n+Speech.prototype.detect = function(file, config, callback) {\n+  var self = this;\n+\n+  Speech.findFiles_(file, function(err, files) {\n+    if (err) {\n+      callback(err);\n+      return;\n+    }\n+\n+    var reqOpts = {\n+      config: extend({\n+        encoding: Speech.detectEncoding_(file)\n+      }, config),\n+      audio: files[0]\n+    };\n+\n+    self.recognize(reqOpts, callback);\n+  });\n+};\n+\n+/**\n+ * Perform asynchronous speech-recognition: receive results via the\n+ * `google.longrunning.Operations` interface.\n+\n+ * This method sends audio to the Speech API, which immediately responds with a\n+ * job ID. You can then poll the job for a result. This is useful if your app\n+ * doesn't need to wait for the result of the analysis.\n+ *\n+ * This is an advanced API method that requires a raw\n+ * [`AsyncRecognizeRequest`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.AsyncRecognizeRequest)\n+ * object. If that doesn't sound like what you're looking for,\n+ * you'll probably appreciate {module:speech#createDetectJob}.\n+ *\n+ * @resource [`AsyncRecognize` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.Speech.AsyncRecognize}\n+ * @resource [`AsyncRecognizeRequest` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.AsyncRecognizeRequest}\n+ *\n+ * @param {object} asyncRecognizeRequest - A `AsyncRecognizeRequest` object. See\n+ *     [`AsyncRecognizeRequest`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.AsyncRecognizeRequest).\n+ * @param {object} asyncRecognizeRequest.config - A\n+ *     `RecognitionConfig` object. See [`RecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig).\n+ * @param {string} asyncRecognizeRequest.config.encoding - Encoding of audio\n+ *     data sent in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.encoding`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {number} asyncRecognizeRequest.config.sampleRate - Sample rate in\n+ *     Hertz of the audio data sent in all RecognitionAudio messages. See\n+ *     [`RecognitionConfig.sampleRate`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {string=} asyncRecognizeRequest.config.languageCode - See\n+ *     [`RecognitionConfig.languageCode`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `\"en-US\"`.\n+ * @param {number=} asyncRecognizeRequest.config.maxAlternatives - See\n+ *     [`RecognitionConfig.maxAlternatives`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `1`.\n+ * @param {boolean=} asyncRecognizeRequest.config.profanityFilter - See\n+ *     [`RecognitionConfig.profanityFilter`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {string[]=} asyncRecognizeRequest.config.speechContext - See\n+ *     [`RecognitionConfig.speechContext`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `[]`.\n+ * @param {object} asyncRecognizeRequest.audio - A `RecognitionAudio` object.\n+ *     See [`RecognitionAudio`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionAudio).\n+ * @param {buffer} asyncRecognizeRequest.audio.content - The audio data bytes\n+ *     encoded as specified in `RecognitionConfig`.\n+ * @param {string} asyncRecognizeRequest.audio.uri - URI that points to a file\n+ *     that contains audio data bytes as specified in `RecognitionConfig`.\n+ *     Currently, only Google Cloud Storage URIs are supported, which must be\n+ *     specified in the following format: `gs://bucket_name/object_name`.\n+ * @param {function} callback - The callback function.\n+ * @param {?error} callback.err - An error returned while making this request.\n+ * @param {module:speech/operation} callback.operation - `Operation` object. See\n+ *     [`Operation`](https://cloud.google.com/speech/reference/rpc/google.longrunning#google.longrunning.Operation).\n+ * @param {object} callback.apiResponse - Raw API response.\n+ *\n+ * @example\n+ * //-\n+ * // <h3>Send raw audio</h3>\n+ * //-\n+ * var fs = require('fs');\n+ *\n+ * fs.readFile('./system-test/data/bridge.raw', function (err, rawAudio) {\n+ *   // See the link in the parameters for `AsyncRecognizeRequest`.\n+ *   var asyncRecognizeRequest = {\n+ *     config: {\n+ *       encoding: 'LINEAR16',\n+ *       sampleRate: 16000\n+ *     },\n+ *     audio: {\n+ *       content: rawAudio\n+ *     }\n+ *   };\n+ *\n+ *   speech.createRecognizeJob(\n+ *     asyncRecognizeRequest,\n+ *     function(err, operation, apiResponse) {\n+ *       console.log(operation);\n+ *     }\n+ *   );\n+ * });\n+ *\n+ * //-\n+ * // <h3>Specify URI to audio file</h3>\n+ * //-\n+ * // See the link in the parameters for `AsyncRecognizeRequest`.\n+ * var asyncRecognizeRequest = {\n+ *   config: {\n+ *     encoding: 'LINEAR16',\n+ *     sampleRate: 16000\n+ *   },\n+ *   audio: {\n+ *     uri: 'gs://your-bucket-name/bridge.raw'\n+ *   }\n+ * };\n+ *\n+ * speech.createRecognizeJob(\n+ *   asyncRecognizeRequest,\n+ *   function(err, operation, apiResponse) {\n+ *     console.log(operation);\n+ *   }\n+ * );\n+ */\n+Speech.prototype.createRecognizeJob = function(reqOpts, callback) {\n+  var self = this;\n+  var protoOpts = {\n+    service: 'Speech',\n+    method: 'asyncRecognize'\n+  };\n+\n+  this.request(protoOpts, reqOpts, function(err, apiResponse) {\n+    if (err) {\n+      callback(err, null, apiResponse);\n+      return;\n+    }\n+    callback(null, self.operation(apiResponse), apiResponse);\n+  });\n+};\n+\n+/**\n+ * Asynchronously detect speech from an audio file.\n+ *\n+ * This method sends audio to the Speech API, which immediately responds with a\n+ * job ID. You can then poll the job for a result. This is useful if your app\n+ * doesn't need to wait for the result of the analysis.\n+ *\n+ * @param {string|module:storage/file} file - The source file to run the\n+ *     detection on. It can be either a local file path, a remote file URL, a\n+ *     Cloud Storage URI, or a gcloud File object.\n+ * @param {object} recognitionConfig - A\n+ *     `RecognitionConfig` object. See [`RecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig).\n+ * @param {string} recognitionConfig.encoding - Encoding of audio data\n+ *     sent in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.encoding`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {number} recognitionConfig.sampleRate - Sample rate in Hertz\n+ *     of the audio data sent in all RecognitionAudio messages. See\n+ *     [`RecognitionConfig.sampleRate`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {string=} recognitionConfig.languageCode - See\n+ *     [`RecognitionConfig.languageCode`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `\"en-US\"`.\n+ * @param {number=} recognitionConfig.maxAlternatives - See\n+ *     [`RecognitionConfig.maxAlternatives`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `1`.\n+ * @param {boolean=} recognitionConfig.profanityFilter - See\n+ *     [`RecognitionConfig.profanityFilter`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {string[]=} recognitionConfig.speechContext - See\n+ *     [`RecognitionConfig.speechContext`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `[]`.\n+ * @param {function} callback - The callback function.\n+ * @param {?error} callback.err - An error returned while making this request.\n+ * @param {module:speech/operation} callback.operation - `Operation` object. See\n+ *     [`Operation`](https://cloud.google.com/speech/reference/rpc/google.longrunning#google.longrunning.Operation).\n+ * @param {object} callback.apiResponse - Raw API response.\n+ *\n+ * @example\n+ * //-\n+ * // <h3>Run speech detection over a local file</h3>\n+ * //-\n+ * speech.createDetectJob('./bridge.raw', {\n+ *   encoding: 'LINEAR16',\n+ *   sampleRate: 16000\n+ * }, function(err, operation, apiResponse) {\n+ *   operation.on('complete', function(err, operation, apiResponse) {\n+ *     // operation = {\n+ *     //   response: {\n+ *     //     results: [\n+ *     //       {\n+ *     //         alternatives: [\n+ *     //           {\n+ *     //             transcript: \"...\",\n+ *     //             confidence: 0.88\n+ *     //           }\n+ *     //         ]\n+ *     //       }\n+ *     //     ]\n+ *     //   }\n+ *     // }\n+ *   });\n+ * });\n+ *\n+ * //-\n+ * // <h3>Run speech detection over a remote file</h3>\n+ * //\n+ * // *Note: This is not an officially supported feature of the Speech API. Our\n+ * // library will make a request to the URL given, and send that upstream.*\n+ * //-\n+ * var file = 'https://your-domain.com/files/bridge.raw';\n+ * speech.createDetectJob(file, {\n+ *   encoding: 'LINEAR16',\n+ *   sampleRate: 16000\n+ * }, function(err, operation, apiResponse) {});\n+ *\n+ * //-\n+ * // <h3>Run speech detection over a file in Cloud Storage</h3>\n+ * //-\n+ * var file = 'gs://your-bucket-name/bridge.raw';\n+ * speech.createDetectJob(file, {\n+ *   encoding: 'LINEAR16',\n+ *   sampleRate: 16000\n+ * }, function(err, operation, apiResponse) {\n+ *   operation.on('complete', function(err, operation, apiResponse) {\n+ *     // operation = {\n+ *     //   response: {\n+ *     //     results: [\n+ *     //       {\n+ *     //         alternatives: [\n+ *     //           {\n+ *     //             transcript: \"...\",\n+ *     //             confidence: 0.88\n+ *     //           }\n+ *     //         ]\n+ *     //       }\n+ *     //     ]\n+ *     //   }\n+ *     // }\n+ *   });\n+ * });\n+ */\n+Speech.prototype.createDetectJob = function(file, config, callback) {\n+  var self = this;\n+\n+  Speech.findFiles_(file, function(err, files) {\n+    if (err) {\n+      callback(err);\n+      return;\n+    }\n+\n+    var reqOpts = {\n+      config: extend({\n+        encoding: Speech.detectEncoding_(file)\n+      }, config),\n+      audio: files[0]\n+    };\n+\n+    self.createRecognizeJob(reqOpts, callback);\n+  });\n+};\n+\n+/**\n+ * Perform bidirectional streaming speech-recognition: receive results while\n+ * sending audio.\n+ *\n+ * This is an advanced API method that requires raw\n+ * [`StreamingRecognizeRequest`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognizeRequest)\n+ * objects. If that doesn't sound like what you're looking for, you'll probably\n+ * appreciate {module:speech#streamingDetect}.\n+ *\n+ * @resource [`StreamingRecognize` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.Speech.StreamingRecognize}\n+ * @resource [`StreamingRecognizeRequest` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognizeRequest}\n+ *\n+ * @param {object} streamingRecognizeRequest - A `StreamingRecognizeRequest`\n+ *     object. See [`StreamingRecognizeRequest`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognizeRequest).\n+ * @param {object} streamingRecognizeRequest.streamingConfig - A\n+ *     `StreamingRecognitionConfig` object. See [`StreamingRecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognitionConfig).\n+ * @param {object} streamingRecognizeRequest.streamingConfig.config - A\n+ *     `RecognitionConfig` object. See [`RecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig).\n+ * @param {string} streamingRecognizeRequest.streamingConfig.config.encoding -\n+ *     Encoding of audio data sent in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.encoding`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {number} streamingRecognizeRequest.streamingConfig.config.sampleRate\n+ *     - Sample rate in Hertz of the audio data sent in all RecognitionAudio\n+ *     messages. See\n+ *     [`RecognitionConfig.sampleRate`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {string=}\n+ *     streamingRecognizeRequest.streamingConfig.config.languageCode\n+ *     - See [`RecognitionConfig.languageCode`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `\"en-US\"`.\n+ * @param {number=}\n+ *     streamingRecognizeRequest.streamingConfig.config.maxAlternatives\n+ *     - See [`RecognitionConfig.maxAlternatives`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `1`.\n+ * @param {boolean=}\n+ *     streamingRecognizeRequest.streamingConfig.config.profanityFilter\n+ *     - See [`RecognitionConfig.profanityFilter`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {string[]=}\n+ *     streamingRecognizeRequest.streamingConfig.config.speechContext\n+ *     - See [`RecognitionConfig.speechContext`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `[]`.\n+ * @param {boolean=} streamingRecognizeRequest.streamingConfig.singleUtterance\n+ *     - See [`StreamingRecognitionConfig.singleUtterance`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {boolean=} streamingRecognizeRequest.streamingConfig.interimResults\n+ *     - See [`StreamingRecognitionConfig.interimResults`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @returns {object} Readable and writable stream.\n+ *\n+ * @example\n+ * var fs = require('fs');\n+ * var through = require('through2');\n+ * var toRecognizeRequest = through.obj(function(chunk, encoding, done) {\n+ *   done(null, {\n+ *     audioContent: chunk\n+ *   });\n+ * });\n+ *\n+ * // See the link in the parameters for `StreamingRecognizeRequest`.\n+ * var streamingRecognizeRequest = {\n+ *   streamingConfig: {\n+ *     config: {\n+ *       encoding: 'LINEAR16',\n+ *       sampleRate: 16000\n+ *     },\n+ *     singleUtterance: false,\n+ *     interimResults: false\n+ *   }\n+ * };\n+ *\n+ * var recognizeStream = speech.createRecognizeStream(streamingRecognizeRequest)\n+ *   .on('data', function (apiResponse) {\n+ *     console.log(apiResponse);\n+ *   });\n+ *\n+ * // See the link for `RecognitionAudio`.\n+ * fs.createReadStream('./system-test/data/bridge.raw')\n+ *   .pipe(toRecognizeRequest)\n+ *   .pipe(recognizeStream);\n+ * fs.createReadStream('./system-test/data/spain.raw')\n+ *   .pipe(toRecognizeRequest)\n+ *   .pipe(recognizeStream);\n+ */\n+Speech.prototype.createRecognizeStream = function(reqOpts) {\n+  var protoOpts = {\n+    service: 'Speech',\n+    method: 'streamingRecognize'\n+  };\n+\n+  var stream = this.requestWritableStream(protoOpts);\n+  stream.write(reqOpts);\n+  return stream;\n+};\n+\n+/**\n+ * Perform bidirectional streaming speech-recognition: receive results while\n+ * sending audio.\n+ *\n+ * <h4>API simplifications</h4>\n+ *\n+ * This method returns a simplified response. For the response in the original\n+ * format, review the `apiResponse` argument your callback receives.\n+ *\n+ * @resource [`StreamingRecognize` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.Speech.StreamingRecognize}\n+ * @resource [`StreamingRecognizeRequest` API Reference]{@link https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognizeRequest}\n+ *\n+ * @param {object} streamingConfig - A `StreamingRecognitionConfig` object. See\n+ *     [`StreamingRecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognitionConfig).\n+ * @param {object} streamingConfig.config - A `RecognitionConfig` object. See\n+ *     [`RecognitionConfig`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig).\n+ * @param {string} streamingConfig.config.encoding - Encoding of audio data sent\n+ *     in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.encoding`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {number} streamingConfig.config.sampleRate - Sample rate in Hertz of\n+ *     the audio data sent in all `RecognitionAudio` messages. See\n+ *     [`RecognitionConfig.sampleRate`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ * @param {string=} streamingConfig.config.languageCode - See\n+ *     [`RecognitionConfig.languageCode`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `\"en-US\"`.\n+ * @param {number=} streamingConfig.config.maxAlternatives - See\n+ *     [`RecognitionConfig.maxAlternatives`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `1`.\n+ * @param {boolean=} streamingConfig.config.profanityFilter - See\n+ *     [`RecognitionConfig.profanityFilter`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {string[]=} streamingConfig.config.speechContext - See\n+ *     [`RecognitionConfig.speechContext`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.RecognitionConfig.FIELDS).\n+ *     Default: `[]`.\n+ * @param {boolean=} streamingConfig.singleUtterance - See\n+ *     [`StreamingRecognitionConfig.singleUtterance`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @param {boolean=} streamingConfig.interimResults - See\n+ *     [`StreamingRecognitionConfig.interimResults`](https://cloud.google.com/speech/reference/rpc/google.cloud.speech.v1beta1#google.cloud.speech.v1beta1.StreamingRecognitionConfig.FIELDS).\n+ *     Default: `false`.\n+ * @returns {object} Readable and writable stream.\n+ *\n+ * @example\n+ * var fs = require('fs');\n+ *\n+ * // See the link in the parameters for `RecognizeRequest`.\n+ * var streamingConfig = {\n+ *   config: {\n+ *     encoding: 'LINEAR16',\n+ *     sampleRate: 16000\n+ *   },\n+ *   singleUtterance: false,\n+ *   interimResults: false\n+ * };\n+ *\n+ * var recognizeStream = speech.createDetectStream(streamingConfig)","path":"packages/speech/src/index.js","position":742,"original_position":742,"commit_id":"3fc3b851b148697e9dd16e5b8974a0c06e96778f","original_commit_id":"3fc3b851b148697e9dd16e5b8974a0c06e96778f","user":{"login":"callmehiphop","id":1707267,"avatar_url":"https://avatars.githubusercontent.com/u/1707267?v=3","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false},"body":"We've received some feedback here that we should add an example on how to pipe in a stream from a users microphone to our api.","created_at":"2016-08-19T13:16:54Z","updated_at":"2016-08-19T13:16:54Z","html_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/1407#discussion_r75479201","pull_request_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407","_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments/75479201"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/1407#discussion_r75479201"},"pull_request":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407"}}},"pull_request":{"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407","id":76055472,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/1407","diff_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/1407.diff","patch_url":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/1407.patch","issue_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/1407","number":1407,"state":"open","locked":false,"title":"speech: initial support","user":{"login":"jmdobry","id":1213510,"avatar_url":"https://avatars.githubusercontent.com/u/1213510?v=3","gravatar_id":"","url":"https://api.github.com/users/jmdobry","html_url":"https://github.com/jmdobry","followers_url":"https://api.github.com/users/jmdobry/followers","following_url":"https://api.github.com/users/jmdobry/following{/other_user}","gists_url":"https://api.github.com/users/jmdobry/gists{/gist_id}","starred_url":"https://api.github.com/users/jmdobry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmdobry/subscriptions","organizations_url":"https://api.github.com/users/jmdobry/orgs","repos_url":"https://api.github.com/users/jmdobry/repos","events_url":"https://api.github.com/users/jmdobry/events{/privacy}","received_events_url":"https://api.github.com/users/jmdobry/received_events","type":"User","site_admin":false},"body":"Closes #1406\r\n\r\nAdd support for the Speech API (v1beta1)!\r\n\r\n[Docs](http://callmehiphop.github.io/gcloud-node/#/docs/speech/master/speech)\r\n\r\n----\r\n\r\n- [x] Implementation\r\n  - [x] Speech service\r\n    - [x] `Speech#recognize` - maps directly to `SyncRecognize` grpc method (no sugar added)\r\n    - [x] `Speech#detect` - easier to use version of `recognize`\r\n    - [x] `Speech#createRecognizeJob` - maps directly to `AsyncRecognize` grpc method (no sugar added)\r\n    - [x] `Speech#createDetectJob` - easier to use version of `createRecognizeJob`\r\n    - [x] `Speech#createRecognizeStream` - maps directly to `StreamingRecognize` grpc method (no sugar added)\r\n    - [x] `Speech#createDetectStream` - easier to use version of `streamingRecognize`\r\n  - [x] Operations service\r\n    - [x] `Operation#get`\r\n- [x] Docs\r\n- [x] Tests\r\n  - [x] e2e Tests\r\n    - [x] Speech service\r\n      - [x] `Speech#recognize`\r\n      - [x] `Speech#detect`\r\n      - [x] `Speech#createRecognizeJob`\r\n      - [x] `Speech#createDetectJob`\r\n      - [x] `Speech#createRecognizeStream`\r\n      - [x] `Speech#createDetectStream`\r\n    - [x] Operations service\r\n      - [x] `Operation#get`\r\n  - [x] Unit Tests\r\n    - [x] Speech service\r\n      - [x] `Speech#recognize`\r\n      - [x] `Speech#detect`\r\n      - [x] `Speech#createRecognizeJob`\r\n      - [x] `Speech#createDetectJob`\r\n      - [x] `Speech#createRecognizeStream`\r\n      - [x] `Speech#createDetectStream`\r\n    - [x] Operations service\r\n      - [x] `Operation#get`\r\n\r\nNew files:\r\n\r\n* lib/speech/index.js\r\n* lib/speech/operation.js\r\n* test/speech/index.js\r\n* test/speech/operation.js\r\n* system-test/speech.js\r\n* system-test/data/bridge.raw\r\n* system-test/data/spain.raw\r\n* system-test/data/quit.raw\r\n\r\nModified:\r\n\r\n* lib/index.js\r\n* lib/common/grpc-service.js\r\n* lib/common/grpc-service-object.js\r\n* docs/toc.json\r\n* README.md\r\n* package.json\r\n* CONTRIBUTORS","created_at":"2016-07-02T04:11:46Z","updated_at":"2016-08-19T13:16:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"e3adacb82485f9b34602a2c10020f444fc6b8375","assignee":{"login":"callmehiphop","id":1707267,"avatar_url":"https://avatars.githubusercontent.com/u/1707267?v=3","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false},"assignees":[{"login":"callmehiphop","id":1707267,"avatar_url":"https://avatars.githubusercontent.com/u/1707267?v=3","gravatar_id":"","url":"https://api.github.com/users/callmehiphop","html_url":"https://github.com/callmehiphop","followers_url":"https://api.github.com/users/callmehiphop/followers","following_url":"https://api.github.com/users/callmehiphop/following{/other_user}","gists_url":"https://api.github.com/users/callmehiphop/gists{/gist_id}","starred_url":"https://api.github.com/users/callmehiphop/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/callmehiphop/subscriptions","organizations_url":"https://api.github.com/users/callmehiphop/orgs","repos_url":"https://api.github.com/users/callmehiphop/repos","events_url":"https://api.github.com/users/callmehiphop/events{/privacy}","received_events_url":"https://api.github.com/users/callmehiphop/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407/commits","review_comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407/comments","review_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments{/number}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/1407/comments","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/statuses/3fc3b851b148697e9dd16e5b8974a0c06e96778f","head":{"label":"jmdobry:speech","ref":"speech","sha":"3fc3b851b148697e9dd16e5b8974a0c06e96778f","user":{"login":"jmdobry","id":1213510,"avatar_url":"https://avatars.githubusercontent.com/u/1213510?v=3","gravatar_id":"","url":"https://api.github.com/users/jmdobry","html_url":"https://github.com/jmdobry","followers_url":"https://api.github.com/users/jmdobry/followers","following_url":"https://api.github.com/users/jmdobry/following{/other_user}","gists_url":"https://api.github.com/users/jmdobry/gists{/gist_id}","starred_url":"https://api.github.com/users/jmdobry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmdobry/subscriptions","organizations_url":"https://api.github.com/users/jmdobry/orgs","repos_url":"https://api.github.com/users/jmdobry/repos","events_url":"https://api.github.com/users/jmdobry/events{/privacy}","received_events_url":"https://api.github.com/users/jmdobry/received_events","type":"User","site_admin":false},"repo":{"id":62340865,"name":"gcloud-node","full_name":"jmdobry/gcloud-node","owner":{"login":"jmdobry","id":1213510,"avatar_url":"https://avatars.githubusercontent.com/u/1213510?v=3","gravatar_id":"","url":"https://api.github.com/users/jmdobry","html_url":"https://github.com/jmdobry","followers_url":"https://api.github.com/users/jmdobry/followers","following_url":"https://api.github.com/users/jmdobry/following{/other_user}","gists_url":"https://api.github.com/users/jmdobry/gists{/gist_id}","starred_url":"https://api.github.com/users/jmdobry/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmdobry/subscriptions","organizations_url":"https://api.github.com/users/jmdobry/orgs","repos_url":"https://api.github.com/users/jmdobry/repos","events_url":"https://api.github.com/users/jmdobry/events{/privacy}","received_events_url":"https://api.github.com/users/jmdobry/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jmdobry/gcloud-node","description":"Google Cloud Client Library for Node.js","fork":true,"url":"https://api.github.com/repos/jmdobry/gcloud-node","forks_url":"https://api.github.com/repos/jmdobry/gcloud-node/forks","keys_url":"https://api.github.com/repos/jmdobry/gcloud-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jmdobry/gcloud-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jmdobry/gcloud-node/teams","hooks_url":"https://api.github.com/repos/jmdobry/gcloud-node/hooks","issue_events_url":"https://api.github.com/repos/jmdobry/gcloud-node/issues/events{/number}","events_url":"https://api.github.com/repos/jmdobry/gcloud-node/events","assignees_url":"https://api.github.com/repos/jmdobry/gcloud-node/assignees{/user}","branches_url":"https://api.github.com/repos/jmdobry/gcloud-node/branches{/branch}","tags_url":"https://api.github.com/repos/jmdobry/gcloud-node/tags","blobs_url":"https://api.github.com/repos/jmdobry/gcloud-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jmdobry/gcloud-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jmdobry/gcloud-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/jmdobry/gcloud-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jmdobry/gcloud-node/statuses/{sha}","languages_url":"https://api.github.com/repos/jmdobry/gcloud-node/languages","stargazers_url":"https://api.github.com/repos/jmdobry/gcloud-node/stargazers","contributors_url":"https://api.github.com/repos/jmdobry/gcloud-node/contributors","subscribers_url":"https://api.github.com/repos/jmdobry/gcloud-node/subscribers","subscription_url":"https://api.github.com/repos/jmdobry/gcloud-node/subscription","commits_url":"https://api.github.com/repos/jmdobry/gcloud-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/jmdobry/gcloud-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/jmdobry/gcloud-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/jmdobry/gcloud-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/jmdobry/gcloud-node/contents/{+path}","compare_url":"https://api.github.com/repos/jmdobry/gcloud-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jmdobry/gcloud-node/merges","archive_url":"https://api.github.com/repos/jmdobry/gcloud-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jmdobry/gcloud-node/downloads","issues_url":"https://api.github.com/repos/jmdobry/gcloud-node/issues{/number}","pulls_url":"https://api.github.com/repos/jmdobry/gcloud-node/pulls{/number}","milestones_url":"https://api.github.com/repos/jmdobry/gcloud-node/milestones{/number}","notifications_url":"https://api.github.com/repos/jmdobry/gcloud-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jmdobry/gcloud-node/labels{/name}","releases_url":"https://api.github.com/repos/jmdobry/gcloud-node/releases{/id}","deployments_url":"https://api.github.com/repos/jmdobry/gcloud-node/deployments","created_at":"2016-06-30T20:38:57Z","updated_at":"2016-06-30T20:38:59Z","pushed_at":"2016-08-18T22:51:02Z","git_url":"git://github.com/jmdobry/gcloud-node.git","ssh_url":"git@github.com:jmdobry/gcloud-node.git","clone_url":"https://github.com/jmdobry/gcloud-node.git","svn_url":"https://github.com/jmdobry/gcloud-node","homepage":"https://googlecloudplatform.github.io/gcloud-node/","size":16098,"stargazers_count":0,"watchers_count":0,"language":"JavaScript","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"GoogleCloudPlatform:master","ref":"master","sha":"d606b2aecf8033a96cb512d509fa98ee33a3dc89","user":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"repo":{"id":19483273,"name":"gcloud-node","full_name":"GoogleCloudPlatform/gcloud-node","owner":{"login":"GoogleCloudPlatform","id":2810941,"avatar_url":"https://avatars.githubusercontent.com/u/2810941?v=3","gravatar_id":"","url":"https://api.github.com/users/GoogleCloudPlatform","html_url":"https://github.com/GoogleCloudPlatform","followers_url":"https://api.github.com/users/GoogleCloudPlatform/followers","following_url":"https://api.github.com/users/GoogleCloudPlatform/following{/other_user}","gists_url":"https://api.github.com/users/GoogleCloudPlatform/gists{/gist_id}","starred_url":"https://api.github.com/users/GoogleCloudPlatform/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/GoogleCloudPlatform/subscriptions","organizations_url":"https://api.github.com/users/GoogleCloudPlatform/orgs","repos_url":"https://api.github.com/users/GoogleCloudPlatform/repos","events_url":"https://api.github.com/users/GoogleCloudPlatform/events{/privacy}","received_events_url":"https://api.github.com/users/GoogleCloudPlatform/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/GoogleCloudPlatform/gcloud-node","description":"Google Cloud Client Library for Node.js","fork":false,"url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node","forks_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/forks","keys_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/keys{/key_id}","collaborators_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/teams","hooks_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/hooks","issue_events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/events{/number}","events_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/events","assignees_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/assignees{/user}","branches_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/branches{/branch}","tags_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/tags","blobs_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/refs{/sha}","trees_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/trees{/sha}","statuses_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/statuses/{sha}","languages_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/languages","stargazers_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/stargazers","contributors_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/contributors","subscribers_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/subscribers","subscription_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/subscription","commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/commits{/sha}","git_commits_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/git/commits{/sha}","comments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/comments{/number}","issue_comment_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/comments{/number}","contents_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/contents/{+path}","compare_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/compare/{base}...{head}","merges_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/merges","archive_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/downloads","issues_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues{/number}","pulls_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls{/number}","milestones_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/milestones{/number}","notifications_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/labels{/name}","releases_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/releases{/id}","deployments_url":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/deployments","created_at":"2014-05-06T06:18:00Z","updated_at":"2016-08-19T10:32:09Z","pushed_at":"2016-08-19T00:50:31Z","git_url":"git://github.com/GoogleCloudPlatform/gcloud-node.git","ssh_url":"git@github.com:GoogleCloudPlatform/gcloud-node.git","clone_url":"https://github.com/GoogleCloudPlatform/gcloud-node.git","svn_url":"https://github.com/GoogleCloudPlatform/gcloud-node","homepage":"https://googlecloudplatform.github.io/gcloud-node/","size":17870,"stargazers_count":867,"watchers_count":867,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":199,"mirror_url":null,"open_issues_count":65,"forks":199,"open_issues":65,"watchers":867,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407"},"html":{"href":"https://github.com/GoogleCloudPlatform/gcloud-node/pull/1407"},"issue":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/1407"},"comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/issues/1407/comments"},"review_comments":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407/comments"},"review_comment":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/pulls/1407/commits"},"statuses":{"href":"https://api.github.com/repos/GoogleCloudPlatform/gcloud-node/statuses/3fc3b851b148697e9dd16e5b8974a0c06e96778f"}}}}
{"actor":{"display_login":"callmehiphop"}}