public Task<ServiceResponseAPI> Invoke(String actionName, ServiceRequestAPI serviceRequest)
 {
     try
     {
         return DocordoServiceSingleton.GetInstance().Invoke(this.GetWho(), actionName, serviceRequest);
     }
     catch (Exception exception)
     {
         throw ErrorUtils.GetWebException(HttpStatusCode.BadRequest, exception);
     }
 }
 public ServiceResponseAPI Invoke(String actionName, ServiceRequestAPI serviceRequest)
 {
     try
     {
         return(SalesforceServiceSingleton.GetInstance().Invoke(EmailNotifier.GetInstance(this.GetWho(), serviceRequest.configurationValues, "PluginSalesforceController.Invoke"), this.GetWho(), actionName, serviceRequest));
     }
     catch (Exception exception)
     {
         throw BaseHttpUtils.GetWebException(HttpStatusCode.BadRequest, BaseHttpUtils.GetExceptionMessage(exception));
     }
 }
        public async Task<ServiceResponseAPI> InvokeCreateMatter(IAuthenticatedWho authenticatedWho, ServiceRequestAPI serviceRequest)
        {
            ServiceResponseAPI serviceResponse = null;
            DateTime whenDate = DateTime.Now;
            List<ObjectAPI> taskObjects = null;
            ObjectAPI taskObject = null;

            string authenticationUrl = null;
            string username = null;
            string password = null;

            string recordNumber = null;
            string description = null;

            string matterId = null;

            // Grab the configuration values from the service request
            authenticationUrl = SettingUtils.GetConfigurationValue(DocordoServiceSingleton.SERVICE_VALUE_DOCORDO_DOMAIN, serviceRequest.configurationValues, true);
            username = SettingUtils.GetConfigurationValue(DocordoServiceSingleton.SERVICE_VALUE_DOCORDO_USERNAME, serviceRequest.configurationValues, true);
            password = SettingUtils.GetConfigurationValue(DocordoServiceSingleton.SERVICE_VALUE_DOCORDO_PASSWORD, serviceRequest.configurationValues, true);            

            if (serviceRequest.authorization != null)
            {
                // Get the message from the inputs
                recordNumber = ValueUtils.GetContentValue(DocordoServiceSingleton.SERVICE_INPUT_RECORD_NUMBER, serviceRequest.inputs, true);
                description = ValueUtils.GetContentValue(DocordoServiceSingleton.SERVICE_INPUT_MATTER_DESCRIPTION, serviceRequest.inputs, true);

                // Create a task object to save back to the system
                taskObject = new ObjectAPI();
                taskObject.developerName = "Matter";
                taskObject.properties = new List<PropertyAPI>();
                taskObject.properties.Add(new PropertyAPI() { developerName = "RecordNumber", contentValue = description });                
                taskObject.properties.Add(new PropertyAPI() { developerName = "Description", contentValue = description });                

                // Add the object to the list of objects to save
                taskObjects = new List<ObjectAPI>();
                taskObjects.Add(taskObject);
                
                // Save the task object to docordo
                DocordoLoginResponse docordoLoginResponse = DocordoAPI.DocordoService.GetInstance().Login(authenticationUrl, username, password);

                taskObjects = DocordoDataSingleton.GetInstance().CreateMatter(authenticationUrl, docordoLoginResponse.EbikkoSessionId, docordoLoginResponse.CookieJSESSIONID, recordNumber, description);

                // Check to see if anything came back as part of the save - it should unless there was a fault
                if (taskObjects != null &&
                    taskObjects.Count > 0)
                {
                    // Grab the first object from the returned task objects
                    taskObject = taskObjects[0];

                    // Grab the id from that object - this needs to be returned in our outputs
                    matterId = taskObject.externalId;
                }
                else
                {
                    // If we didn't get any objects back, we need to throw an error
                    String errorMessage = "Task could not be created for an unknown reason.";

                    ErrorUtils.SendAlert(authenticatedWho, ErrorUtils.ALERT_TYPE_FAULT, "*****@*****.**", "DocordoPlugin", errorMessage);

                    throw ErrorUtils.GetWebException(HttpStatusCode.InternalServerError, errorMessage);
                }

            }
            else
            {
                // Alert the admin that no one is in the authorization context
                ErrorUtils.SendAlert(authenticatedWho, ErrorUtils.ALERT_TYPE_WARNING, "*****@*****.**", "DocordoPlugin", "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 = matterId, developerName = DocordoServiceSingleton.SERVICE_OUTPUT_ID });

            return serviceResponse;
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
        /// <summary>
        /// This method allows the user to share the flow app in salesforce with their friends.
        /// </summary>
        public MessageAPI PostNotification(INotifier notifier, IAuthenticatedWho authenticatedWho, String oauthToken, ServiceRequestAPI serviceRequest, String endpointUrl, String flowLink, ChatterPostedMessage chatterPostedMessage)
        {
            HttpResponseMessage      httpResponseMessage      = null;
            HttpClient               httpClient               = null;
            MediaTypeFormatter       jsonFormatter            = null;
            MultipartFormDataContent multipartFormDataContent = null;
            ChatterMessage           chatterMessage           = null;
            ChatterAttachmentLink    chatterAttachmentLink    = null;
            MessageAPI               message = null;
            String chatterBaseUrl            = null;
            String adminEmail = null;

            if (oauthToken == null ||
                oauthToken.Trim().Length == 0)
            {
                throw new ArgumentNullException("BadRequest", "OAuthToken cannot be null or blank.");
            }

            if (endpointUrl == null ||
                endpointUrl.Trim().Length == 0)
            {
                throw new ArgumentNullException("BadRequest", "EndpointUrl cannot be null or blank.");
            }

            // Grab the values necessary to post the message over to chatter
            chatterBaseUrl = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_CHATTER_BASE_URL, serviceRequest.configurationValues, true);
            adminEmail     = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_ADMIN_EMAIL, serviceRequest.configurationValues, true);

            // Now we can create the multipart form we're going to post over to salesforce
            multipartFormDataContent = new MultipartFormDataContent();

            if (flowLink != null &&
                flowLink.Trim().Length > 0)
            {
                // We also add the link to the app so the user has it
                chatterAttachmentLink = new ChatterAttachmentLink();
                chatterAttachmentLink.AttachmentType = "Link";
                chatterAttachmentLink.Url            = flowLink;
                chatterAttachmentLink.UrlName        = "Link to ManyWho Flow";

                chatterPostedMessage.Attachment = chatterAttachmentLink;
            }

            // We enclose the request in a for loop to handle http errors
            for (int i = 0; i < SalesforceHttpUtils.MAXIMUM_RETRIES; i++)
            {
                try
                {
                    // Create a new client object
                    httpClient = SalesforceHttpUtils.CreateHttpClient(oauthToken);

                    // Create a new json formatter so the request will be in the right format
                    jsonFormatter = new JsonMediaTypeFormatter();

                    // Use the JSON formatter to create the content of the chatter post
                    multipartFormDataContent.Add(new ObjectContent <ChatterPostedMessage>(chatterPostedMessage, jsonFormatter), "json");

                    // Post the message over to chatter
                    httpResponseMessage = httpClient.PostAsync(endpointUrl, multipartFormDataContent).Result;

                    // Check the status of the response and respond appropriately
                    if (httpResponseMessage.IsSuccessStatusCode)
                    {
                        // Grab the chatter message from the post
                        chatterMessage = httpResponseMessage.Content.ReadAsAsync <ChatterMessage>().Result;

                        // Convert it over to a manywho message
                        message = SalesforceSocialSingleton.GetInstance().ChatterMessageToMessageAPI(chatterBaseUrl, null, chatterMessage);

                        // We successfully executed the request, we can break out of the retry loop
                        break;
                    }
                    else
                    {
                        // Make sure we handle the lack of success properly
                        BaseHttpUtils.HandleUnsuccessfulHttpResponseMessage(notifier, authenticatedWho, i, httpResponseMessage, endpointUrl);
                    }
                }
                catch (Exception exception)
                {
                    // Make sure we handle the exception properly
                    BaseHttpUtils.HandleHttpException(notifier, authenticatedWho, i, exception, endpointUrl);
                }
                finally
                {
                    // Clean up the objects from the request
                    BaseHttpUtils.CleanUpHttp(httpClient, null, httpResponseMessage);
                }
            }

            return(message);
        }
 public MessageAPI PostNotification(INotifier notifier, IAuthenticatedWho authenticatedWho, ServiceRequestAPI serviceRequest, String endpointUrl, String flowLink, ChatterPostedMessage chatterPostedMessage)
 {
     return(PostNotification(notifier, authenticatedWho, SalesforceHttpUtils.GetAuthenticationDetails(authenticatedWho.Token).Token, serviceRequest, endpointUrl, flowLink, chatterPostedMessage));
 }
        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 HttpResponseMessage TaskEmailOutcomeResponse(String token, String selectedOutcomeId, String redirectUri = null)
        {
            IAuthenticatedWho   authenticatedWho = null;
            INotifier           notifier         = null;
            HttpResponseMessage response         = null;
            ServiceResponseAPI  serviceResponse  = null;
            ServiceRequestAPI   serviceRequest   = null;
            String invokeType      = null;
            String responseContent = null;

            try
            {
                if (String.IsNullOrWhiteSpace(token) == true)
                {
                    throw new ArgumentNullException("Token", "The token for the request is null or blank.");
                }

                if (String.IsNullOrWhiteSpace(selectedOutcomeId) == true)
                {
                    throw new ArgumentNullException("SelectedOutcomeId", "The selected outcome for the request is null or blank.");
                }

                // Get the email verification for this tracking code
                serviceRequest = JsonConvert.DeserializeObject <ServiceRequestAPI>(StorageUtils.GetStoredJson(token.ToLower()));

                if (serviceRequest == null)
                {
                    throw new ArgumentNullException("ServiceRequest", "The request has already been processed.");
                }

                // Get the notifier email
                authenticatedWho       = new AuthenticatedWho();
                authenticatedWho.Email = ValueUtils.GetContentValue(SalesforceServiceSingleton.SERVICE_VALUE_ADMIN_EMAIL, serviceRequest.configurationValues, true);

                // Create the notifier
                notifier = EmailNotifier.GetInstance(serviceRequest.tenantId, authenticatedWho, null, "TaskEmailOutcomeResponse");

                // Create the service response to send back to ManyWho based on this outcome click
                serviceResponse                   = new ServiceResponseAPI();
                serviceResponse.invokeType        = ManyWhoConstants.INVOKE_TYPE_FORWARD;
                serviceResponse.tenantId          = serviceRequest.tenantId;
                serviceResponse.token             = serviceRequest.token;
                serviceResponse.selectedOutcomeId = selectedOutcomeId;

                // Invoke the response on the manywho service
                invokeType = RunSingleton.GetInstance().Response(notifier, null, serviceRequest.tenantId, serviceRequest.callbackUri, serviceResponse);

                if (invokeType == null ||
                    invokeType.Trim().Length == 0)
                {
                    throw new ArgumentNullException("ServiceRequest", "The invokeType coming back from ManyWho cannot be null or blank.");
                }

                if (invokeType.IndexOf(ManyWhoConstants.INVOKE_TYPE_SUCCESS, StringComparison.InvariantCultureIgnoreCase) >= 0)
                {
                    // The system has accepted our task email response so the token is now dead - we remove it from storage
                    StorageUtils.RemoveStoredJson(token.ToLower());
                }
                else
                {
                    // The system has not accepted our task email response, so we should simply keep waiting and responding to emails with this task token
                }

                // Tell the user the outcome selection was successful
                responseContent = "Your request has been successfully completed. Please close this window.";

                if (String.IsNullOrWhiteSpace(redirectUri) == false)
                {
                    // Redirect the user as specified
                    response = Request.CreateResponse(HttpStatusCode.RedirectMethod, redirectUri);
                    response.Headers.Add("Location", redirectUri);
                }
                else
                {
                    // Send the user a response page
                    response         = Request.CreateResponse(HttpStatusCode.OK);
                    response.Content = new StringContent(responseContent);
                }
            }
            catch (Exception exception)
            {
                throw BaseHttpUtils.GetWebException(HttpStatusCode.BadRequest, BaseHttpUtils.GetExceptionMessage(exception));
            }

            return(response);
        }
        /// <summary>
        /// This method is used to invoke particular messages on the service.
        /// </summary>
        public async Task<ServiceResponseAPI> Invoke(IAuthenticatedWho authenticatedWho, String action, ServiceRequestAPI serviceRequest)
        {
            System.Diagnostics.Trace.TraceInformation("@start - public async Task<ServiceResponseAPI> Invoke(IAuthenticatedWho authenticatedWho, String action, ServiceRequestAPI serviceRequest)");
            Trace.TraceInformation(JsonConvert.SerializeObject(authenticatedWho));
            Trace.TraceInformation(JsonConvert.SerializeObject(action));
            Trace.TraceInformation(JsonConvert.SerializeObject(serviceRequest));

            ServiceResponseAPI serviceResponse = null;

            if (string.IsNullOrEmpty(action))
            {
                throw ErrorUtils.GetWebException(HttpStatusCode.BadRequest, "Action cannot be null or blank.");
            }

            if (serviceRequest == null)
            {
                throw ErrorUtils.GetWebException(HttpStatusCode.BadRequest, "ServiceRequest cannot be null.");
            }

            if (action.Equals(SERVICE_ACTION_LOGIN, StringComparison.InvariantCultureIgnoreCase) == true)
            {
                serviceResponse = await SalesforceInvokeSingleton.GetInstance().InvokeCreateMatter(authenticatedWho, serviceRequest);
            }
            else
            {
                // We don't have an action by that name
                throw ErrorUtils.GetWebException(HttpStatusCode.BadRequest, "Action cannot be found for name: " + action);
            }

            return serviceResponse;            
        }