public EngineInitializationResponseAPI Initialize(string authenticationToken, string tenantId, EngineInitializationRequestAPI engineInitializationRequest) { string endpointUrl = null; HttpClient httpClient = null; HttpContent httpContent = null; HttpResponseMessage httpResponseMessage = null; EngineInitializationResponseAPI engineInitializationResponse = null; Policy.Handle <ServiceProblemException>().Retry(HttpUtils.MAXIMUM_RETRIES).Execute(() => { using (httpClient = HttpUtils.CreateRuntimeHttpClient(authenticationToken, tenantId, null)) { // Use the JSON formatter to create the content of the request body httpContent = new StringContent(JsonConvert.SerializeObject(engineInitializationRequest)); httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // Construct the URL for the engine initialization request endpointUrl = ServiceUrl + MANYWHO_ENGINE_INITIALIZE_URI_PART; // Post the engine initialization request over to ManyWho httpResponseMessage = httpClient.PostAsync(endpointUrl, httpContent).Result; // Check the status of the response and respond appropriately if (httpResponseMessage.IsSuccessStatusCode) { // Get the engine initialization response object from the response message engineInitializationResponse = JsonConvert.DeserializeObject <EngineInitializationResponseAPI>(httpResponseMessage.Content.ReadAsStringAsync().Result); } else { throw new ServiceProblemException(new ServiceProblem(endpointUrl, httpResponseMessage, string.Empty)); } } }); return(engineInitializationResponse); }
public void Execute(INotifier notifier, String tenantId, String flowId, String player, String mode, String reportingMode, WorkflowRuleNotification workflowRuleNotification) { FlowResponseAPI flowResponse = null; EngineInvokeRequestAPI engineInvokeRequest = null; EngineInvokeResponseAPI engineInvokeResponse = null; EngineInitializationRequestAPI engineInitializationRequest = null; EngineInitializationResponseAPI engineInitializationResponse = null; AuthenticationCredentialsAPI authenticationCredentials = null; String authenticationToken = null; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing notification."); } // Check to see if we have object identifiers to process if (workflowRuleNotification.ObjectIDs != null && workflowRuleNotification.ObjectIDs.Count > 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Notification has object identifiers."); } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry(String.Format("Loading flow for tenant ({0}) and identifier ({1}).", tenantId, flowId)); } // Now we have the data from the message, we can execute the workflow // Load the flow by the unique identifier flowResponse = RunSingleton.GetInstance().LoadFlowById(notifier, authenticationToken, tenantId, flowId); // Check to make sure we have a flow response if (flowResponse == null) { throw new ArgumentNullException("FlowResponse", "The flow is null for the provided tenant and flow identifier."); } foreach (String objectID in workflowRuleNotification.ObjectIDs) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Sending initialization request to ManyWho."); } // Create an engine initialization request to kick off the flow engineInitializationRequest = new EngineInitializationRequestAPI(); engineInitializationRequest.flowId = new FlowIdAPI(); engineInitializationRequest.flowId.id = flowResponse.id.id; engineInitializationRequest.flowId.versionId = flowResponse.id.versionId; engineInitializationRequest.mode = mode; engineInitializationRequest.reportingMode = reportingMode; // If we're not using the default player, change the urls if (player != "default") { engineInitializationRequest.joinPlayerUrl = "https://flow.manywho.com/" + tenantId + "/play/" + player; engineInitializationRequest.playerUrl = "https://flow.manywho.com/" + tenantId + "/play/" + player; } // Initialize the workflow with the values provided engineInitializationRequest.inputs = new List <EngineValueAPI>(); engineInitializationRequest.inputs.Add(new EngineValueAPI() { developerName = "SalesforceNotificationRecordId", contentValue = objectID, contentType = ManyWhoConstants.CONTENT_TYPE_STRING }); engineInitializationRequest.inputs.Add(new EngineValueAPI() { developerName = "SalesforceNotificationObjectName", contentValue = workflowRuleNotification.ObjectName, contentType = ManyWhoConstants.CONTENT_TYPE_STRING }); if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("SalesforceNotificationRecordId: " + objectID); } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("SalesforceNotificationObjectName: " + workflowRuleNotification.ObjectName); } // Initialize the engine with the bare basics engineInitializationResponse = RunSingleton.GetInstance().Initialize(notifier, authenticationToken, tenantId, engineInitializationRequest); // Check to see if the workflow is authorized to execute - if not, we need to login using the session if (engineInitializationResponse.statusCode.Equals(ManyWhoConstants.AUTHORIZATION_STATUS_NOT_AUTHORIZED, StringComparison.OrdinalIgnoreCase) == true) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Event not authorized, attempting a login using session info."); } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("SessionId: " + workflowRuleNotification.SessionID); } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("SessionURL: " + workflowRuleNotification.SessionURL); } // Create the authentication credentials for the service authenticationCredentials = new AuthenticationCredentialsAPI(); authenticationCredentials.loginUrl = engineInitializationResponse.authorizationContext.loginUrl; authenticationCredentials.sessionToken = workflowRuleNotification.SessionID; authenticationCredentials.sessionUrl = workflowRuleNotification.SessionURL; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Logging into service again using session info."); } // Login to the system authenticationToken = RunSingleton.GetInstance().Login(notifier, tenantId, engineInitializationResponse.stateId, authenticationCredentials); // Apply the state back engineInitializationRequest.stateId = engineInitializationResponse.stateId; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Initializing engine again for state identifier: " + engineInitializationResponse.stateId); } // Initialize the engine again - re-using the state identifier engineInitializationResponse = RunSingleton.GetInstance().Initialize(notifier, authenticationToken, tenantId, engineInitializationRequest); } // Now create the fist engine invoke request so we can get the content of the first ivr engineInvokeRequest = new EngineInvokeRequestAPI(); engineInvokeRequest.currentMapElementId = engineInitializationResponse.currentMapElementId; engineInvokeRequest.invokeType = ManyWhoConstants.INVOKE_TYPE_FORWARD; engineInvokeRequest.mapElementInvokeRequest = new MapElementInvokeRequestAPI(); engineInvokeRequest.currentMapElementId = engineInitializationResponse.currentMapElementId; engineInvokeRequest.stateId = engineInitializationResponse.stateId; engineInvokeRequest.stateToken = engineInitializationResponse.stateToken; engineInvokeRequest.mode = mode; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Sending invoke request to ManyWho."); } // Invoke the engine with the first request engineInvokeResponse = RunSingleton.GetInstance().Execute(notifier, authenticationToken, tenantId, engineInvokeRequest); // If we're running in step through mode, we notify the author with the join identifier so they can debug the workflow if (SettingUtils.IsDebugging(engineInvokeRequest.mode) == true && engineInvokeRequest.mode.Equals(ManyWhoConstants.MODE_DEBUG_STEPTHROUGH, StringComparison.OrdinalIgnoreCase) == true) { notifier.AddLogEntry("Flow is waiting to be joined in order to be debugged."); notifier.AddLogEntry("JoinUrl: " + engineInvokeResponse.joinFlowUri + "&mode=" + engineInvokeRequest.mode); } } } else { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Notification does not have object identifiers."); } } }