Come posso creare avvisi personalizzati per indirizzi email esterni?
-
10-12-2019 - |
Domanda
Nella nostra azienda abbiamo informazioni riservate archiviate in SharePoint.Alcune persone politicamente efficaci stanno spingendo affinché gli avvisi vengano inviati ai loro indirizzi email esterni.Come posso inviare avvisi e-mail personalizzati con contenuto a e-mail interne e avvisi senza contenuto a indirizzi e-mail esterni?
Soluzione
Crea nuovi modelli di avviso
1 Crea una copia dei modelli predefiniti, modifica il nome, l'ID e aggiungi la chiamata al gestore personalizzato a ciascuno di essi.
Fai in modo che i modelli personalizzati abbiano un ".Ext" alla fine del nome.
Le funzionalità personalizzate chiamano anche un NotificationHandlerAssembly personalizzato
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(); } } } } }
Assemblaggio del gestore delle notifiche personalizzato
1 La classe CCPersonalClass implementa l'interfaccia IAlertNotifyHandler che contiene il metodo definito OnNotification
Tenta di inviare l'avviso personalizzato (se fallisce, invia l'avviso normale).
Avviso personalizzato:
Ottiene i dati del campo PersonalEmail dall'elenco delle informazioni utente
Se l'e-mail personale è vuota, invia semplicemente un avviso normale
Se l'e-mail personale è popolata
Invia un'e-mail normale all'e-mail interna
Invia email ridotta a indirizzo esterno
Sostituire
http://
conhttp://ext-
Se si invia un'e-mail esterna, rimuovere tutti i record di dettaglio e lasciare solo le intestazioni.
{
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"];
}
}
}
}
Imposta gli avvisi per utilizzare il modello esterno
1 Il contenuto esistente viene aggiornato con il ricevitore di eventi Funzionalità:
Avvisi esistenti:
- Site.allwebs.alerts viene cambiato con lo stesso nome del modello che aveva con l'aggiunta di .ext
Elenchi esistenti:
- Site.allwebs.lists ha trasformato i modelli di avviso allegati nella loro controparte .ext
{
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;
}
}
}
}
}
}
Il codice seguente viene utilizzato dalle funzioni di attivazione, disattivazione e dal gestore eventi OnListCreation
{
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 Reti future e relative liste future
- L'evento SPListEventReceiver ListAdded() capovolge il modello in tutti gli elenchi creati nella raccolta siti
{
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();
}
}
}
Faccende domestiche
1 Durante l'attivazione della funzione
creare un campo PersonalEmail nell'elenco delle informazioni utente di rootweb
Il codice è incluso nella funzione ricevitore eventi attivata sopra
2 Durante la disattivazione della funzione
- PersonalEmail diventa contenuto quindi non viene rimosso al momento della disattivazione
Altri suggerimenti
Se è isolato a un solo elenco, potresti essere in grado di utilizzare invece un flusso di lavoro.È possibile creare un elenco di partecipazione per tenere traccia del tipo di cosa per inviare un'e-mail e un elenco delimitato dal punto di partenza degli indirizzi e-mail.Quando un elemento viene creato o modificato (qualunque sia la logica di avviso dovrebbe essere) cerchi l'elenco appropriato degli indirizzi e-mail e l'e-mail che raggruppa l'e-mail sanitariata.