public ServiceResponseAPI InvokeNotifyUsers(INotifier notifier, IAuthenticatedWho authenticatedWho, ServiceRequestAPI serviceRequest) { ChatterPostedMessage chatterPostedMessage = null; ChatterNewMessageSegment chatterNewMessageSegment = null; ServiceResponseAPI serviceResponse = null; SforceService sforceService = null; String groupAuthenticationToken = null; String authenticationUrl = null; String username = null; String password = null; String securityToken = null; String chatterBaseUrl = null; String adminEmail = null; String endpointUrl = null; String message = null; // Grab the configuration values from the service request authenticationUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_URL, serviceRequest.configurationValues, true); username = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_USERNAME, serviceRequest.configurationValues, true); password = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_PASSWORD, serviceRequest.configurationValues, true); securityToken = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_SECURITY_TOKEN, serviceRequest.configurationValues, false); chatterBaseUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_CHATTER_BASE_URL, serviceRequest.configurationValues, true); adminEmail = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_ADMIN_EMAIL, serviceRequest.configurationValues, true); if (serviceRequest.authorization != null) { Boolean postMade = false; // Get the message from the inputs message = ValueUtils.GetContentValue("Post", serviceRequest.inputs, true); // Check to see if we have any group authorization - if so, we post to those groups if (serviceRequest.authorization.groups != null && serviceRequest.authorization.groups.Count > 0) { foreach (GroupAuthorizationGroupAPI groupAuthorization in serviceRequest.authorization.groups) { // For group posts, we post as the admin, not as the user - as it's very likely the user does not have permissions to post if (groupAuthenticationToken == null || groupAuthenticationToken.Trim().Length == 0) { // Login as the API user sforceService = SalesforceDataSingleton.GetInstance().Login(authenticatedWho, serviceRequest.configurationValues, true, false); if (sforceService == null) { throw new ArgumentNullException("SalesforceService", "Unable to log into Salesforce."); } // Get the session id out as we'll use that for the oauth login groupAuthenticationToken = sforceService.SessionHeaderValue.sessionId; } // Create the endpoint url for the group endpointUrl = chatterBaseUrl + SalesforceServiceSingleton.CHATTER_URI_PART_API_VERSION + String.Format(SalesforceServiceSingleton.CHATTER_URI_PART_POSTS, groupAuthorization.authenticationId); // Create a new chatter post chatterPostedMessage = new ChatterPostedMessage(); chatterPostedMessage.Body = new ChatterNewMessageBody(); chatterPostedMessage.Body.MessageSegments = new List <ChatterSegment>(); // Create a message segment for the actual post chatterNewMessageSegment = new ChatterNewMessageSegment(); chatterNewMessageSegment.Type = ChatterMessageSegmentType.Text.ToString(); chatterNewMessageSegment.Text = message; // Add the segment to the post chatterPostedMessage.Body.MessageSegments.Add(chatterNewMessageSegment); // Post the message synchronously SalesforceSocialSingleton.GetInstance().PostNotification(notifier, authenticatedWho, groupAuthenticationToken, serviceRequest, endpointUrl, serviceRequest.joinPlayerUri, chatterPostedMessage); // Set the flag that we did in fact make a post postMade = true; } } // Check to see if we have any user authorization - if so, we post to those users if (serviceRequest.authorization.users != null && serviceRequest.authorization.users.Count > 0) { // Create the endpoint url endpointUrl = chatterBaseUrl + SalesforceServiceSingleton.CHATTER_URI_PART_API_VERSION + String.Format(SalesforceServiceSingleton.CHATTER_URI_PART_MY_FEED, authenticatedWho.UserId); // Create a new chatter post chatterPostedMessage = new ChatterPostedMessage(); chatterPostedMessage.Body = new ChatterNewMessageBody(); chatterPostedMessage.Body.MessageSegments = new List <ChatterSegment>(); // Create a message segment for the actual post chatterNewMessageSegment = new ChatterNewMessageSegment(); chatterNewMessageSegment.Type = ChatterMessageSegmentType.Text.ToString(); chatterNewMessageSegment.Text = message; // Add the segment to the post chatterPostedMessage.Body.MessageSegments.Add(chatterNewMessageSegment); // Rather than posting to each user, we do a joint post to all of the users that need to be notified foreach (GroupAuthorizationUserAPI userAuthorization in serviceRequest.authorization.users) { ChatterMentionsSegment chatterMentionsSegment = null; chatterMentionsSegment = new ChatterMentionsSegment(); chatterMentionsSegment.Id = userAuthorization.authenticationId; chatterMentionsSegment.Type = ChatterMessageSegmentType.Mention.ToString(); // Add the user to the @mention chatterPostedMessage.Body.MessageSegments.Add(chatterMentionsSegment); } // Post the message synchronously SalesforceSocialSingleton.GetInstance().PostNotification(notifier, authenticatedWho, serviceRequest, endpointUrl, serviceRequest.joinPlayerUri, chatterPostedMessage); // Set the flag that we did in fact make a post postMade = true; } if (postMade == false) { // Alert the admin that no message was sent ErrorUtils.SendAlert(notifier, authenticatedWho, ErrorUtils.ALERT_TYPE_WARNING, "The service request does not have anything in the authorization context, so there's no one to notify."); } } else { // Alert the admin that no one is in the authorization context ErrorUtils.SendAlert(notifier, authenticatedWho, ErrorUtils.ALERT_TYPE_WARNING, "The service request does not have an authorization context, so there's no one to notify."); } // Construct the service response serviceResponse = new ServiceResponseAPI(); serviceResponse.invokeType = ManyWhoConstants.INVOKE_TYPE_FORWARD; serviceResponse.token = serviceRequest.token; serviceResponse.outputs = null; return(serviceResponse); }
public Boolean SendEmail(INotifier notifier, IAuthenticatedWho authenticatedWho, ServiceRequestAPI serviceRequest, Boolean includeTracking) { SforceService sforceService = null; List <String> toEmails = null; Boolean includeOutcomesAsButtons = true; String includeOutcomesAsButtonsString = null; String toEmail = null; String fromEmail = null; String subject = null; String textBody = null; String htmlBody = null; String authenticationUrl = null; String username = null; String password = null; String securityToken = null; String redirectUri = null; // Get the configuration information for salesforce authenticationUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_URL, serviceRequest.configurationValues, true); username = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_USERNAME, serviceRequest.configurationValues, true); password = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_PASSWORD, serviceRequest.configurationValues, true); securityToken = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_SECURITY_TOKEN, serviceRequest.configurationValues, false); // Get the values from the incoming request toEmail = ValueUtils.GetContentValue(SERVICE_VALUE_TO_EMAIL, serviceRequest.inputs, false); fromEmail = ValueUtils.GetContentValue(SERVICE_VALUE_FROM_EMAIL, serviceRequest.inputs, false); subject = ValueUtils.GetContentValue(SERVICE_VALUE_SUBJECT, serviceRequest.inputs, true); textBody = ValueUtils.GetContentValue(SERVICE_VALUE_TEXT_BODY, serviceRequest.inputs, false); htmlBody = ValueUtils.GetContentValue(SERVICE_VALUE_HTML_BODY, serviceRequest.inputs, false); redirectUri = ValueUtils.GetContentValue(SERVICE_VALUE_REDIRECT_URI, serviceRequest.inputs, false); includeOutcomesAsButtonsString = ValueUtils.GetContentValue(SERVICE_VALUE_INCLUDE_OUTCOMES_AS_BUTTONS, serviceRequest.inputs, false); // Create the to emails list toEmails = new List <String>(); // Check to see if we have a value for including outcome buttons if (String.IsNullOrWhiteSpace(includeOutcomesAsButtonsString) == true) { // Default is true includeOutcomesAsButtons = true; } else { includeOutcomesAsButtons = Boolean.Parse(includeOutcomesAsButtonsString); } if (String.IsNullOrWhiteSpace(toEmail) == true) { if (serviceRequest.authorization == null) { throw new ArgumentNullException("ServiceRequest.Authorization", "The ServiceRequest.Authorization property cannot be null as we will not know who to send the email to."); } if (serviceRequest.authorization.groups == null || serviceRequest.authorization.groups.Count == 0) { throw new ArgumentNullException("ServiceRequest.Authorization.Groups", "The ServiceRequest.Authorization.Groups property cannot be null or empty as we will not know who to send the email to."); } if (serviceRequest.authorization.groups.Count > 1) { throw new ArgumentNullException("ServiceRequest.Authorization.Groups", "The ServiceRequest.Authorization.Groups property cannot contain more than one group currently."); } // We need to get the users from salesforce sforceService = SalesforceDataSingleton.GetInstance().Login(authenticatedWho, serviceRequest.configurationValues, true, false); if (sforceService == null) { throw new ArgumentNullException("SalesforceService", "Unable to log into Salesforce."); } // Get the to emails from Salesforce toEmails = SalesforceAuthenticationSingleton.GetInstance().GetGroupMemberEmails(notifier, sforceService, serviceRequest, serviceRequest.authorization.groups[0].authenticationId); if (toEmails == null || toEmails.Count == 0) { throw new ArgumentNullException("ServiceRequest.Authorization.Groups", "The ServiceRequest.Authorization.Groups configuration is not returning any users to send the email to."); } } else { // The user is explicitly setting the to email toEmails.Add(toEmail); } if (includeOutcomesAsButtons == false) { // Null out any outcomes so we don't send them through serviceRequest.outcomes = null; } // Send the actual email this.SendEmail(serviceRequest.configurationValues, fromEmail, toEmails.ToArray(), null, subject, textBody, htmlBody, serviceRequest.token, redirectUri, serviceRequest.outcomes); return(includeOutcomesAsButtons); }
public ServiceResponseAPI InvokeCreateEvent(INotifier notifier, IAuthenticatedWho authenticatedWho, ServiceRequestAPI serviceRequest) { List <ObjectDataTypePropertyAPI> objectDataTypeProperties = null; ServiceResponseAPI serviceResponse = null; DateTime whenDate = DateTime.Now; List <ObjectAPI> eventObjects = null; ObjectAPI eventObject = null; String authenticationUrl = null; String username = null; String password = null; String securityToken = null; String adminEmail = null; String when = null; String duration = null; String description = null; String subject = null; String eventId = null; // Grab the configuration values from the service request authenticationUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_URL, serviceRequest.configurationValues, true); username = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_USERNAME, serviceRequest.configurationValues, true); password = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_PASSWORD, serviceRequest.configurationValues, true); securityToken = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_SECURITY_TOKEN, serviceRequest.configurationValues, false); adminEmail = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_ADMIN_EMAIL, serviceRequest.configurationValues, true); if (serviceRequest.authorization != null) { // Get the message from the inputs when = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_INPUT_WHEN, serviceRequest.inputs, true); duration = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_INPUT_DURATION, serviceRequest.inputs, true); description = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_INPUT_DESCRIPTION, serviceRequest.inputs, true); subject = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_INPUT_SUBJECT, serviceRequest.inputs, true); // Get the when date for the provided command whenDate = DateUtils.CreateDateFromWhenCommand(notifier, authenticatedWho, when, adminEmail); // Set the calendar event for a day in the week at 10am whenDate = DateUtils.GetDayInWeek(whenDate, 10); // Add the link to the flow in the description description += " Link to Flow: " + serviceRequest.joinPlayerUri; // Create a event object to save back to the system eventObject = new ObjectAPI(); eventObject.developerName = "Event"; eventObject.properties = new List <PropertyAPI>(); eventObject.properties.Add(new PropertyAPI() { developerName = "ActivityDateTime", contentValue = whenDate.ToUniversalTime().ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'fffZ") }); eventObject.properties.Add(new PropertyAPI() { developerName = "Description", contentValue = description }); eventObject.properties.Add(new PropertyAPI() { developerName = "DurationInMinutes", contentValue = duration }); eventObject.properties.Add(new PropertyAPI() { developerName = "Subject", contentValue = subject }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsAllDayEvent", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsArchived", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsChild", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsGroupEvent", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsPrivate", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsRecurrence", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsReminderSet", contentValue = "false" }); eventObject.properties.Add(new PropertyAPI() { developerName = "IsVisibleInSelfService", contentValue = "false" }); // Add the object to the list of objects to save eventObjects = new List <ObjectAPI>(); eventObjects.Add(eventObject); // Create the object data type properties for this object so the system knows what we're selecting objectDataTypeProperties = new List <ObjectDataTypePropertyAPI>(); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "ActivityDateTime" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "Description" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "DurationInMinutes" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "Subject" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsAllDayEvent" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsArchived" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsChild" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsGroupEvent" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsPrivate" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsRecurrence" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsReminderSet" }); objectDataTypeProperties.Add(new ObjectDataTypePropertyAPI() { developerName = "IsVisibleInSelfService" }); // Save the event object to salesforce eventObjects = SalesforceDataSingleton.GetInstance().Save(notifier, authenticatedWho, serviceRequest.configurationValues, objectDataTypeProperties, eventObjects); // Check to see if anything came back as part of the save - it should unless there was a fault if (eventObjects != null && eventObjects.Count > 0) { // Grab the first object from the returned event objects eventObject = eventObjects[0]; // Grab the id from that object - this needs to be returned in our outputs eventId = eventObject.externalId; } else { // If we didn't get any objects back, we need to throw an error String errorMessage = "Event could not be created for an unknown reason."; ErrorUtils.SendAlert(notifier, authenticatedWho, ErrorUtils.ALERT_TYPE_FAULT, errorMessage); throw new ArgumentNullException("BadRequest", errorMessage); } } else { // Alert the admin that no one is in the authorization context ErrorUtils.SendAlert(notifier, authenticatedWho, ErrorUtils.ALERT_TYPE_WARNING, "The service request does not have an authorization context, so there's no one to notify."); } // Construct the service response serviceResponse = new ServiceResponseAPI(); serviceResponse.invokeType = ManyWhoConstants.INVOKE_TYPE_FORWARD; serviceResponse.token = serviceRequest.token; serviceResponse.outputs = new List <EngineValueAPI>(); serviceResponse.outputs.Add(new EngineValueAPI() { contentType = ManyWhoConstants.CONTENT_TYPE_STRING, contentValue = eventId, developerName = SalesforceServiceSingleton.SERVICE_OUTPUT_ID }); return(serviceResponse); }
private void Execute(INotifier notifier, String tenantId, String mode, WorkflowRuleNotification workflowRuleNotification) { Dictionary <String, ListenerServiceRequestAPI> salesforceListenerEntries = null; ListenerServiceResponseAPI listenerServiceResponse = null; ListenerServiceRequestAPI listenerServiceRequest = null; SforceService sforceService = null; String authenticationStrategy = null; String authenticationUrl = null; String securityToken = null; String invokeType = null; String username = null; String password = null; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing listener notification."); } // Go through each object identifier in the notification if (workflowRuleNotification.ObjectIDs != null && workflowRuleNotification.ObjectIDs.Count > 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Workflow event has object identifiers."); } foreach (String objectId in workflowRuleNotification.ObjectIDs) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Processing object identifier: " + objectId); } // Check to see if ManyWho has asked us to listen to any of them salesforceListenerEntries = SalesforceListenerSingleton.GetInstance().GetListenerRequests(tenantId, objectId); // Check to see if we're actually listening if (salesforceListenerEntries != null && salesforceListenerEntries.Count > 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Object has listener entries."); } // If it has, send a listen notification back to the workflow engine - one by one at the moment (no bulk!) foreach (KeyValuePair <String, ListenerServiceRequestAPI> pair in salesforceListenerEntries) { // Get the listener request out listenerServiceRequest = pair.Value; if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing listener entry."); } // Create the service response listenerServiceResponse = new ListenerServiceResponseAPI(); listenerServiceResponse.annotations = listenerServiceRequest.annotations; listenerServiceResponse.culture = listenerServiceRequest.culture; listenerServiceResponse.tenantId = listenerServiceRequest.tenantId; listenerServiceResponse.token = listenerServiceRequest.token; // Apply the settings for the response from the request so the engine has the full details about the object listenerServiceResponse.listeningEventValue = listenerServiceRequest.valueForListening; listenerServiceResponse.listeningEventValue.contentType = listenerServiceRequest.valueForListening.contentType; listenerServiceResponse.listeningEventValue.contentValue = listenerServiceRequest.valueForListening.contentValue; listenerServiceResponse.listeningEventValue.developerName = listenerServiceRequest.valueForListening.developerName; listenerServiceResponse.listeningEventValue.typeElementDeveloperName = listenerServiceRequest.valueForListening.typeElementDeveloperName; listenerServiceResponse.listeningEventValue.typeElementId = listenerServiceRequest.valueForListening.typeElementId; listenerServiceResponse.listeningEventValue.typeElementPropertyDeveloperName = listenerServiceRequest.valueForListening.typeElementPropertyDeveloperName; listenerServiceResponse.listeningEventValue.typeElementPropertyId = listenerServiceRequest.valueForListening.typeElementPropertyId; listenerServiceResponse.listeningEventValue.valueElementId = listenerServiceRequest.valueForListening.valueElementId; // Get the configuration values out that are needed to check the voting status // TODO: we should smart cache the login info and connection authenticationUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_URL, listenerServiceRequest.configurationValues, true); username = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_USERNAME, listenerServiceRequest.configurationValues, true); password = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_PASSWORD, listenerServiceRequest.configurationValues, true); securityToken = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_SECURITY_TOKEN, listenerServiceRequest.configurationValues, false); authenticationStrategy = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_AUTHENTICATION_STRATEGY, listenerServiceRequest.configurationValues, false); if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Logging into salesforce using: " + username); } if (String.IsNullOrWhiteSpace(authenticationStrategy) == true || authenticationStrategy.Equals(SalesforceServiceSingleton.AUTHENTICATION_STRATEGY_STANDARD, StringComparison.OrdinalIgnoreCase) == true || authenticationStrategy.Equals(SalesforceServiceSingleton.AUTHENTICATION_STRATEGY_ACTIVE_USER, StringComparison.OrdinalIgnoreCase) == true) { sforceService = SalesforceDataSingleton.GetInstance().LogUserInBasedOnSession(listenerServiceRequest.configurationValues, workflowRuleNotification.SessionID, workflowRuleNotification.SessionURL); } else if (authenticationStrategy.Equals(SalesforceServiceSingleton.AUTHENTICATION_STRATEGY_SUPER_USER, StringComparison.OrdinalIgnoreCase) == true) { // Login to salesforce using the details in the service request sforceService = SalesforceDataSingleton.GetInstance().LoginUsingCredentials(authenticationUrl, username, password, securityToken); } else { throw new ArgumentNullException("ConfigurationValues", String.Format("The provided authentication strategy is not supported: '{0}'", authenticationStrategy)); } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Getting full sObject for: " + objectId); } // Load the latest object from salesforce so we have the data to send back listenerServiceResponse.listeningEventValue.objectData = SalesforceDataSingleton.GetInstance().LoadSObjectByIdentifier(sforceService, workflowRuleNotification.ObjectName, objectId, true); try { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Executing event against ManyWho"); } // Dispatch a listen response to the engine as an event has occurred invokeType = RunSingleton.GetInstance().Event(notifier, null, tenantId, listenerServiceRequest.callbackUri, listenerServiceResponse); } catch (Exception exception) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Event execution failed with: " + BaseHttpUtils.GetExceptionMessage(exception)); } // Something went wrong - but we ignore it for now invokeType = ManyWhoConstants.INVOKE_TYPE_FORWARD; } if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Service returned invoke type of: " + invokeType); } // If the engine returns nothing, errors or returns an response other than a "WAIT", we delete the listener for now // TODO: make this a bit more intelligent so we can handle things like retry if (String.IsNullOrWhiteSpace(invokeType) == false && invokeType.IndexOf(ManyWhoConstants.INVOKE_TYPE_WAIT, StringComparison.InvariantCultureIgnoreCase) < 0) { if (SettingUtils.IsDebugging(mode)) { notifier.AddLogEntry("Removing entry from listeners for invoke type: " + invokeType); } SalesforceListenerSingleton.GetInstance().UnregisterListener(tenantId, objectId, listenerServiceRequest); } } } } } }