AlertUser API
This API is used to contact the IPF portals from a third-party application and start a session. The API creates a new temporary session in memory and runs custom code under a mapped portal user account. For example, you could use this alert to send rich-HTML portal email based on back office actions, such as order entry. When an order is placed in the back office, the application can contact the Customer Portal, and the Customer Portal can send out an order verification email message.
This API has four signatures:
- void AlertUser(string userId, IPFEventI e)
- void AlertUser(string userId, string eventName)
- void AlertUser(string userId, IPFEventI e, int LCID)
- void AlertUser(string userId, string eventName, int LCID)
userId: The IPF user under which the custom code is executed.
e / eventName: The payload to be delivered to the custom code, either a full event with variables, or simply a name.
LCID: The Microsoft locale ID used when the alert is handled on the target portal. If the LCID is invalid or not supplied, then the target portal's default locale is used.
This API throws exceptions if either of these is true:
- userId is null, empty, does not refer to a valid IPF user, or the calling user does not have permission to run custom code under the userId's account. See the next section for details.
- e is null
OnUserAlert handler
After a logged-in user has been alerted, the custom code is run under the given user. This custom code is located in the portal's user-authenticated script. The UserAuthenticated event fires, and any handlers connected to this event will execute, just like any other user logging in to the portal. If access has been granted, then the OnUserAlert event fires, and any handlers connected to this event will execute. These handlers have this signature:
- OnUserAlerted(ByVal context As SessionUserAlertContextI, ByVal parms As SessionUserAlertParmsI)
context: Gives access to the same level of functionality as the SessionUserAuthenticatedContext, essentially leaving out alerts and any functionality having to do with layouts and rendering.
parms: Contains information having to do with the AlertUser request:
- IPFEventI Event: The payload of the alert.
- String FromUser: The IPF user who initiated the alert.
Calling from a third-party application
The AlertUser API is used by portal users who are already logged in, however, the same action can be taken by outside applications, such as . By calling the AlertUser web service available in the portal, outside applications can get the same result from outside the portal.
A third-party application should contain the following code in a separate VB file in its Visual Studio project. In order for this code to be compiled, the .NET assembly 'System.ServiceModel' must be added as a reference to the project.
Option Strict On
Option Explicit On
Imports System
Imports System.Runtime.Serialization
Imports System.ServiceModel
Namespace IPFAlertService
Public Class AlertServiceClient
Public Sub New(ByVal portalURL As String)
_portalURL = portalURL
Dim MAXSIZE As Integer = Int32.MaxValue
Dim binding As BasicHttpBinding = New BasicHttpBinding()
binding.MessageEncoding = WSMessageEncoding.Text
binding.MaxBufferSize = MAXSIZE
binding.MaxReceivedMessageSize = MAXSIZE
binding.SendTimeout = New TimeSpan(0, 10, 0)
binding.ReceiveTimeout = New TimeSpan(0, 10, 0)
Dim readerQuotasDictionary As System.Xml.XmlDictionaryReaderQuotas
= New System.Xml.XmlDictionaryReaderQuotas()
readerQuotasDictionary.MaxStringContentLength = MAXSIZE
readerQuotasDictionary.MaxArrayLength = MAXSIZE
readerQuotasDictionary.MaxDepth = MAXSIZE
readerQuotasDictionary.MaxNameTableCharCount = MAXSIZE
binding.ReaderQuotas = readerQuotasDictionary
Dim bindingSecurity As BasicHttpSecurity = New BasicHttpSecurity()
bindingSecurity.Mode = BasicHttpSecurityMode.TransportCredentialOnly
Dim bindingTransportSecurity As HttpTransportSecurity = New
HttpTransportSecurity()
bindingTransportSecurity.ClientCredentialType =
HttpClientCredentialType.Windows
bindingSecurity.Transport = bindingTransportSecurity
binding.Security = bindingSecurity
binding.ProxyAddress = New Uri(portalURL)
binding.UseDefaultWebProxy = False
Try
Dim endPoint As EndpointAddress = New EndpointAddress(portalURL)
_client = New
IPFAlertService.AlertServiceClient.AlertServiceClient(binding, endPoint)
_client.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Identification
_client.ChannelFactory.Credentials.Windows.ClientCredential =
System.Net.CredentialCache.DefaultNetworkCredentials
Catch ex As Exception
Throw New Exception("Unable to connect")
End Try
End Sub
Public Sub AlertUser(ByVal userId As String, ByRef e As IPFEvent)
_client.AlertUser_Event(userId, e)
End Sub
Public Sub AlertUser(ByVal userId As String, ByVal eventName As String)
_client.AlertUser_EventName(userId, eventName)
End Sub
Public Sub AlertUser(ByVal userId As String, ByRef e As IPFEvent, ByVal
LCID As Integer)
_client.AlertUser_Event_LCID(userId, e, LCID)
End Sub
Public Sub AlertUser(ByVal userId As String, ByVal eventName As String,
ByVal LCID As Integer)
_client.AlertUser_EventName_LCID(userId, eventName, LCID)
End Sub
Private _portalURL As String
Private _client As AlertServiceClient
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"4.0.0.0"), _
System.ServiceModel.ServiceContractAttribute([Namespace]:="IPFAlertService",
ConfigurationName:="AlertServiceReference.IAlertService")> _
Private Interface IAlertService
<System.ServiceModel.OperationContractAttribute(Action:="IPFAlertService/IAle
rtService/AlertUser_Event",
ReplyAction:="IPFAlertService/IAlertService/AlertUser_EventResponse")> _
Sub AlertUser_Event(ByVal userId As String, ByVal e As
IPFAlertService.IPFEvent)
<System.ServiceModel.OperationContractAttribute(Action:="IPFAlertService/IAle
rtService/AlertUser_EventName",
ReplyAction:="IPFAlertService/IAlertService/AlertUser_EventNameResponse")> _
Sub AlertUser_EventName(ByVal userId As String, ByVal eventName As
String)
<System.ServiceModel.OperationContractAttribute(Action:="IPFAlertService/IAle
rtService/AlertUser_Event_LCID",
ReplyAction:="IPFAlertService/IAlertService/AlertUser_Event_LCIDResponse")> _
Sub AlertUser_Event_LCID(ByVal userId As String, ByVal e As
IPFAlertService.IPFEvent, ByVal LCID As Integer)
<System.ServiceModel.OperationContractAttribute(Action:="IPFAlertService/IAle
rtService/AlertUser_EventName_LCID",
ReplyAction:="IPFAlertService/IAlertService/AlertUser_EventName_LCIDResponse"
)> _
Sub AlertUser_EventName_LCID(ByVal userId As String, ByVal eventName
As String, ByVal LCID As Integer)
End Interface
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"4.0.0.0")> _
Private Interface IAlertServiceChannel
Inherits IPFAlertService.AlertServiceClient.IAlertService,
System.ServiceModel.IClientChannel
End Interface
<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel",
"4.0.0.0")> _
Partial Private Class AlertServiceClient
Inherits System.ServiceModel.ClientBase(Of
IPFAlertService.AlertServiceClient.IAlertService)
Implements IPFAlertService.AlertServiceClient.IAlertService
Public Sub New()
MyBase.New()
End Sub
Public Sub New(ByVal endpointConfigurationName As String)
MyBase.New(endpointConfigurationName)
End Sub
Public Sub New(ByVal endpointConfigurationName As String, ByVal
remoteAddress As String)
MyBase.New(endpointConfigurationName, remoteAddress)
End Sub
Public Sub New(ByVal endpointConfigurationName As String, ByVal
remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(endpointConfigurationName, remoteAddress)
End Sub
Public Sub New(ByVal binding As System.ServiceModel.Channels.Binding,
ByVal remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(binding, remoteAddress)
End Sub
Public Sub AlertUser_Event(ByVal userId As String, ByVal e As
IPFAlertService.IPFEvent) Implements
IPFAlertService.AlertServiceClient.IAlertService.AlertUser_Event
MyBase.Channel.AlertUser_Event(userId, e)
End Sub
Public Sub AlertUser_EventName(ByVal userId As String, ByVal eventName
As String) Implements
IPFAlertService.AlertServiceClient.IAlertService.AlertUser_EventName
MyBase.Channel.AlertUser_EventName(userId, eventName)
End Sub
Public Sub AlertUser_Event_LCID(ByVal userId As String, ByVal e As
IPFAlertService.IPFEvent, ByVal LCID As Integer) Implements
IPFAlertService.AlertServiceClient.IAlertService.AlertUser_Event_LCID
MyBase.Channel.AlertUser_Event_LCID(userId, e, LCID)
End Sub
Public Sub AlertUser_EventName_LCID(ByVal userId As String, ByVal
eventName As String, ByVal LCID As Integer) Implements
IPFAlertService.AlertServiceClient.IAlertService.AlertUser_EventName_LCID
MyBase.Channel.AlertUser_EventName_LCID(userId, eventName, LCID)
End Sub
End Class
End Class
<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization"
, "4.0.0.0"), _
System.Runtime.Serialization.DataContractAttribute(Name:="IPFEvent",
[Namespace]:="IPFAlertService"), _
System.SerializableAttribute()> _
Partial Public Class IPFEvent
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject,
System.ComponentModel.INotifyPropertyChanged
<System.NonSerializedAttribute()> _
Private extensionDataField As
System.Runtime.Serialization.ExtensionDataObject
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private NameField As String
<System.Runtime.Serialization.OptionalFieldAttribute()> _
Private VariablesField As System.Collections.Generic.Dictionary(Of
String, Object)
Public Sub New()
Variables = New System.Collections.Generic.Dictionary(Of String,
Object)
End Sub
<Global.System.ComponentModel.BrowsableAttribute(False)> _
Public Property ExtensionData() As
System.Runtime.Serialization.ExtensionDataObject Implements
System.Runtime.Serialization.IExtensibleDataObject.ExtensionData
Get
Return Me.extensionDataField
End Get
Set(ByVal value As System.Runtime.Serialization.ExtensionDataObject)
Me.extensionDataField = value
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Name() As String
Get
Return Me.NameField
End Get
Set(ByVal value As String)
If (Object.ReferenceEquals(Me.NameField, value) <> True) Then
Me.NameField = value
Me.RaisePropertyChanged("Name")
End If
End Set
End Property
<System.Runtime.Serialization.DataMemberAttribute()> _
Public Property Variables() As System.Collections.Generic.Dictionary(Of
String, Object)
Get
Return Me.VariablesField
End Get
Set(ByVal value As System.Collections.Generic.Dictionary(Of String,
Object))
If (Object.ReferenceEquals(Me.VariablesField, value) <> True) Then
Me.VariablesField = value
Me.RaisePropertyChanged("Variables")
End If
End Set
End Property
Public Event PropertyChanged As
System.ComponentModel.PropertyChangedEventHandler Implements
System.ComponentModel.INotifyPropertyChanged.PropertyChanged
Protected Sub RaisePropertyChanged(ByVal propertyName As String)
Dim propertyChanged As
System.ComponentModel.PropertyChangedEventHandler = Me.PropertyChangedEvent
If (Not (propertyChanged) Is Nothing) Then
propertyChanged(Me, New
System.ComponentModel.PropertyChangedEventArgs(propertyName))
End If
End Sub
End Class
End Namespace
This code exposes two classes, AlertServiceClient and IPFEvent, located in the IPFAlertService namespace. An AlertServiceClient instance is created by passing in the URL of the alert service endpoint of the portal to contact:
<Full Portal URL>
/ipf/svc/au_wcf
After this object is created, it has four methods that have the same parameters as the four AlertUser portal scripting methods shown in the previous section. The following example creates a client object, creates an IPFEvent object with two variables, and alerts a user with the event payload.
Dim client As IPFAlertService.AlertServiceClient = New IPFAlertService.AlertServiceClient("http://myPortal:8282/ipf/svc/au_wcf")
Dim eventPayload As IPFAlertService.IPFEvent = New IPFAlertService.IPFEvent()
eventPayload.Name = "EmailOrderConfirmation"
eventPayload.Variables.Add("Timestamp", System.DateTime.Now)
eventPayload.Variables.Add("OrderId", 201)
client.AlertUser("ipf_user_to_alert", eventPayload)
Any call made to this service endpoint must be authenticated using Windows domain authentication. If issues are encountered, an exception is thrown giving details as to why the call failed.
The calling application can see this message:
Issue | Exception message |
---|---|
IPF cannot determine the identity of who called the service. | No Windows account appears for this request. |
The identity can be determined, but it is not listed in the external interface mapping in the Portal Manager (see next section). | The Windows Account '<account>' does not map to any IPF user. |
The identity can be determined and is listed in the external interface mapping, but the IPF user to which it maps does not exist. | The user '<user>' in the external interface mapping is not a valid IPF user. |
The portal has not been configured with a task repository. This requires creating an MSSQL data source in the Portal Manager and designating it as a task repository by applying the 'IPF Task Repository' Managed Revision Based Schema against it. | This portal has not been configured with a valid IPF Task Repository. |
The user being alerted by the AlertUser call does not exist. | The user '<user>' to be alerted is not a valid IPF user. |
External interface mapping
When an external application connects to this interface, Windows domain authentication is used to ensure that the external application is on the same domain as the portal it is trying to connect with. Following this authentication, the calling Windows account must be associated with a portal user account. This association is made in the Portal Manager on the External Interface tab.
Viewing tasks
The AlertUser API, along with other features of IPF 4.x, is implemented by placing a task into an MSSQL content database for a thread to pick up and process. This enables longer-running requests to be executed in a way that does not block other tasks that are running at the same time.
Like the email repository, this can be set up in the configuration of an MSSQL data source, as described in the portal installation guide. If a data source has been set up to be a Task Repository, then a View Tasks link is available with the data source record in the Portal Manager. When View Tasks is clicked, a modal window shows current and past tasks on the portal.
Changing the task repository
If you must change the task repository from one content database to another, you are prompted to confirm if either the current or new repository is not empty. These messages are displayed:
Condition | Message |
---|---|
The current repository is non-empty. | Your current task repository has existing tasks that will no longer run on this portal. Are you sure you want to continue? |
The new repository is non-empty. | The new repository you are about to select has existing tasks that will now be activated for this portal. Are you sure you want to continue? |
Both the current and new repositories are non-empty. | Your current task repository and the new repository you are about to select are both non-empty. This means that tasks in the current repository will no longer run on this portal, and tasks in the new repository will now be activated for this portal. Are you sure you want to continue? |