Wie kann ich benutzerdefinierte Benachrichtigungen für externe E-Mail-Adressen erstellen?
-
10-12-2019 - |
Frage
In unserem Unternehmen haben wir vertrauliche Informationen in SharePoint gespeichert.Einige politisch einflussreiche Personen drängen darauf, dass Benachrichtigungen an ihre externen E-Mail-Adressen gesendet werden.Wie kann ich benutzerdefinierte E-Mail-Benachrichtigungen mit Inhalt an interne E-Mails und Benachrichtigungen ohne Inhalt an externe E-Mail-Adressen senden?
Lösung
Erstellen Sie neue Benachrichtigungsvorlagen
1 Erstellen Sie eine Kopie der Standardvorlagen, ändern Sie den Namen und die ID und fügen Sie den Aufruf des benutzerdefinierten Handlers zu jeder Vorlage hinzu.
Stellen Sie sicher, dass die benutzerdefinierten Vorlagen am Ende ihres Namens ein „.Ext“ haben.
Die benutzerdefinierten Funktionen rufen auch eine benutzerdefinierte NotificationHandlerAssembly auf
using System; using System.Runtime.InteropServices; using Microsoft.SharePoint; using Microsoft.SharePoint.Administration; using System.Xml; namespace Prov.Shared.CCPersonalEmail.Features.AlertTemplates { public class AlertTemplatesEventReceiver : SPFeatureReceiver { public override void FeatureActivated(SPFeatureReceiverProperties properties) { //The Properties we will add to the Alert Template //(Since this feature lives in the same project with the //IAlertNotifyHandler we just refer to our own assembly) string ClassToAdd = "CCPersonalClass"; SPFeatureDefinition FeatDef = (SPFeatureDefinition)properties.Feature.Definition; string ourAssemblyName = FeatDef.ReceiverAssembly; SPWebApplication WebApplication = (SPWebApplication)properties.Feature.Parent; SPWebService WebService = WebApplication.WebService; SPAlertTemplateCollection colSPAT = new SPAlertTemplateCollection(WebService); foreach (SPAlertTemplate SPAT in colSPAT) { if (SPAT.Name.Contains(".Ext")) { SPAT.Delete(); } } foreach (SPAlertTemplate SPAT in colSPAT) { if (SPAT.Name.Contains("SPAlertTemplateType")) { SPAlertTemplate newSPAT = new SPAlertTemplate(); XmlDocument xmlSpit = new XmlDocument(); xmlSpit.LoadXml(SPAT.Xml.ToString()); //create node and add value XmlNode node = xmlSpit.CreateNode(XmlNodeType.Element, "Properties", string.Empty); //create 3 nodes XmlNode nodeAssembly = xmlSpit.CreateElement("NotificationHandlerAssembly"); XmlNode nodeClassName = xmlSpit.CreateElement("NotificationHandlerClassName"); XmlNode nodeProperties = xmlSpit.CreateElement("NotificationHandlerProperties"); nodeAssembly.InnerText = ourAssemblyName; nodeClassName.InnerText = ourAssemblyName.Substring(0,ourAssemblyName.IndexOf(",")) + "." + ClassToAdd; //add to parent node node.AppendChild(nodeAssembly); node.AppendChild(nodeClassName); node.AppendChild(nodeProperties); //add to elements collection xmlSpit.DocumentElement.AppendChild(node); newSPAT.Xml = xmlSpit.InnerXml; newSPAT.Name = SPAT.Name.ToString() + ".Ext"; newSPAT.Id = Guid.NewGuid(); colSPAT.Add(newSPAT); } } foreach (SPTimerServiceInstance timerservice in WebApplication.Farm.TimerService.Instances) { timerservice.Stop(); timerservice.Start(); } } public override void FeatureDeactivating(SPFeatureReceiverProperties properties) { SPWebApplication WebApplication = (SPWebApplication)properties.Feature.Parent; SPWebService WebService = WebApplication.WebService; SPAlertTemplateCollection colSPAT = new SPAlertTemplateCollection(WebService); foreach (SPAlertTemplate SPAT in colSPAT) { if (SPAT.Name.Contains(".Ext")) { SPAT.Delete(); } } } } }
Benutzerdefinierte Benachrichtigungshandler-Assembly
1 Die Klasse CCPersonalClass implementiert die IAlertNotifyHandler-Schnittstelle, die die definierte Methode OnNotification enthält
Versucht, die benutzerdefinierte Benachrichtigung zu senden (wenn dies fehlschlägt, wird eine normale Benachrichtigung gesendet.)
Benutzerdefinierte Benachrichtigung:
Ruft die PersonalEmail-Felddaten aus der Benutzerinformationsliste ab
Wenn die persönliche E-Mail-Adresse leer ist, wird nur eine normale Benachrichtigung gesendet
Wenn die persönliche E-Mail-Adresse ausgefüllt ist
Senden Sie eine normale E-Mail an die interne E-Mail
Senden Sie eine reduzierte E-Mail an eine externe Adresse
Ersetzen
http://
mithttp://ext-
Wenn Sie externe E-Mails senden, entfernen Sie alle Detaildatensätze und lassen Sie nur die Kopfzeilen übrig.
{
using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using System.Text.RegularExpressions;
using Framework.Logger;
using System.Collections.Specialized;
namespace Shared.CCPersonalEmail
{
class CCPersonalClass: IAlertNotifyHandler
{
public bool OnNotification(SPAlertHandlerParams alertHandler)
{
using (new SPMonitoredScope("Shared.CCPersonalClass OnNotification"))
{
string siteUrl = alertHandler.siteUrl;
using (SPSite site = new SPSite(siteUrl + alertHandler.webUrl))
{
using (SPWeb web = site.OpenWeb())
{
try
{
return CustomAlertNotification(web, alertHandler, siteUrl);
}
catch
{
//if it fails due to configuration still the default alert should work
SPUtility.SendEmail(web, alertHandler.headers, alertHandler.body);
return false;
}
}
}
}
}
private bool CustomAlertNotification(SPWeb web, SPAlertHandlerParams alertHandler, string siteUrl)
{
using (new SPMonitoredScope("Shared.CCPersonalClass CustomAlertNotification"))
{
string PersonalEmail = string.Empty;
int eventCount = alertHandler.eventData.GetLength(0);
//Get the Personal Email from the User Information List
try
{
PersonalEmail = GetPersonalEmail(alertHandler.headers["to"], web);
}
catch (Exception e)
{
Logger.LogError(e, "CCPersonalClass");
}
//Send each alert in the alertHandler
for (int i = 0; i < eventCount; i++)
{
try
{
if (string.IsNullOrEmpty(PersonalEmail))
{
SPUtility.SendEmail(web, alertHandler.headers, alertHandler.body);
}
else
{
//Send a normal notification to the work email
SPUtility.SendEmail(web, alertHandler.headers, alertHandler.body);
//Send an abbreviated email to the external email
string txt = alertHandler.body.ToString().Replace("http://", "http://ext-");
//Digest messages- removing detail records
string strRegex = "<tr>\\s*<td class=\"[a-z]*?\"> <div class=\"nobr\">.*?</td>{0}s*</tr>|";
//Immediate messages- removing detail records
strRegex = strRegex + "<tr>\\s*<td class=\"formlabel\">.*<td class=\"altvb\"> </td>\\s*</tr>";
txt = Regex.Replace(txt, strRegex, string.Empty, RegexOptions.Singleline);
StringDictionary PersonalHeader = alertHandler.headers;
PersonalHeader["cc"] = PersonalEmail;
SPUtility.SendEmail(web, PersonalHeader, txt);
}
}
catch (Exception e)
{
Logger.LogError(e, "CCPersonalClass");
}
}
if (eventCount > 1)
return true;
else
return false;
}
}
private string GetPersonalEmail(string WorkEmail, SPWeb web)
{
using (new SPMonitoredScope("Shared.CCPersonalClass GetPersonalEmail"))
{
SPQuery SelectUser = new SPQuery();
string SelectUserQS = string.Format("<Query><Where><Eq><FieldRef Name='EMail' /><Value Type='Text'>{0}</Value></Eq></Where></Query>", WorkEmail);
SelectUser.Query = SelectUserQS;
SPList UserList = web.Site.RootWeb.Lists["User Information List"];
SPListItemCollection SelectedUserCol = UserList.GetItems(SelectUser);
SPListItem SelectedUser = SelectedUserCol[0];
return (string)SelectedUser["PersonalEmail"];
}
}
}
}
Legen Sie fest, dass die Warnungen die externe Vorlage verwenden
1 Vorhandener Inhalt wird mit Feature-Ereignisempfänger aktualisiert:
Vorhandene Warnungen:
- Site.allwebs.alerts erhalten denselben Vorlagennamen mit angehängter .ext-Datei
Vorhandene Listen:
- Site.allwebs.lists hat die angehängten Alerttemplates in ihr .ext-Gegenstück umgewandelt
{
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Prov.Framework.Logger;
namespace Prov.Shared.CCPersonalEmail.Features.CCAlerts
{
[Guid("a3889d39-ea91-441e-9039-157c512441e4")]
public class CCAlertsEventReceiver : SPFeatureReceiver
{
// Set AlertTemplates on sites and alerts to custom templates.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
using (SPSite site = (SPSite)properties.Feature.Parent)
{
AlertTemplateSelector objSelectedAlertTemplate = new AlertTemplateSelector(site);
//Add PersonalEmail field if it does not exist yet
SPFieldCollection UserInfoFields = site.RootWeb.Lists["User Information List"].Fields;
try
{
bool FieldExists = UserInfoFields.ContainsField("PersonalEmail");
if (!FieldExists)
{
UserInfoFields.Add("PersonalEmail", SPFieldType.Text, false);
}
}
catch (Exception e)
{
Logger.LogError(e, "CCPersonalClass");
}
foreach (SPWeb web in site.AllWebs)
{
using (web)
{
web.AllowUnsafeUpdates = true;
foreach (SPList List in web.Lists)
{
try
{
List.AlertTemplate = objSelectedAlertTemplate.SwapAlertTemplate(List.AlertTemplate.Name, true);
List.Update();
}
catch (Exception e)
{
Logger.LogError(e, "CCAlertsEventReceiver");
}
}
foreach (SPAlert Alert in web.Alerts)
{
try
{
Alert.AlertTemplate = objSelectedAlertTemplate.SwapAlertTemplate(Alert.AlertTemplate.Name, true);
Alert.Update();
}
catch (Exception e)
{
Logger.LogError(e, "CCAlertsEventReceiver");
}
}
web.AllowUnsafeUpdates = false;
}
}
}
}
// Revert AlertsTemplates on sites and alerts back to out of box templates.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
using (SPSite site = (SPSite)properties.Feature.Parent)
{
AlertTemplateSelector objSelectedAlertTemplate = new AlertTemplateSelector(site);
foreach (SPWeb web in site.AllWebs)
{
using (web)
{
web.AllowUnsafeUpdates = true;
foreach (SPList List in web.Lists)
{
try
{
List.AlertTemplate = objSelectedAlertTemplate.SwapAlertTemplate(List.AlertTemplate.Name, false);
List.Update();
}
catch (Exception e)
{
Logger.LogError(e, "CCAlertsEventReceiver");
}
}
foreach (SPAlert Alert in web.Alerts)
{
try
{
Alert.AlertTemplate = objSelectedAlertTemplate.SwapAlertTemplate(Alert.AlertTemplate.Name, false);
Alert.Update();
}
catch (Exception e)
{
Logger.LogError(e, "CCAlertsEventReceiver");
}
}
web.AllowUnsafeUpdates = false;
}
}
}
}
}
}
Der folgende Code wird von der Feature-Aktivierung, -Deaktivierung und dem OnListCreation-Ereignishandler verwendet
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
namespace Shared.CCPersonalEmail
{
class AlertTemplateSelector
{
private SPAlertTemplateCollection atc;
private SPSite site;
public AlertTemplateSelector(SPSite site)
{
this.site = site;
this.atc = new SPAlertTemplateCollection((SPWebService)site.WebApplication.Parent);
}
public SPAlertTemplate SwapAlertTemplate(string PreviousAlert, bool isActivating)
{
if ((!PreviousAlert.EndsWith(".Ext")) && (isActivating))
{
PreviousAlert = string.Format("{0}.Ext", PreviousAlert);
}
if ((PreviousAlert.EndsWith(".Ext")) && (!isActivating))
{
PreviousAlert = PreviousAlert.Replace(".Ext", "");
}
SPAlertTemplate newTemplate = atc[PreviousAlert];
if (newTemplate == null)
{
if (isActivating)
{
newTemplate = atc["SPAlertTemplateType.GenericList.Ext"];
}
else
{
newTemplate = atc["SPAlertTemplateType.GenericList"];
}
}
return newTemplate;
}
}
}
2 Future-Webs und ihre Future-Listen
- Das SPListEventReceiver ListAdded()-Ereignis dreht die Vorlage für alle in der Websitesammlung erstellten Listen um
{
namespace Shared.CCPersonalEmail.OnListCreation
{
public class OnListCreation : SPListEventReceiver
{
public override void ListAdded(SPListEventProperties properties)
{
base.ListAdded(properties);
SPWeb web = properties.Web;
SPList List = web.Lists[properties.ListId];
AlertTemplateSelector objSelectedAlertTemplate = new AlertTemplateSelector(web.Site);
List.AlertTemplate = objSelectedAlertTemplate.SwapAlertTemplate(List.AlertTemplate.Name, true);
List.Update();
}
}
}
Hauswirtschaft
1 Während der Funktionsaktivierung
Erstellen Sie ein PersonalEmail-Feld in der Benutzerinformationsliste des Rootweb
Der Code ist im oben genannten funktionsaktivierten Ereignisempfänger enthalten
2 Während der Funktionsdeaktivierung
- PersonalEmail wird zum Inhalt, sodass es bei der Deaktivierung nicht entfernt wird
Andere Tipps
Wenn es mit nur einer einzigen Liste isoliert ist, können Sie stattdessen einen Workflow verwenden.Sie können eine Holdingliste erstellen, um die Art der Sache zu verfolgen, um eine E-Mail-Adresse auf und eine Semikolon-Liste der E-Mail-Adressen zu verfolgen.Wenn ein Element erstellt oder bearbeitet wird (was auch immer Ihre Alarmlogik sein sollte), suchen Sie nach der entsprechenden Liste der E-Mail-Adressen und senden Sie die E-Mail, die die desinfizierte E-Mail-Adresse gruppiert.