Ejemplo n.º 1
0
        public void SendNotification(Guid SubscriptionId, string[] DataItems, string InstanceId, string[] TemplateIds, string[] PrimaryUserGuids, ActivityExecutionContext executionContext)
        {
            NotifyUser notice = new NotifyUser();

            notice.SubscriptionId  = SubscriptionId;
            notice.DataItems       = DataItems;
            notice.InstanceId      = InstanceId;
            notice.TemplateIds     = TemplateIds;
            notice.PrimaryUserList = PrimaryUserGuids;

            notice.Execute(executionContext);
        }
Ejemplo n.º 2
0
        //execute the Workflow to Notify the Assigned User
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext TTUExecutionContext)
        {
            //since workflows only run on the workflow server, we can safely
            //connect and execute against the localhost
            EnterpriseManagementGroup emg = new EnterpriseManagementGroup("localhost");

            //Get the classes we need to work with

            /*
             *  get-scsmclass -name "System.WorkItem.TroubleTicket.AnalystCommentLog" | select name, id
             *  get-scsmclass -name "System.WorkItem.TroubleTicket.UserCommentLog" | select name, id
             *  get-scsmrelationshipclass -name "System.WorkItem.TroubleTicketHasAnalystComment" | select name, id
             * https://github.com/SMLets/SMLets/blob/55f1bac3bc7a7011a461b24f6d7787ba89fe2624/SMLets.Shared/Code/EntityTypes.cs#L120
             * https://github.com/SMLets/SMLets/blob/55f1bac3bc7a7011a461b24f6d7787ba89fe2624/SMLets.Shared/Code/EntityTypes.cs#L161
             */
            ManagementPackClass        UserCommentClass  = emg.EntityTypes.GetClass(new Guid("a3d4e16f-5e8a-18ba-9198-d9815194c986"));
            ManagementPackClass        UserClass         = emg.EntityTypes.GetClass(new Guid("943d298f-d79a-7a29-a335-8833e582d252"));
            ManagementPackClass        LocalizationClass = emg.EntityTypes.GetClass(new Guid("efa8bbd3-3fa4-2f37-d0d5-7a6bf53be7c8"));
            ManagementPackRelationship TroubleTicketHasUserCommentRelClass = emg.EntityTypes.GetRelationshipClass(new Guid("ce423786-16dd-da9c-fb7b-21ab5189e12b"));
            ManagementPackRelationship AssignedUserRelClass      = emg.EntityTypes.GetRelationshipClass(new Guid("15e577a3-6bf9-6713-4eac-ba5a5b7c4722"));
            ManagementPackRelationship UserHasPreferenceRelClass = emg.EntityTypes.GetRelationshipClass(new Guid("649e37ab-bf89-8617-94f6-d4d041a05171"));

            //Get the Template GUID from the Translate MP
            EnterpriseManagementObject emoAdminSetting = emg.EntityObjects.GetObject <EnterpriseManagementObject>(new Guid("49a053e7-6080-e211-fd79-ca3607eecce7"), ObjectQueryOptions.Default);
            string templateID = emoAdminSetting[null, "TroubleTicketUserCommentTemplate"].Value.ToString();
            bool   isAzureTranslateEnabled;

            try { isAzureTranslateEnabled = Boolean.Parse(emoAdminSetting[null, "EnableAzureTranslate"].ToString()); }
            catch { isAzureTranslateEnabled = false; }

            //get the objects we'll need to work with starting with...
            //Comment object, the string/guid is an incoming parameter from the management pack
            //$commentObject = Get-SCSMObject -id "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            Guid CommentGuid = new Guid(this.InstanceIds[0].ToString());
            EnterpriseManagementObject CommentObject = emg.EntityObjects.GetObject <EnterpriseManagementObject>(CommentGuid, ObjectQueryOptions.Default);

            //Comment and Work Item relationship object
            //Using SMLets' Get-SCSMRelationshipObject -ByTarget parameter: https://github.com/SMLets/SMLets/blob/55f1bac3bc7a7011a461b24f6d7787ba89fe2624/SMLets.Shared/Code/EntityObjects.cs#L1853
            //$WorkItemActionLogRelObject = Get-SCSMRelationshipObject -ByTarget $commentObject | ?{$_.relationshipid -eq "835a64cd-7d41-10eb-e5e4-365ea2efc2ea"}
            IList <EnterpriseManagementRelationshipObject <EnterpriseManagementObject> > CommentWorkItemRelObjects  = emg.EntityObjects.GetRelationshipObjectsWhereTarget <EnterpriseManagementObject>(CommentObject.Id, ObjectQueryOptions.Default);
            EnterpriseManagementRelationshipObject <EnterpriseManagementObject>          WorkItemActionLogRelObject = null;

            foreach (EnterpriseManagementRelationshipObject <EnterpriseManagementObject> relObject in CommentWorkItemRelObjects)
            {
                //if the relationship object has an ID that is the TroubleTicketHasUserCommentRelClass, then update the variable above with it
                if (relObject.RelationshipId.ToString() == TroubleTicketHasUserCommentRelClass.Id.ToString())
                {
                    //we now have the relationship object that contains the Comment and the Work Item
                    WorkItemActionLogRelObject = relObject;
                    break;
                }
            }

            //if the WorkItemActionLogRelObject is empty, we have a Service Request
            //end this workflow and let the other carry out
            if (WorkItemActionLogRelObject == null)
            {
                return(base.Execute(TTUExecutionContext));
            }

            //Work Item object
            //Get-SCSMObject -id $WorkItemActionLogRelObject.SourceObject.Id
            EnterpriseManagementObject WorkItem = emg.EntityObjects.GetObject <EnterpriseManagementObject>(WorkItemActionLogRelObject.SourceObject.Id, ObjectQueryOptions.Default);

            //Assigned User relationship object
            IList <EnterpriseManagementRelationshipObject <EnterpriseManagementObject> > WorkItemRelUsers = emg.EntityObjects.GetRelationshipObjectsWhereSource <EnterpriseManagementObject>(WorkItem.Id, TraversalDepth.Recursive, ObjectQueryOptions.Default);
            EnterpriseManagementObject AssignedUser = null;

            foreach (EnterpriseManagementRelationshipObject <EnterpriseManagementObject> relObject in WorkItemRelUsers)
            {
                //if the relationship object has an ID that is the Assigned User and it isn't an old (isDeleted) user, then update the variable above with it
                if ((relObject.RelationshipId == AssignedUserRelClass.Id) && (relObject.IsDeleted == false))
                {
                    //we now have the relationship object that contains the Assigned User
                    AssignedUser = relObject.TargetObject;
                    break;
                }
            }

            //if the Assigned User exists, try and retrieve their Locale
            if (AssignedUser != null)
            {
                //Try to retrieve the Assigned User's Locale
                //Affected User's Preference relationship objects
                //https://github.com/SMLets/SMLets/blob/55f1bac3bc7a7011a461b24f6d7787ba89fe2624/SMLets.Shared/Code/EntityObjects.cs#L2775
                //Get-SCSMRelatedObject -SMObject AffectedUser
                EnterpriseManagementObject AssignedUserLocale = null;

                //get the Assigned User's locale
                IList <EnterpriseManagementObject> AssignedUserPreferences = emg.EntityObjects.GetRelatedObjects <EnterpriseManagementObject>(AssignedUser.Id, TraversalDepth.OneLevel, ObjectQueryOptions.Default);
                foreach (EnterpriseManagementObject preference in AssignedUserPreferences)
                {
                    if (preference.GetClasses()[0].Name == "System.UserPreference.Localization")
                    {
                        AssignedUserLocale = preference;
                        break;
                    }
                }

                //check if the Assigned User has a defined Locale, if they do and Azure Translate is enabled we can go ahead with a comparison.
                if ((AssignedUserLocale != null) && (isAzureTranslateEnabled))
                {
                    //get the Assigned User's locale
                    string AssignedUserLocaleCode = AssignedUserLocale[(ManagementPackType)LocalizationClass, "LocaleID"].Value.ToString();

                    //get the Assigned User's language code
                    //PowerShell equivalent:
                    //[System.Globalization.Cultureinfo]::GetCultureInfo(LocaleCode).TwoLetterISOLanguageName
                    string AssignedUserLangCode = System.Globalization.CultureInfo.GetCultureInfo(int.Parse(AssignedUserLocaleCode)).TwoLetterISOLanguageName.ToString().ToLower();

                    //now we need determine the language of the comment that was left
                    //first, grab the Comment object and it's actual comment that was left
                    //second, grab the person who entered the comment
                    string CommentText = CommentObject[(ManagementPackType)UserCommentClass, "Comment"].Value.ToString();
                    string EnteredBy   = CommentObject[(ManagementPackType)UserCommentClass, "EnteredBy"].Value.ToString();
                    int    CommentFirstSentencePeriod = CommentText.IndexOf(".");

                    //use a period to try to find the end of the first sentence to save on Azure spend
                    //second, make the call to the Azure Translate class in this project to Detect the language code of the comment
                    AzureCognitiveServicesTranslate languageManipulation = new AzureCognitiveServicesTranslate();
                    string CommentLangCode                    = null;
                    string CommentLangDetectSample            = null;
                    int    CommentLangDetectSamplePeriodIndex = CommentText.IndexOf(".");
                    try
                    {
                        CommentLangDetectSample = CommentText.Substring(0, CommentLangDetectSamplePeriodIndex);
                    }
                    catch
                    {
                        CommentLangDetectSample = CommentText;
                    }

                    if (CommentLangDetectSample.Length > 1)
                    {
                        CommentLangCode = languageManipulation.LanguageDetect(emg, CommentLangDetectSample);
                    }
                    else
                    {
                        CommentLangCode = languageManipulation.LanguageDetect(emg, CommentText);
                    }

                    //if the detected Comment Language is different than that of the Assigned User then...
                    //translate, leave the translated comment on the Action Log, notify on the new translated entry
                    //this if statement would compare as seen below:
                    //if ("en" != "es")
                    if (CommentLangCode != AssignedUserLangCode)
                    {
                        //different languages
                        //translate with Azure
                        string translatedComment = languageManipulation.LanguageTranslate(emg, CommentLangCode, AssignedUserLangCode, CommentText);

                        //create a New translated User Comment via projection/function from Rob Ford on TechNet
                        //https://social.technet.microsoft.com/Forums/WINDOWS/en-US/1f06e71c-00f4-4cf7-9f7e-a9a78b4b907c/creating-action-log-entry-for-incident-via-sdk-in-c?forum=customization
                        AddActionLogEntry newComment     = new AddActionLogEntry();
                        string            newCommentGuid = newComment.AddToActionLog(emg, WorkItem, translatedComment, EnteredBy, "UserCommentLog");

                        //notify on the new comment using the recently created comment's guid instead of the one that came in from the workflow parameter
                        NotifyUser notification = new NotifyUser();
                        notification.SendNotification(this.SubscriptionId, this.DataItems, newCommentGuid, new String[] { templateID }, new String[] { AssignedUser.Id.ToString() }, TTUExecutionContext);
                    }
                    else
                    {
                        //same language
                        //notify on the original comment
                        NotifyUser notification = new NotifyUser();
                        notification.SendNotification(this.SubscriptionId, this.DataItems, this.InstanceIds[0].ToString(), new String[] { templateID }, new String[] { AssignedUser.Id.ToString() }, TTUExecutionContext);
                    }
                }
                else
                {
                    //the Affected user doesn't have a locale or Azure Translate isn't enabled, just notify them
                    //notify the User
                    NotifyUser notification = new NotifyUser();
                    notification.SendNotification(this.SubscriptionId, this.DataItems, this.InstanceIds[0].ToString(), new String[] { templateID }, new String[] { AssignedUser.Id.ToString() }, TTUExecutionContext);
                }
            }
            else
            {
                //the assigned user doesn't exist, so there isn't anyone to notify
            }

            return(base.Execute(TTUExecutionContext));
        }