22

This is probably a simple question but I'm new to cloud functions/Node programming and haven't found the right documentation yet.

How do I write a Google cloud function that will receive a HTTP request but then send a HTTP request to a different endpoint? For example, I can send the HTTP trigger to my cloud function (https://us-central1-plugin-check-xxxx.cloudfunctions.net/HelloWorldTest). Later in the project I'll figure out how to implement a delay. But then I want to respond with a new HTTP request to a different endpoint (https://maker.ifttt.com/trigger/arrive/with/key/xxxx). How do I do that?

exports.helloWorld = function helloWorld(req, res) {
  // Example input: {"message": "Hello!"}
  if (req.body.message === undefined) {
    // This is an error case, as "message" is required.
    res.status(400).send('No message defined!');
  } else {
    // Everything is okay.
    console.log(req.body.message);
    res.status(200).send('Success: ' + req.body.message);
    // ??? send a HTTP request to IFTTT endpoint here
  }
};
Mark Peterson
  • 899
  • 3
  • 10
  • 19

5 Answers5

22

Here is the code that I managed to get working with help from Chetan Kanjani. When I send a text message to my Google Cloud function endpoint, it replys with a text message to IFTTT (a different endpoint).

const request = require('request');

exports.helloWorld = function helloWorld(req, res) {
  // Example input: {"message": "Hello!"}
  if (req.body.message === undefined) {
    // This is an error case, as "message" is required.
    res.status(400).send('No message defined!');
  } else {
    // Everything is okay.
    console.log(req.body.message);

    request.get('https://maker.ifttt.com/trigger/arrival/with/key/xxxx', function (error, response, body) {
      console.log('error:', error); // Print the error if one occurred 
      console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received 
      console.log('body:', body); //Prints the response of the request. 
    });
    res.status(200).send("Success");
  }
};

I also had to change the package.json file to include the request package. It already had the sample-http package, I added the dependencies:

{
  "name": "sample-http",
  "version": "0.0.1",
  "dependencies": {
    "request": "^2.81.0"
  }
}

I'm still not sure where the console.log function prints out the information. That might be helpful for future debugging.

Mark Peterson
  • 899
  • 3
  • 10
  • 19
  • The logs goes to google cloud logging https://console.cloud.google.com/logs?service=cloudfunctions.googleapis.com – Neil Jul 14 '17 at 18:55
  • Just leaving a note that this worked for me but I had to wait a few minutes for the request module to be installed. I was getting errors stating the module could not be found, so I imagine there's an npm installer process happening in the background. After a few minutes, it was fine. – Sinaesthetic Apr 07 '18 at 22:07
  • Message from 2020: This answer saved me! Been keyboard banging for days trying to get pub/sub to send a GET request (which I guess it won't) and learned there's a module to get Firebase to GET for me! Now I get it. – AverageHelper Feb 13 '20 at 06:07
  • FYI the `request` module was deprecated in 2020 – Crashalot May 08 '20 at 01:45
5

The Request module uses callbacks. If you want to use JavaScript promises instead, the Axios module provides equivalent functionality.

5

Old, but I came across this while searching myself:

request module with promise support is (request-promise)

OtterJesus
  • 55
  • 3
  • 10
5

The code below worked. Not sure if Axios is the ideal module for simple requests like these, but the Google Cloud Function documentation uses Axios so it seemed sensible to also use Axios. Other answers use the request module, but it was deprecated in February 2020.

Note: GCF doesn't support ES6 natively at this time. ES6 support is coming with Node 13.

Package.json

{
  "name": "YOUR_NAME",
  "version": "0.0.1",
  "dependencies": {
    "axios": "^0.19.2"
  }
}

Index.js

/**
 * Required Modules
 */
const axios = require("axios");


/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.run = async(req, res) => {
  // Set API end point.
  let apiURL = YOUR_URL;

  // Wrap API parameters in convenient object.
  let apiData = {
    PARAM_1: PARAM_DATA,
    PARAM_2: PARAM_DATA
  };

  // Invoke API.
  axios.post(apiURL,
    JSON.stringify(apiData)
  )
  .then((response) => {
    res.status(200).send(response.data);
    console.log(response);
  }, (error) => {
    res.status(500).send(response.data);
    console.log(error);
  });
};
Crashalot
  • 33,605
  • 61
  • 269
  • 439
  • what version of node are you using? – Ari Aug 11 '20 at 02:29
  • @Ari node 10 now, though this answer was originally on node 8. – Crashalot Aug 11 '20 at 07:39
  • thank you, I was running into issues with Node and ES6 support so thought the version matters. Turns out I just needed to change the `index.js` to `index.mjs` thanks tho – Ari Aug 12 '20 at 18:24
  • 1
    @Ari no problem. this code is also outdated because it uses promises chaining instead of async/await. can update the answer to what we're using now if you want. – Crashalot Aug 13 '20 at 00:40
4

Use https://www.npmjs.com/package/request module.

var request = require('request');
request.get('https://maker.ifttt.com/trigger/arrive/with/key/xxxx', function (error, response, body) {
  console.log('error:', error); // Print the error if one occurred 
  console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received 
  console.log('body:', body); //Prints the response of the request. 
});
  • Thanks for pointing me in the right direction. I was able to get the cloud function working. The final version is posted – Mark Peterson Jun 01 '17 at 04:03