Script Examples | Vantage CX - 1.4 - Script Examples - Vantage Customer Experience

Vantage Customer Experience User Guide

Product
Vantage Customer Experience
Release Number
1.4
Release Date
June 2021
Content Type
User Guide
Publication ID
B035-3800-099K
Language
English (United States)

The following example provides you with a fully-commented sample script.

For downloadable script templates that you can use as a starting point, refer to Vantage Customer Experience User Guide on https://docs.teradata.com/. The following gtm_template.groovy script is included in the template zip file.

import static groovyx.net.http.HttpBuilder.configure
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity

import com.teradata.tdaa.apihost.util.OAuth
import com.teradata.tdaa.apihost.util.Secret

import groovy.json.*

/**
 * Template that shows how you might configure a new API to translate requests and route them 
 * to the Decision Service's Targeted Message API
 * 
 * To use this, remove the comment marks (//) from the @RestController line below,
 * and change the details of each method in the class to the desired format,
 * You can add as many method annotated with @GetMapping or @PostMapping as you need.
 * 
 * See the Spring MVC documentation (https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-controller)
 * for more details on how you can annotate these methods and their arguments to extract different parts of the request URI, body, or HTTP headers.
 *
 * See https://http-builder-ng.github.io/http-builder-ng/ for more details on making outgoing HTTP requests.
 *
 * You can also call additional Java libraries from these scripts by placing a JAR file in
 * the /opt/teradata/api-host/scriptlibraries directory and importing the relevant classes.
 */
@RestController
class MyApiController {

	// constants for the connection to the downstream service
	final BASE_URL = "https://decision-server-host:8113"
	final USERNAME = "admin"
	final PASSWORD = Secret.get("decision-server")

	// definition of an HTTP client builder for the Decision Service
	// GET or POST requests will reuse this object and change properties specific to each API call
	def http = configure {
	    request.uri = BASE_URL
		request.headers["Authorization"] = "Basic " + "${USERNAME}:${PASSWORD}".bytes.encodeBase64().toString()
	    request.accept = "application/json"
	    request.contentType = "application/json"
	}

	// simple example of an object to use in the API results
	class Message {
		String id
		String link

		Message(id, link) {
			this.id = id
			this.link = link
		}
	}

	/**
	 * Example API endpoint that accepts GET requests in the form /mymessages/{customer id} and calls
	 * Get Targeted Message to a fixed channel and interaction point, then translates the results to a different format.
 	 */
	@GetMapping("/mymessages/{customerId}")
	handleGet(@PathVariable("customerId") customerId)	{
		// variables for the API, including Organization, Channel, Interaction Point, and Customer ID
		// you can hard-code these or retreive them from the incoming request URI
		def org = "Default"
		def channelKey = "ch2"
		def interactionPointKey = "ip1"

		// the URL for the Targeted Messages API, with placeholders from the variables defined above
		def targetedMessagesUrl = "/artim-decision/rs/interaction/${org}:${customerId}/TargetedMessages;channel=${channelKey};inp=${interactionPointKey}"

		// make an HTTP GET call to Targeted Messages
		http.get {
			request.uri.path = targetedMessagesUrl
			request.headers["Authorization"] = "Bearer " + OAuth.token("api_host_client")

			response.success { resp, result ->

				// translate the results from the Targeted Message API to the output format for this API
				def messages = []
		        result.Messages.each {
		        	messages.add(new Message(it.name, "/result/${it.messagePathId}"))
		        }

		        return [ "allMessages": messages ];
		    }
		    response.failure { resp, body ->
		        // in case of error, return the HTTP status code that the downstream service returned
		    	return ResponseEntity.status(resp.statusCode).build()
		    }
		}
	}

	/**
	 * Example API endpoint that accepts POST requests to /purchase-event and calls
	 * Get Targeted Message to a channel extracted from an HTTP header and a fixed interaction point, 
	 * then translates the results to a different format.
	 *
	 * The expected HTTP POST body for this example contains:
	 *
	 * { 
     *   "requestDetails": {
     *           "eventID": 1,
     *           "type": "checkout",
     *           "customerId": "Cust12345",
     *           "purchase": {
     *                   "date": "2020-01-02",
     *                   "amount": 1
     *           }
     *   }
	 *  } 
     *
     * and the request should include an "X-Channel-Id" request header matching the channel name.
     *
     * This expects the Organization to have channel mathcing the channel name and an interaction point named "cart" or "home".
 	 */
	@PostMapping("/purchase-event")
	handlePost(@RequestHeader HttpHeaders headers, @RequestBody String requestBody) {
		// parse the incoming HTTP request body as JSON (you could alternately use groovy.xml.XmlSlurper to parse XML)
		// see https://groovy-lang.org/json.html for more details on processing JSON 
		// or  https://groovy-lang.org/processing-xml.html for more details on processing XML
		def incoming = new JsonSlurper().parseText(requestBody)

		// variables for the API, including Organization, Channel, Interaction Point, and Customer ID
		// you can hard-code these or retreive them from the incoming request body, URI, or HTTP headers
		def org = "Default"
		def channelKey = headers["X-Channel-Id"][0]
		def interactionPointKey = (incoming.requestDetails.type == "checkout" ? "cart" : "home")
		def customerId = incoming.requestDetails.customerId

		// build up the set of Attributes to send as part of the request
		// you can hard-code these or retreive them from the incoming request object
		def gtmRequest = [			
			"tagData": [				
				"Customer": [					
					"Purchases": [						
						"transactionDate" : incoming.requestDetails.purchase.date,
						"amount" : incoming.requestDetails.purchase.amount,
						"type" : "Credit"
					]				
				]			
			]	
		]

		// the URL for the Targeted Messages API, with placeholders from the variables defined above
		def targetedMessagesUrl = "/artim-decision/rs/interaction/${org}:${customerId}/TargetedMessages;channel=${channelKey};inp=${interactionPointKey}"

		// make an HTTP POST call to Targeted Messages
		http.post {
			request.uri.path = targetedMessagesUrl
			request.body = gtmRequest
			//request.headers["Authorization"] = "Bearer " + OAuth.token('api_host_client')

			response.success { resp, result ->

				// translate the results from the Targeted Message API to the output format for this API
				def messages = []
		        result.Messages.each {
		        	messages.add(new Message(it.name, "/result/${it.messagePathId}"))
		        }

		        return [ "allMessages": messages ];
		    }
		    response.failure { resp, body ->
		    	// in case of error, return the HTTP status code that the downstream service returned
		    	return ResponseEntity.status(resp.statusCode).build()
		    }
		}

	}

}