Backup Orders to the Cloud using Pub/Sub

This article will talk about how to use a small amount of code to push order data to pub/sub where we can then run a google cloud function to save the data to google cloud storage.

Create a Pub/Sub Topic, such as woo-orders.

Simple Cloud Function to send data to Pub/Sub.

JavaScript (index.js)
'use strict';

const {PubSub} = require('@google-cloud/pubsub');
const pubsub = new PubSub();
const url = require('url');


// Publish to Pub/Sub.
exports.publish = async (req, res) => {

  if( 'POST' !== req.method ) {
      res.status(403).send('Forbidden!');
  }

  if( ! req.query && ! req.query.topic ){
    return res.status( 420 ).send( "Missing required \'topic\' parameter." );
  }

  if( req.query.apikey !== String( process.env.APIKEY ) ){
    return res.status( 420 ).send( "Required API Key is missing or invalid." );
  }

  console.log( "Publishing to Pub/Sub Topic: " + req.query.topic );

  // Set Topic.
  const topic = pubsub.topic( req.query.topic );

  const messageObject = {
    data: {
      message: req.body,
    },
  };
  const messageBuffer = Buffer.from(JSON.stringify(messageObject), 'utf8');
  
  console.log( JSON.stringify( req.body ) );

  // Publish the message.
  try {
    await topic.publish(messageBuffer);
    res.status(200).send({ "status" : "success", 'topic' : req.query.topic, "message" : req.body });
  } catch (err) {
    console.error(err);
    res.status(500).send(err);
    return Promise.reject(err);
  }
};
JSON (package.json)
 {
  "name": "webhook-to-pubsub",
  "version": "0.0.1",
  "private": true,
  "license": "Apache-2.0",
  "author": "Brandon Hubbard",
  "dependencies": {
    "@google-cloud/pubsub": "^1.4.1",
     "url"   : "^0.11.0"
  }
}

Now that are order data is making it to pub/sub we can create a new cloud function to save all the data to a google storage bucket.

PHP
if ( ! class_exists( 'Google_Cloud_Functions' ) ) {

	/**
	 * Google Cloud Functions
	 */
	class Google_Cloud_Functions {

		/**
		 * __construct function.
		 *
		 * @access public
		 * @return void
		 */
		public function __construct() {

		}

		/**
		 * Trigger Google Cloud Function.
		 * @param  string $region        Region.
		 * @param  string $project       Project.
		 * @param  string $function_name Function Name.
		 * @param  array  $body          Body.
		 * @return mixed                Results or error.
		 */
		public function trigger( string $region = '', string $project = '', string $function_name = '', $body = '', bool $cache = false, bool $debug = false ) {

			// Missing Valid Region.
			if( empty( $region ) ) {
				return new WP_Error( 'missing-region', __( "Please provide a valid Google Cloud Region (https://cloud.google.com/compute/docs/regions-zones/).", "google-cloud-functions" ) );
			}

			// Missing Valid Project.
			if( empty( $project ) ) {
				return new WP_Error( 'missing-project', __( 'Please provide a valid project name.', 'google-cloud-functions' ) );
			}

			// Missing Valid Function Name.
			if( empty( $function_name ) ) {
				return new WP_Error( 'missing-function-name', __( 'Please provide a valid function name.', 'google-cloud-functions' ) );
			}

			// Define Function URL.
			$function_url = esc_url( 'https://' . $region .'-' . $project . '.cloudfunctions.net/' . $function_name );

			// Use a Cached Response.
			if( true === $cache ) {
				$cache_name = 'gcf_cache_' . md5( $function_url );
				$response = get_transient( $cache_name );
				if( false === $response ) {
					$response = wp_remote_post( $function_url, array( 'body' => $body ) );
					set_transient( $cache_name, $response );
				}
			} else {
				$response = wp_remote_post( $function_url, array( 'body' => $body ) );
			}

			// Debug Response.
			if ( true === $debug ) {
				error_log( print_r( $response ) );
			}

			// Display Error.
			if( is_wp_error( $response ) ) {
    		return $response->get_error_message();
			}

			// Return Response.
			return wp_remote_retrieve_body( $response );

		}
	}
}

Related posts