Extender: User Inactivity Email
This Extender can be executed in a Data Management step to automate emailing details of an auto-expiring account to the related user.
Imports System
Imports System.Data
Imports System.Data.Common
Imports System.IO
Imports System.Collections.Generic
Imports System.Globalization
Imports System.Linq
Imports Microsoft.VisualBasic
Imports System.Threading
Imports System.Windows.Forms
Imports OneStream.Shared.Common
Imports OneStream.Shared.Wcf
Imports OneStream.Shared.Engine
Imports OneStream.Shared.Database
Imports OneStream.Stage.Engine
Imports OneStream.Stage.Database
Imports OneStream.Finance.Engine
Imports OneStream.Finance.Database
'** IMPORTANT! Update "InactiveEmailNotification" in line below
' with actual name of the Extender business rule you created
Namespace OneStream.BusinessRule.Extender.InactiveEmailNotification
Public Class MainClass
Public Function Main(ByVal si As SessionInfo, ByVal globals As BRGlobals, ByVal api As Object, ByVal args As ExtenderArgs) As Object
'---------------------------------------------------------------------------------------
'Description: User Expiration Warning
'
'Usage: Sends an email to users prior their account auto expire date.
' This Snippet should replace an entire rule as it includes non-standard Imports [Lines 1-18]
'
'Notes: Administrator must set the following values prior to use:
' BusinessRuleName [Line 20]
' EmailConnectionName [Line 58]
' UserWarningThreshold [Line 61]
' EmailTitle [Line 64]
' EmailMessage [Line 68-75]
' EmailList [Line 78]
'
'Created By: OneStream Software
'Date Created: 09-15-2020
'---------------------------------------------------------------------------------------
Try
Select Case args.FunctionType
Case Is = ExtenderFunctionType.Unknown
Me.EmailNotification(si)
Case Is = ExtenderFunctionType.ExecuteDataMgmtBusinessRuleStep
Me.EmailNotification(si)
End Select
Return Nothing
Catch ex As Exception
Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
End Try
End Function
#Region "General Helpers"
Public Sub EmailNotification(ByVal si As SessionInfo)
Try
'Specify the email connection (Defined in Application Server setup)
Dim emailConnectionName As String = "OneStreamEmail"
'Enter number of days prior to user expiration that warning will be sent.
' Email will only be sent if "Remaining Allowed Inactivity" is less than or equal to threshold days.
Dim userWarningThreshold As Double = 20
'Define the the email title to be sent. The value [days] will be updated during processing.
Dim emailTitle As String = "OneStream User ID Expiration - [days] day warning"
'Define the the email body to be sent.
' [user] & [days] will automatically be replaced, during processing,
' with the OneSteam Username & number of days till expiration.
Dim emailMessage As New Text.StringBuilder
emailMessage.AppendLine("Attention: [user]")
emailMessage.AppendLine("")
emailMessage.AppendLine("Your login for OneStream will expire in [days] due to inactivity."
emailMessage.AppendLine("Please login as soon as possible.")
emailMessage.AppendLine("")
' replace xxx in text below with relevant email address
emailMessage.AppendLine("If you require assistance, please contact xxxx .")
emailMessage.AppendLine("")
emailMessage.AppendLine("Thank you.")
emailMessage.AppendLine("The Support Team")
'Define any additional email addresses to include other than the user that is expiring.
' All emails will be listed in the "To: field" of the email.
Dim emailList As New List(Of String)
' Uncomment following lines if necessary and update with relevant addresses.
'emailList.Add("emailaddress1@customer.com")
'emailList.Add("emailaddress2@customer.com")
' If you need more addresses, just add more lines like the ones above
'Account Expiration Warning
Me.ValidateUserExpiration(si, emailConnectionName, _
userWarningThreshold, emailTitle, emailMessage.ToString, emailList)
Catch ex As Exception
Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
End Try
End Sub
Public Sub ValidateUserExpiration(ByVal si As SessionInfo, ByVal emailConnectionName As String, _
ByVal userWarningThreshold As Double, ByVal emailTitle As String,
ByVal emailMessage As String, ByVal emailList As List(Of String))
Try
Dim dtResults As New DataTable
Using dbConnApp As DbConnInfo = BRAPi.Database.CreateApplicationDbConnInfo(si)
Dim ds As DataSet = BRApi.Database.ExecuteMethodCommand( _
dbConnApp, XFCommandMethodTypeID.Users, "{}", "Users", Nothing)
If Not ds Is Nothing Then
Dim dt As DataTable = ds.Tables(0).Copy
Dim userID As Guid = Guid.Empty
Dim userName As String = String.Empty
Dim remainingDays As Double = 0
Dim updatedEmailList As New List(Of String)
Dim updatedEmailTitle As String = String.Empty
Dim updatedEmailMessage As String = String.Empty
Dim objUserInfoAndStatus As UserInfoAndStatus = BRApi.Security.Admin.GetUserAndStatus( _
si, si.UserName)
For Each dr As DataRow In dt.Rows
'Filter out inactive users and users without a defined email address
If(dr(4).ToString().XFContainsIgnoreCase("TRUE")) And (Not String.IsNullOrEmpty(dr(7).ToString)) Then
'Get UserName and UserInfoAndStatus
userName = dr(1)
objUserInfoAndStatus = BRApi.Security.Admin.GetUserAndStatus(si, userName)
If objUserInfoAndStatus.LogonStatus.GetNumDaysOfRemainingAllowedInactivity <= userWarningThreshold Then
remainingDays = objUserInfoAndStatus.LogonStatus.GetNumDaysOfRemainingAllowedInactivity
'Reset email list for next user
updatedemailList.Clear
updatedemailList.AddRange(emailList)
'Add user to email list
updatedemailList.Add(dr(6).ToString)
'Replace [days] & [user] values in email EmailTitle and EmailMessage
updatedEmailTitle = emailTitle.Replace( _
"[days]", ConvertHelper.ToInt32(remainingDays))
updatedEmailMessage = emailMessage.Replace( _
"[days]", ConvertHelper.ToInt32(remainingDays))
updatedEmailMessage = updatedEmailMessage.Replace( _
"[user]", userName)
'Send the email using a worker background thread
Dim mailThread As New SendMailThread(si, _
emailConnectionName, updatedemailList, _
updatedEmailTitle, updatedEmailMessage, Nothing)
mailThread.Start
End If
End If
Next
End If
End Using
Catch ex As Exception
Throw ErrorHandler.LogWrite(si, New XFException(si, ex))
End Try
End Sub
#End Region
#Region "Constants and Enumerations"
'String Messages
Public m_MsgNoEmailConnection As String = "Cannot Send Notifications: Email Connection must be specified."
#End Region
Public Class SendMailThread
#Region "Module Level Variables"
Private Const m_ThreadNamePrefix As String = "XF Send Mail Thread"
Private m_SI As SessionInfo = Nothing
Private m_MailConnectionName As String = String.Empty
Private m_ToEmailAddresses As New List(Of String)
Private m_Subject As String = String.Empty
Private m_Body As String = String.Empty
Private m_AttachmentFilePaths As New List(Of String)
Private m_WorkerThread As Thread
#End Region
#Region "Constructor"
Public Sub New(ByVal si As SessionInfo, ByVal mailConnectionName As String, _
ByVal toEmailAddresses As List(Of String), ByVal subject As String, _
ByVal body As String, ByVal attachmentFilePaths As List(Of String))
'Copy the input parameters so the background thread can access them.
m_SI = si
m_MailConnectionName = mailConnectionName
m_ToEmailAddresses = toEmailAddresses
m_Subject = subject
m_Body = body
m_AttachmentFilePaths = attachmentFilePaths
End Sub
#End Region
#Region "Public Methods"
Public Sub Start()
Try
'Create the Background Thread
m_WorkerThread = New Thread(AddressOf Me.WorkerThreadMethod)
'We don't want this worker thread to keep the process from being shut down.
m_WorkerThread.IsBackground = True
'Naming thread to provide a unique recognizable marker when debugging.
m_WorkerThread.Name = m_ThreadNamePrefix & " " & Guid.NewGuid().ToString("N")
XFWcfOperationInvoker.SetCultureInfoForUserToThread(m_SI, m_WorkerThread)
m_WorkerThread.Start()
Catch ex As Exception
Throw ErrorHandler.LogWrite(m_SI, New XFException(m_SI, ex))
End Try
End Sub
#End Region
#Region "Private Methods"
Private Sub WorkerThreadMethod()
Try
'Send the email
BRApi.Utilities.SendMail(m_SI, m_MailConnectionName, m_ToEmailAddresses, m_Subject, m_Body, m_AttachmentFilePaths)
Catch ex As Exception
'Important: do not re-throw the exception from this worker thread since it will be processed by .NET as an unhandled exception.
'Even if an exception could be processed normally, it couldn't be sent back to the client via WCF because the client isn't
'waiting for a WCF method to complete and the client might not not even be logged on anymore.
Try
BRApi.ErrorLog.LogError(m_SI, ex)
Catch
End Try
End Try
End Sub
#End Region
End Class
End Class
End Namespace
Updated 2 years ago
Version 3.0