AdhocAdam / smletsexchangeconnector

SMLets PowerShell based Exchange Connector for controlling Microsoft System Center Service Manager 2016+
https://adhocadam.github.io/smletsexchangeconnector/
GNU General Public License v3.0
29 stars 19 forks source link

Submit Requests on Behalf of other users #31

Closed AdhocAdam closed 1 year ago

AdhocAdam commented 6 years ago

Introduce a mechanism to submit requests on behalf of others. This addresses 2 to 3 different scenarios:

TomH-OpsDev commented 6 years ago

Just jotting down ideas...

I am envisioning this as a keyword/token such as [For:otherPerson@mycompany.com].

Or perhaps it would be better to use the username instead of email address (especially for companies where the email address might or might not contain formal/nicknames)? e.g.: [For:myDomain\user123]

Is there a better/cleaner/easier way than this, possibly?

AdhocAdam commented 6 years ago

I struggle with this as well, since it seems open to fat fingering on a mobile device. I was thinking of possibly doing something with CC (since all clients auto-complete) and then using the aforementioned keyword.

This also seemed error prone, but again - just jotting ideas down.

TomH-OpsDev commented 6 years ago

Agree with the advantage of autocomplete and challenges of typing on mobile (and the dreaded autocorrect...)

I thought about suggesting CC also, for some of the same reasons, but I see a lot of emails come to Service Manager with many people already CC'ed. Perhaps if the CC was used in combination with a [token] of some kind and users of it would know that the first/only name in the CC is becomes the affected user, that could work.

In the end, we may just need to pick one and make some process/documentation suggestions.

AdhocAdam commented 6 years ago

I think we're both overlooking something potentially obvious here, what if we enable [take] (and in turn other keywords) on New Work Item creation? And if we couple this in turn with your change to the take functionality #27...

While it increases the scope of New-WorkItem it may allow us to address this without introducing a new keyword for an "update" scenario and a different one for a "new" scenario. Then back to our previous point on CC - the first user identified CC-ed or even To that isn't Service Manager becomes the Affected User. Leveraging [take] the Sender then becomes the Assigned To. All other users become related users per routine CI attachment.

Jeff-Lang commented 6 years ago

I've been thinking about this myself for the last few days, i think the affected user should by default always be the sender. although Only IF using a token in the email eg [take] should it then change the affected user to either another "To" or "CC" . Since the majority of the times i have seen others CC'd on a email to Service Manager, they were just letting those other people know about the issue in the same email.

What i think would be also beneficial to this, is to have an option to add all people in the TO or CC field to the Watch List for the workitem, so if they look in the portal, that can see the workitem and see what is happening if anything.

TomH-OpsDev commented 6 years ago

I agree that many emails about tickets often have additional people CC'ed only for FYI purposes. I love the idea of adding them to the watchlist (optional).

AdhocAdam commented 6 years ago

Second. Great use case here @Jeff-Lang !

Created feature request #34 on integrating with Cireson SCSM Portal Watchlist.

AdhocAdam commented 4 years ago

Since most mobile mail clients feature a "Directory Lookup" action, I'm relying on its use to prevent fat fingering here. Given Directory Lookup, this feature would introduce a new configurable keyword e.g [for] and require some modification to the New-WorkItem function that seems doable. Take the following scenarios:

Scenario 1 = Two users

To: Service Manager Cc: User1 Body: This is [for] another person Logic: If even to the To and Cc were swapped or both part of a single Recipient array - Given the presence of the [for] token and that there are only 2 users on the email, get the one that isn't the SCSM mailbox and make it the Affected User. The sender becomes the Assigned To.

Scenario 2 = Three or more users

To: Service Manager, User1, User2, User3 Cc: User4, User5, User6 Body: This is [for] another person Logic: Given the presence of the [for] token, get the user that immediately follows SCSM in whichever recipient array. In this case User1 becomes the Affected User. The rest of the Users become Related Users and the Sender becomes the Assigned To.

Scenario 3 = Three or more users that emphasize Scenario 2 logic

To: User1, Service Manager, User2, User3 Cc: User4, User5, User6 Body: This is [for] another person Logic: Given the presence of the [for] token, get the user that immediately follows SCSM in whichever recipient array. In this case User2 becomes the Affected User. The rest of the Users become Related Users and the Sender becomes the Assigned To.

Scenario 4 = Three or more users that emphasizes Scenario 2+3 logic plus error handling

To: User1, User2, User3 Cc: User4, User5, User6, Service Manager Body: This is [for] another person Logic: Given the presence of the [for] token, get the user that precedes SCSM in whichever recipient array. In this case User6 becomes the Affected User. The rest of the Users become Related Users and the Sender becomes the Assigned To.

Scenario 5 = Single To, Many Cc (supports the inverse of Many To, single CC)

To: Service Manager Cc: User1, User2, User3, Body: This is [for] another person Logic: Given the presence of the [for] token, get the first user in the To or Cc Recipients (whichever is the many). In this case User1 becomes the Affected User. The rest of the Users become Related Users and the Sender becomes the Assigned To.

But in any case, let's say someone gets it wrong and meant to set a different Affected User. Since the Work Item is Assigned to them and all users are Related, they'd have to swap relationships around once they were back at their desk. While this may be less than ideal, I'd like to think this is the best chance at addressing this request. Additionally, this would need to be integrated with Multi-Mailbox functionality so the right template was applied for the User sending the Work on behalf of another user. Finally, controlling Support Group logic could get tricky if the user is part of multiple groups as there isn't a concept of a "primary group"

AdhocAdam commented 4 years ago

First pass at the above logic. This would introduce about 100 lines to the New-WorkItem function near it's initial declaration (before or after testing the description length?). The configurable [for] keyword would be tested, else the connector would assume normal processing as it exists today. Multi-mailbox support is also present here using variables as defined in v1 and v2 of the connector. Thus the only new configuration variable that needs to be introduced is the new [for] keyword.

Second to this core logic, is a subsequent test post Work Item creation that performs the assignment from the sender. Would probably leverage the Add-ActionLogEntry function so the Action Log shows the Assignment task as having been performed. Would also set the From/Sender as the Created By.

#logic for controlling Creating Work on Behalf of someone else - Determine Affected and Related users with [for] keyword
if (($description -match '\[for+\]') -and ($to.Count + $cced.Count -ge 2))
{
    #[for] token behavior, generate the Affected and Related Users
    if ($to.Count + $cced.Count -eq 2)
    {
        #there are only two users in the email, determine which isn't the SCSM mailbox
        $allRecipients = $message.ToRecipients + $message.CcRecipients
        #if the multi-mailbox feature is being used check all possible addresses, else just check the primary workflow address
        if (($UseMailboxRedirection) -and ($Mailboxes.Count -ge 1))
        {
            $mailboxesArray = @($Mailboxes.Keys) + $workflowEmailAddress
            $affectedUserEmail = $allRecipients | ?{$mailboxesArray -notcontains $_.address.tolower()} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
        else
        {
            $affectedUserEmail = $allRecipients | ?{$_.address.tolower() -ne $workflowEmailAddress.ToLower()} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
    }
    elseif (($to.Count + $cced.Count -ge 3))
    {
        #there is some larger combination of users, find in which Recipient array the SCSM Mailbox exists
        #if the multi-mailbox feature is being used check all possible addresses, else just check the primary workflow address
        if (($UseMailboxRedirection) -and ($Mailboxes.Count -ge 1))
        {
            $mailboxesArray = @($Mailboxes.Keys) + $workflowEmailAddress
            $scsmMailboxInToRecipients = $message.ToRecipients | ?{$mailboxesArray -contains $_.Address.ToLower()}
            $scsmMailboxInCcRecipients = $message.CcRecipients | ?{$mailboxesArray -contains $_.Address.ToLower()}
        }
        else
        {
            $scsmMailboxInToRecipients = $message.ToRecipients.Address.ToLower() -contains $workflowEmailAddress.ToLower()
            $scsmMailboxInCcRecipients = $message.CcRecipients.Address.ToLower() -contains $workflowEmailAddress.ToLower()
        }

        #1 user in ToRecipients and it's the SCSM mailbox, make the first Cc user the Affected User
        #The rest of the CcRecipients become Related Users
        if (($scsmMailboxInToRecipients -and $to.Count -eq 1) -and ($cced.Count -ge 1))
        {
            $affectedUserEmail = $message.CcRecipients[0].Address
            $relatedUsersEmail = $message.ToRecipients + $message.CcRecipients | ?{$_.Address -ne $affectedUserEmail} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $relatedUsers = $relatedUsersEmail | %{Get-SCSMUserByEmailAddress -EmailAddress $_}
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
        #2 users in the ToRecipients, one of them is the SCSM Mailbox, make the other Affected User
        #CcRecipients become Related Users
        if ($scsmMailboxInToRecipients -and $to.Count -eq 2)
        {
            $affectedUserEmail = $message.ToRecipients | ?{$_.address.tolower() -ne $workflowEmailAddress.ToLower()} | select-object address -ExpandProperty address
            $relatedUsersEmail = $message.ToRecipients + $message.CcRecipients | ?{$_.Address -ne $affectedUserEmail} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $relatedUsers = $relatedUsersEmail | %{Get-SCSMUserByEmailAddress -EmailAddress $_}
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
        #3 or more users in the ToRecipients, one of them is the SCSM Mailbox, make the one next in the array after it of it the Affected User
        #make the remaining To and Cc Recipients Related Users
        elseif ($scsmMailboxInToRecipients -and $to.Count -ge 3)
        {
            #if the SCSM Mailbox is last, get the ToRecipient before it (-1) in the array
            $scsmMailboxIndex = $message.ToRecipients.Address.ToLower().IndexOf($workflowEmailAddress.ToLower())
            if ($message.ToRecipients.Address[$scsmMailboxIndex+1]) {$affectedUserEmail = $message.ToRecipients.Address[$scsmMailboxIndex+1]}
            else {$affectedUserEmail = $message.ToRecipients.Address[$scsmMailboxIndex-1]}
            $relatedUsersEmail = $message.ToRecipients + $message.CcRecipients | ?{$_.Address -ne $affectedUserEmail} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $relatedUsers = $relatedUsersEmail | %{Get-SCSMUserByEmailAddress -EmailAddress $_}
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
        #1 user in CcRecipients and it's the SCSM mailbox, make the first To user the Affected User
        #The rest of the CcRecipients become Related Users
        elseif (($scsmMailboxInCcRecipients -and $cced.Count -eq 1) -and ($to.Count -ge 1))
        {
            $affectedUserEmail = $message.ToRecipients[0].Address
            $relatedUsersEmail = $message.ToRecipients + $message.CcRecipients | ?{$_.Address -ne $affectedUserEmail} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $relatedUsers = $relatedUsersEmail | %{Get-SCSMUserByEmailAddress -EmailAddress $_}
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
        #2 users in the CcRecipients, one of them is the SCSM Mailbox, make the other Affected User
        #ToRecipients become Related Users
        elseif ($scsmMailboxInCcRecipients -and $cced.Count -eq 2)
        {
            $affectedUserEmail = $message.CcRecipients | ?{$_.address.tolower() -ne $workflowEmailAddress.ToLower()} | select-object address -ExpandProperty address
            $relatedUsersEmail = $message.ToRecipients + $message.CcRecipients | ?{$_.Address -ne $affectedUserEmail} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $relatedUsers = $relatedUsersEmail | %{Get-SCSMUserByEmailAddress -EmailAddress $_}
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
        #3 or more users in the CcRecipients, one of them is the SCSM Mailbox, make the one next in the array after it of it the Affected User
        #make the remaining To and Cc Recipients Related Users
        elseif ($scsmMailboxInCcRecipients -and $cced.Count -ge 3)
        {
            #if the SCSM Mailbox is last, get the CcRecipient before it (-1) in the array
            $scsmMailboxIndex = $message.CcRecipients.Address.ToLower().IndexOf($workflowEmailAddress.ToLower())
            if ($message.ToRecipients.Address[$scsmMailboxIndex+1]) {$affectedUserEmail = $message.ToRecipients.Address[$scsmMailboxIndex+1]}
            else {$affectedUserEmail = $message.ToRecipients.Address[$scsmMailboxIndex-1]}
            $relatedUsersEmail = $message.ToRecipients + $message.CcRecipients | ?{$_.Address -ne $affectedUserEmail} | select-object address -ExpandProperty address
            $affectedUser = Get-SCSMUserByEmailAddress -EmailAddress $affectedUserEmail
            $relatedUsers = $relatedUsersEmail | %{Get-SCSMUserByEmailAddress -EmailAddress $_}
            $createdByUser = Get-SCSMUserByEmailAddress -EmailAddress $from
        }
    }
}