{"id":15568685,"url":"https://github.com/shanepeckham/cadlab_loyalty","last_synced_at":"2025-06-23T05:42:29.034Z","repository":{"id":69130194,"uuid":"84064144","full_name":"shanepeckham/CADLab_Loyalty","owner":"shanepeckham","description":"This is a end to end Loyalty business scenario","archived":false,"fork":false,"pushed_at":"2017-11-14T18:34:54.000Z","size":10077,"stargazers_count":19,"open_issues_count":1,"forks_count":9,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-24T00:06:04.141Z","etag":null,"topics":["azure","azure-functions","cognitive-services","hackathon","iaas","paas","serverless"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shanepeckham.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-03-06T11:13:07.000Z","updated_at":"2023-08-29T11:07:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"05bd0b8b-d75f-4d27-8b58-c3840b244418","html_url":"https://github.com/shanepeckham/CADLab_Loyalty","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shanepeckham%2FCADLab_Loyalty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shanepeckham%2FCADLab_Loyalty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shanepeckham%2FCADLab_Loyalty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shanepeckham%2FCADLab_Loyalty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shanepeckham","download_url":"https://codeload.github.com/shanepeckham/CADLab_Loyalty/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250535100,"owners_count":21446508,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","azure-functions","cognitive-services","hackathon","iaas","paas","serverless"],"created_at":"2024-10-02T17:20:28.326Z","updated_at":"2025-04-24T00:06:12.155Z","avatar_url":"https://github.com/shanepeckham.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# *CAD Customer Loyalty Business Scenario Lab*\n\n# What is it?\n\nThis repository will provision an environment that may be used as a Lab to build an end to end scenario that does the following:\n\n*\tQuery a Contact List API for a customer\n*\tQuery our legacy on-prem Ticket system to get the customer’s last feedback\n*\tPerform sentiment analysis on this feedback\n*\tGenerate a digital discount coupon if they were dissatisfied\n*\tMail them the coupon\n\n# What does it showcase?\n\nThis solution brings together Infrastructure as a Service (IaaS), Platform as a Service (PaaS), Software as a Service (SaaS) and Serverless components on Microsoft Azure to build a realistic end to end scenario to nurture customers. Furthermore, the democratization of AI is tied in nicely by incorporating Cognitive Services to perform text analysis and determine the sentiment of a customer’s feedback.\n\n# The end to end scenario\n\nThis solution will query a customer datastore, then get the last support case associated with a customer from a different datastore, check the sentiment/satisfaction of the customer's last feedback and generate a digital discount coupon for them if their sentiment is determined to be dissatisfied. The coupon will then be emailed to the customer to redeem. \n\n# The solution aims to show the following:\n\n*\tHow legacy lift and shift applications on IaaS can be incorporated into modern solutions to quickly derive value from higher value services in the cloud.\n*\tHow existing investments can be modernized without having to rebuild everything to drive customer value\n*\tThe ease with which On-premise, public and private components may be brought together to build workloads that bring business value\n*\tThe meshing of IaaS, PaaS, SaaS, Serverless and AI with tools that are accessible to non-developers\n*\tOSS workloads running on Azure\n\n# Technology used\n\nThe following technology components are used in this solution:\n\n*\tSwagger enabled Node.js APIs running on Azure App Services (PaaS)\n*\tUbuntu with a custom extension template to rapidly provision and deploy a custom image with a running legacy mysql solution (IaaS) [Thanks Justin Davies for helping here](https://github.com/juda-ms)\n*\tAzure networking to isolate legacy workloads (IaaS)\n*\tAPI Management to govern APIs and to bridge publicly accessible APIs with isolated APIs (SaaS) (IaaS)\n*\tAzure functions to run dynamic ‘pay-as-you-go’ compute (Serverless) [Thanks Christof Claasens and Katrien de Graeve for the generate coupon function](https://github.com/xstof/Quiz) \n*\tAzure logic apps to provide serverless integration that is accessible to non-developers (Serveless)\n*\tAzure Resource Manager templates to automate the provisioning and inflation of a full environment\n\n# Solution flow\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/Typology.jpg \"Solution Flow\")\n\n# The Lab component\n\nThis solution will install and configure all of the components required to build the end to end Loyalty scenario. The Lab attendees just need to wire everything together in a Logic App. \n\n# Preparing for the solution\n\nFor this Lab you will require:\n* A cognitive services trial account key, get it here - https://www.microsoft.com/cognitive-services/en-us/sign-up\n* A Gmail account for sending emails, get it here - https://accounts.google.com/SignUp?service=mail\u0026continue=http%3A%2F%2Fmail.google.com%2Fmail%2Fe-11-14a952576b5f2ffe90ec0dd9823744e0-46a962fbb7947b68059374ddde7f29b5490a6b4d\n* Install Postman, get it here - https://www.getpostman.com\n* If using Windows 10 get Bash for Windows - https://msdn.microsoft.com/en-us/commandline/wsl/install_guide or putty if on an older version - http://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html\n\n# How to install the solution\n\n[Complete step 1 below prior to attending the lab](#how-to-install-the-solution)\n\n## 1. Provisioning the components: Select Deploy to Azure to deploy to your Azure instance that you are currently logged in to.\n\n\u003ca href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fshanepeckham%2FCADHackathon_Loyalty%2Fmaster%2Fazuredeploy.json\" target=\"_blank\"\u003e\n    \u003cimg src=\"http://azuredeploy.net/deploybutton.png\"/\u003e\n\u003c/a\u003e\n\u003ca href=\"http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2Fshanepeckham%2FCADHackathon_Loyaltys%2Fmaster%2Fazuredeploy.json\" target=\"_blank\"\u003e\n    \u003cimg src=\"http://armviz.io/visualizebutton.png\"/\u003e\n\u003c/a\u003e\n\nSelect or create a Resource Group to deploy to and the only parameter you need to change is the Deployment Name - give it any name of 12 characters or less as it will be used to generate a hash to ensure your site names are unique, see the image below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/deploymentname.png)\n\nThis will take roughly 30 minutes as this will provision:\n\n* Two VNETs\n* An Ubuntu VM and place in inside the VNET isolated with NSGs\n* An API Management instance (Developer Tier) and place it inside a subnet within the VNET\n* An App Service API app (Contact List) and deploy a node.js Swagger enabled API to it\n* An App Service serverless function with dynamic scaling and pricing\n* Storage accounts to house the VM VHD, the Function logging and the App Service API logging\n\n## 2. Checking the Contact List API App: Once deployment is complete, navigate to your App Service API App, its default name will be CADAPIMasterSite[hash] and click on the URI in the overview blade, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/App_URI.png)\n\nThis will navigate you to a URL that will display the following message if it was provisioned correctly:\n```\nCannot GET / \n```\nNow type ``` /docs ``` after the azurewebsites.net part of the url and you should see the Swagger editor open with a test harness to test the API:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/swaggerharness.png)\n\nYou should now be able to test a few methods of the API to check if how it works. It will query 3 contacts and methods exist to query all, query by Id, query associated Case Number by Id and query contact Email by Id.\n\nNow copy the URL without the ``` /docs ``` component and paste is somewhere for retrieval later on.\n\n### Change the email addresses to in the contact API to your email\n\n* Navigate back to your API App in the Azure portal - e.g. http://cadapimastersite[hash].azurewebsites.net\n* Select the Advancted Tools blade and then click Go. This will open the Kudu console where we can be naughty and go and edit the source files \n* In the top menu select Debug Console --\u003e CMD\n* In the top tree folder structure click Site --\u003e WWWRoot --\u003e lib -- and click the pencil next to the contacts.json file. \n* Change the email for the contact you want to change\n* Click Save\n* Restart your API App. This can be done from the Restart button on the overview blade\n\n## 3. Now we will import the Contact List API into the API Management solution\n\nNavigate to API Management component provisioned within Azure, its name will be generated by default with the following format cadapim[hash].\n\nClick on the overview blade and select 'Publisher Portal' (note we will use the old portal while the new portal is still in preview), see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/apimpublisherportal.png)\n\nThis will navigate you to the Publisher portal, select Import API, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/importAPI.png)\n\nNow enter the following values:\n\n* Select \"From Url\"\n* Paste your API URL from step 2 and add ``` /swagger ``` on the end e.g. http://cadapimastersite[hash].azurewebsites.net/swagger\n* Select \"Swagger\" as the specification format\n* Select New API\n* Type \"Contacts\" into the Web API URL Suffix field\n* Click Products and select \"Unlimited\"\n* Click Save\n\nSee below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/importapidetails.png)\n\nYou will now have imported an API that will now be accessible from the API Gateway. You can test it by clicking on Developer Portal, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/developerportal.png)\n\nClick APIs --\u003e Contact List API --\u003e Try It\n\nThis will take you to the test harness of API Management. Click the eyeball and copy the value in the field Ocp-Apim-Subscription-Key, this is your APIMKey which we will use extensively, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/apimkey.png)\n\nYou can test the API now and it should return values with a status of 200 Ok.\n\nWe have now set up the first API in our process.\n\n## 4. Install the legacy Ticket API on the VM\n\nWe could deploy this script as a custom script extension on the VM but that will complicate troubleshooting in a lab scenario so we will manually connect to the machine and run the build script, it is a single install script that will set up everything required.\n\nNavigate to your VM, the default name will be CADLegacyAPI[hash] and navigate to the Overview blade and copy the value in the field Public IP Address/DNS label, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/vmip.png)\n\nWe will now ssh onto the machine using Bash for Windows on Windows 10, or putty or just plain old terminal on a mac or Linux.\n\n* Type ssh MiniCADAdmin@[pasted ip address - without value '/none' on the end) e.g. ssh MiniCADAdmin@12.34.56.78 and press enter - see below:\n\n![alt text](https://github.com/shanepeckham/CADHackathon_Loyalty/blob/master/Images/ssh2.jpg)\n\n* Select yes to the message \"Are you sure you want to continue connecting\"\n* Type in password MiniCADAdmin123 - note this is hardcoded in the deploy\n* Paste the following in the command line: ``` git clone https://github.com/shanepeckham/CADHackathon_Loyalty.git ```\n* Now type ``` cd CADHackathon_Loyalty ```\n* Now type ``` bash installVM.sh ```\n* Upon completion you will see a screen similar to that below, with the final status 'Starting Legacy API'\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/startinglegacyapi.png)\n\nYour Legacy Ticket API should now be listening on port 8000 but this will not be accessible from the outside world. Note, if you restart your VM or want to restart the legacy api, simply navigate to the /LegacyAPI/CADContacts folder and run node server.js. \ne.g.\n\n```cd LegacyAPI \ncd CADContacts\nnode server.js\n```\n \n## 5. Now we will import the Case Contact List API (Legacy Ticket API) into API Management.\n\nNavigate to API Management component provisioned within Azure, its name will be generated by default with the following format cadapim[hash].\n\nClick on the overview blade and select 'Publisher Portal' (note we will use the old portal while the new portal is still in preview), see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/apimpublisherportal.png)\n\nThis will navigate you to the Publisher portal, select Import API, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/importAPI.png)\n\nNow enter the following values:\n\n* Select \"From Url\"\n* Paste http://10.1.1.4:8000/swagger into this field. Note this is your internal VNET address for your VM\n* Select \"Swagger\" as the specification format\n* Select New API\n* Type \"LegacyAPI\" into the Web API URL Suffix field\n* Click Products and select \"Unlimited\"\n* Click Save\n\nSee below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/legacyapiimport.png)\n\nYou will now have imported an API that will now be accessible from the API Gateway. You can test it by clicking on Developer Portal, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/devportallegacy.png)\n\nClick APIs --\u003e Contact Case List API --\u003e Try It\n\nThis will take you to the test harness of API Management. Click the eyeball and copy the value in the field Ocp-Apim-Subscription-Key, this should be the same as your previous API product.\n\nYou can test the API now and it should return values with a status of 200 Ok.\n\nWe have now set up the legacy Ticket API in our process.\n\n## 6. Import Function Storage hooks\n\nClick on the Deploy button below.\n\n\u003ca href=\"https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fshanepeckham%2FCADHackathon_Loyalty%2Fmaster%2Fazuredeployfunctionsettings.json\" target=\"_blank\"\u003e\n    \u003cimg src=\"http://azuredeploy.net/deploybutton.png\"/\u003e\n\u003c/a\u003e\n\nNB - Make sure you use the same Deployment Name as you did in Step 1.\n\nUpdate: Azure functions has recently changed and the new release is not deploying the code correctly. Navigate to Platform Features --\u003e Deployment Options, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/newfuncdeploy1.png)\n\nIn the pane on the right click the 'Sync' button. This will redploy the code and will take around 2-3 minutes, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/newfuncdeploy2.png)\n\nOnce complete, click the Refresh icon as highlighted below and you should see the following:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/newfuncdeploy3.png)\n\nYou can test the function in the test harness within the function app itself, add this to the Request body:\n```\n{ \"name\": \"hello\" }\n```\nYou should see the output look something like this:\n```\n{\"couponUrl\":\"https://cadfuncstorrvhyzok7zv4gw.blob.core.windows.net/coupons/%5Bobject%20Object%5D.jpg?st=2017-03-14T20%3A27%3A59Z\u0026se=2017-03-14T21%3A27%3A59Z\u0026sp=r\u0026sv=2015-12-11\u0026sr=b\u0026sig=6UUHFHY08JihUU8vT%2Fus%2Fot9Pl%2BZud6jaakMNTuCFZc%3D\"} Status 200 Ok\n```\nNote, if you get an error upon first invocation, run it again and it should work. You are now ready to build the logic app.\n\n# The Logic App solution\n\n## SPOILER ALERT - this is the full solution, so only look here if you get stuck!\n\nWe want to get the customer's details, find their last associated case and then check the feedback against it.\n\n### The data model\n\nSee the diagram below for the simplistic data model to help you query the right data.\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/DemoDataModel.jpg)\n\nCreate a HTTP Request Step, click save - you will receive an endpoint upon save. \n\nSelect the Request step, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/Request.png)\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/httprequest.png)\n\nOnce you save the Logic app you will get and endpoint, you can now invoke your logic app with Postman - add the URL and select POST. Ensure you have set the Header \"Content-Type\" with value \"application/json\". Select body, select \"raw\" and enter the follow value for your body content:\n```\n{\n  \"APIMKey\": \"[Your APIM Key goes here]\",\n  \"id\": 1\n}\n```\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/postmanheaders.png)\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/postmanbody.png)\n\nNow add a step to include an API Management API - select your API \"Contact List API\". You will want to select the method GET for contacts/{id}\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/contactsstep1.png)\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/contactsstep2.png)\n\nYou will need to navigate to the code view to be able to select the json fields that will be posted as part of the body. Note, you can select the values you are posting in the body using javascript object notation. \n\nYour code view should look like this:\n```\n            \"QueryContactsById\": {\n                \"inputs\": {\n                    \"api\": {\n                        \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/[ResourceGroup]/providers/Microsoft.ApiManagement/service/cadapimxdb3o43h6p7bq/apis/58cd4c45dc78ac0f84da1287\"\n                    },\n                    \"method\": \"get\",\n                    \"pathTemplate\": {\n                        \"parameters\": {\n                            \"id\": \"@{encodeURIComponent(triggerBody()['id'])}\"\n                        },\n                        \"template\": \"/Contacts/contacts/{id}\"\n                    },\n                    \"subscriptionKey\": \"@{triggerBody()['APIMKey']}\"\n                },\n                \"runAfter\": {},\n                \"type\": \"ApiManagement\"\n            }\n```\nNavigating back to the designer should show your values resolved like below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/querycontactsbyid.png)\n\nNow you need to query the Legacy Ticket API (Contacts Case List API) which is inside the isolated network to get the last case for that customer and retrieve the customer's feedback on the case. From the demo model hint above you want to use the caseNum field from the QueryContactsById to query the Legacy Ticket API field primary key field CaseId.\n\nAdd an API Management API step, select the Contact Case List API and once again query by Id, which in this CaseId which maps to the caseNum output from the previous step and add the API Management subscription key.\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/querycasesbyid.png)\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/querycasesselectidmethod.png)\n\nEnsure you select the correct outputs from the previous step(s) as inputs to this step, see below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/querycasebycasenum.png)\n\nNow if you applied the logic from the previous step to select the correct outut field values (which would be a sensible approach) you will probably get the following error:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/querycaseserror.png)\n\nThis is due to us outputting an array but not specifying which record/index we want to use. Change the following line from\n```\n\"id\": \"@{encodeURIComponent(body('QueryContactsById')?['caseNum'])}\"\n```\nto use the first value of the array, namely the 0 index:\n\n```\n  \"id\": \"@{encodeURIComponent(body('QueryContactsById')[0]['caseNum'])}\"\n```\n\nHere is what your code view should look like for this step:\n```\n            \"QueryCasesById\": {\n                \"inputs\": {\n                    \"api\": {\n                        \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/[ResourceGroup]/providers/Microsoft.ApiManagement/service/cadapimxdb3o43h6p7bq/apis/58cd5516dc78ac0f84da1289\"\n                    },\n                    \"method\": \"get\",\n                    \"pathTemplate\": {\n                        \"parameters\": {\n                            \"id\": \"@{encodeURIComponent(body('QueryContactsById')[0]['caseNum'])}\"\n                        },\n                        \"template\": \"/LegacyAPI/contacts/{id}\"\n                    },\n                    \"subscriptionKey\": \"@{triggerBody()['APIMKey']}\"\n                },\n                \"runAfter\": {\n                    \"QueryContactsById\": [\n                        \"Succeeded\"\n                    ]\n                },\n                \"type\": \"ApiManagement\"\n            },\n```\n\nNow we want to add our Cognitive Services 'Detect Sentiment' (note you will need to have your key ready that you got when you signed up for the Text Analytics preview as part of the pre-requisites) step  so that we can analyse the sentiment of the Ticket Feedback:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/searchdetect.png)\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/selectsentiment.png)\n\nWe now need to make sure we send the correct output from the QueryCasesById step to the Detect Sentiment step, use the javascript dot notation approach again with an index value. Your steps should look like this:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/lastfeedback.png)\n\nYour code view should look like this:\n```\n            \"Detect_Sentiment\": {\n                \"inputs\": {\n                    \"body\": {\n                        \"text\": \"@{body('QueryCasesById')?['last_feedback']}\"\n                    },\n                    \"host\": {\n                        \"api\": {\n                            \"runtimeUrl\": \"https://logic-apis-northeurope.azure-apim.net/apim/cognitiveservicestextanalytics\"\n                        },\n                        \"connection\": {\n                            \"name\": \"@parameters('$connections')['cognitiveservicestextanalytics']['connectionId']\"\n                        }\n                    },\n                    \"method\": \"post\",\n                    \"path\": \"/sentiment\"\n                },\n                \"runAfter\": {\n                    \"QueryCasesById\": [\n                        \"Succeeded\"\n                    ]\n                },\n                \"type\": \"ApiConnection\"\n            },\n```\n\nNow we want to add a condition to check the sentiment, if the probability outcome is less than 0.5, then it negative sentiment and therefore qualifies for our discount coupon.\n\nYour condition should look like this:\n\n![alt text](https://github.com/shanepeckham/CADHackathon_Loyalty/blob/master/Images/Condition.jpg)\n\nWith the following in code view:\n```\n\"expression\": \"@less(body('Detect_Sentiment')?['score'], 0.5)\",\n                        \"runAfter\": {\n                            \"Detect_Sentiment\": [\n                                \"Succeeded\"\n                            ]\n                        },\n                        \"type\": \"If\"\n\n```\n\nNow you can call the GenerateCoupon function if the condition is met, pass in the name of the user that you want to generate the digital coupon for:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/ifcondition0.png)\n\nWith the following in the code view:\n```\n\"GenerateCoupon\": {\n                        \"inputs\": {\n                            \"body\": {\n                                \"name\": \"@body('QueryContactsById')[0]['name']\"\n                            },\n                            \"function\": {\n                                \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/NewLoyaltyPlan/providers/Microsoft.Web/sites/CADFuncxdb3o43h6p7bq/functions/GenerateCoupon\"\n                            }\n                        },\n                        \"runAfter\": {},\n                        \"type\": \"Function\"\n                    }\n                },\n```\nNow we want to send an email to every receipient to inform them that they can download a digital coupon which we have generated for them.\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/selectgmail.png)\n\nYour email step should look like this:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/sendemail.png)\n\nWith the following code view:\n```\n                    \"Send_email\": {\n                        \"inputs\": {\n                            \"body\": {\n                                \"Body\": \"Please accept this coupon: @{body('GenerateCoupon')}\",\n                                \"Subject\": \"We heard that you were not happy\",\n                                \"To\": \"@{body('QueryContactsById')[0]['email']}\"\n                            },\n                            \"host\": {\n                                \"api\": {\n                                    \"runtimeUrl\": \"https://logic-apis-northeurope.azure-apim.net/apim/gmail\"\n                                },\n                                \"connection\": {\n                                    \"name\": \"@parameters('$connections')['gmail']['connectionId']\"\n                                }\n                            },\n                            \"method\": \"post\",\n                            \"path\": \"/Mail\"\n                        },\n                        \"runAfter\": {\n                            \"GenerateCoupon\": [\n                                \"Succeeded\"\n                            ]\n                        },\n                        \"type\": \"ApiConnection\"\n                    }\n```\n\nThe full code solution view looks like this:\n```\n{\n    \"$connections\": {\n        \"value\": {\n            \"cognitiveservicestextanalytics\": {\n                \"connectionId\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/NewLoyaltyPlan/providers/Microsoft.Web/connections/cognitiveservicestextanalytics\",\n                \"connectionName\": \"cognitiveservicestextanalytics\",\n                \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/providers/Microsoft.Web/locations/northeurope/managedApis/cognitiveservicestextanalytics\"\n            },\n            \"gmail\": {\n                \"connectionId\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/NewLoyaltyPlan/providers/Microsoft.Web/connections/gmail\",\n                \"connectionName\": \"gmail\",\n                \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/providers/Microsoft.Web/locations/northeurope/managedApis/gmail\"\n            }\n        }\n    },\n    \"definition\": {\n        \"$schema\": \"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#\",\n        \"actions\": {\n            \"Condition\": {\n                \"actions\": {\n                    \"GenerateCoupon\": {\n                        \"inputs\": {\n                            \"body\": {\n                                \"name\": \"@body('QueryContactsById')[0]['name']\"\n                            },\n                            \"function\": {\n                                \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/NewLoyaltyPlan/providers/Microsoft.Web/sites/CADFuncxdb3o43h6p7bq/functions/GenerateCoupon\"\n                            }\n                        },\n                        \"runAfter\": {},\n                        \"type\": \"Function\"\n                    },\n                    \"Send_email\": {\n                        \"inputs\": {\n                            \"body\": {\n                                \"Body\": \"Please accept this coupon: @{body('GenerateCoupon')}\",\n                                \"Subject\": \"We heard that you were not happy\",\n                                \"To\": \"@{body('QueryContactsById')[0]['email']}\"\n                            },\n                            \"host\": {\n                                \"api\": {\n                                    \"runtimeUrl\": \"https://logic-apis-northeurope.azure-apim.net/apim/gmail\"\n                                },\n                                \"connection\": {\n                                    \"name\": \"@parameters('$connections')['gmail']['connectionId']\"\n                                }\n                            },\n                            \"method\": \"post\",\n                            \"path\": \"/Mail\"\n                        },\n                        \"runAfter\": {\n                            \"GenerateCoupon\": [\n                                \"Succeeded\"\n                            ]\n                        },\n                        \"type\": \"ApiConnection\"\n                    }\n                },\n                \"expression\": \"@less(body('Detect_Sentiment')?['score'], 0.5)\",\n                \"runAfter\": {\n                    \"Detect_Sentiment\": [\n                        \"Succeeded\"\n                    ]\n                },\n                \"type\": \"If\"\n            },\n            \"Detect_Sentiment\": {\n                \"inputs\": {\n                    \"body\": {\n                        \"text\": \"@{body('QueryCasesById')?['last_feedback']}\"\n                    },\n                    \"host\": {\n                        \"api\": {\n                            \"runtimeUrl\": \"https://logic-apis-northeurope.azure-apim.net/apim/cognitiveservicestextanalytics\"\n                        },\n                        \"connection\": {\n                            \"name\": \"@parameters('$connections')['cognitiveservicestextanalytics']['connectionId']\"\n                        }\n                    },\n                    \"method\": \"post\",\n                    \"path\": \"/sentiment\"\n                },\n                \"runAfter\": {\n                    \"QueryCasesById\": [\n                        \"Succeeded\"\n                    ]\n                },\n                \"type\": \"ApiConnection\"\n            },\n            \"QueryCasesById\": {\n                \"inputs\": {\n                    \"api\": {\n                        \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/NewLoyaltyPlan/providers/Microsoft.ApiManagement/service/cadapimxdb3o43h6p7bq/apis/58cd5516dc78ac0f84da1289\"\n                    },\n                    \"method\": \"get\",\n                    \"pathTemplate\": {\n                        \"parameters\": {\n                            \"id\": \"@{encodeURIComponent(body('QueryContactsById')[0]['caseNum'])}\"\n                        },\n                        \"template\": \"/LegacyAPI/contacts/{id}\"\n                    },\n                    \"subscriptionKey\": \"@{triggerBody()['APIMKey']}\"\n                },\n                \"runAfter\": {\n                    \"QueryContactsById\": [\n                        \"Succeeded\"\n                    ]\n                },\n                \"type\": \"ApiManagement\"\n            },\n            \"QueryContactsById\": {\n                \"inputs\": {\n                    \"api\": {\n                        \"id\": \"/subscriptions/1b987fd6-b38e-40a1-bca8-4f67e6272c12/resourceGroups/NewLoyaltyPlan/providers/Microsoft.ApiManagement/service/cadapimxdb3o43h6p7bq/apis/58cd4c45dc78ac0f84da1287\"\n                    },\n                    \"method\": \"get\",\n                    \"pathTemplate\": {\n                        \"parameters\": {\n                            \"id\": \"@{encodeURIComponent(triggerBody()['id'])}\"\n                        },\n                        \"template\": \"/Contacts/contacts/{id}\"\n                    },\n                    \"subscriptionKey\": \"@{triggerBody()['APIMKey']}\"\n                },\n                \"runAfter\": {},\n                \"type\": \"ApiManagement\"\n            }\n        },\n        \"contentVersion\": \"1.0.0.0\",\n        \"outputs\": {},\n        \"parameters\": {\n            \"$connections\": {\n                \"defaultValue\": {},\n                \"type\": \"Object\"\n            }\n        },\n        \"triggers\": {\n            \"manual\": {\n                \"inputs\": {\n                    \"schema\": {}\n                },\n                \"kind\": \"Http\",\n                \"type\": \"Request\"\n            }\n        }\n    }\n}\n\n```\n# Troubleshooting\n\nIf you get and 'Internal Server Error' 500 on the Contact Case List (Legacy Ticket API) this could be because the node API has stopped. ssh into the VM and navigate to the /LegacyAPI/CADContacts folder and run 'node server.js'. \ne.g.\n\n```cd LegacyAPI \ncd CADContacts\nnohup node server.js \u0026\n```\nThe logout out of the ssh session.\n\nIf you get a 404 - Resource not found within the Logic app invoking the Legacy API, ensure that you have selected *HTTPS* not *HTTP* as the Web API URL Scheme. Check your settings are the same as in this image below:\n\n![alt text](https://github.com/shanepeckham/CADLab_Loyalty/blob/master/Images/troubleshoot1.png)\n\n\n# Securing this environment\n\nThe security lab for this environment may be found here [Securing the Loyalty environment](https://github.com/shanepeckham/CADLab_Loyalty_Security) \n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshanepeckham%2Fcadlab_loyalty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshanepeckham%2Fcadlab_loyalty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshanepeckham%2Fcadlab_loyalty/lists"}