Alternatív feladó
Azt hiszem sokaknak okozott már problémát az Exchange Server azon működésmódja, hogy egy adott
felhasználóhoz több e-mail címet rendelve nem tudjuk elérni, hogy a felhasználó az alternatív
címével tudjon levelet küldeni. Ha csak egyszerűen beírjuk az Outlook From: mezőjébe az alternatív
címet akkor egy hibaüzenetet kapunk:
Your message did not reach some or all of the intended recipients.
Subject: test
Sent: 2005. 01. 20. 7:52
The following recipient(s) could not be reached:
suf@freemail.hu on 2005. 01. 20. 7:52
You do not have permission to send to this recipient. For assistance, contact your system administrator.
MSEXCH:MSExchangeIS:/DC=local:MAIL
Ezt nekem idáig kétféleképpen sikerült megkerülnöm:
1. Felveszünk egy másik mailbox-al rendelkező felhasználót az alternatív címmel. Átirányítjuk az alternatív felhasználó
levelezését az eredeti felhasználónkra. Az eredeti felhasználónak Send As jogot adunk az alternatív felhasználóra.
A From: mezőbe beírjuk az alternatív felhasználó címét küldésnél.
Ez a megoldással a következő problémák vannak: Kérdéses, hogy az így felvett plusz felhasználó igényel-e plusz Exchange
licenszet. A küldésnél be kell írni a From: mezőbe a címet és nem tudunk választani a lehetőségeink közül.
2. Ez a megoldás némi fejlesztést is tartalmaz. Az alapelv az, hogy az Exchange-en áthaladó levél feladója az eredeti marad,
majd az alternatív feladót akkor adjuk meg amikor a levél elhagyja a szervert. A levél a szerverről való távozáskor
viszonylag egyszeruen módosítható egy SMTP Event Sink-kel, ugyanakkor gondot okoz, hogy ebben az esetben olyan adat alapján
kell a levelet módosítanunk amit a felhasználó ad meg. Ennek az adatnak (az alternatív címnek) együtt kell utaznia a
levéllel. Legegyszerubb az lenne, hogy a levél SMTP fejlécében elhelyezzük valamilyen X-Valami mezôben az alternatív címet a
felhasználói programban. Ezt az Outlookban sajnos nem tudjuk megtenni, mert a MAPI levélben még nincs SMTP fejléc. Ezért
azt a megoldást választottam, hogy egy GUID nevű rejtett csatolt fájlban helyezem el az alternatív címet. A megoldás alapvető
működéséhez két modul szükséges. Az egyik egy Outlook form ami megnyitáskor az Active Directory-ból felveszi a felhasználó
lehetséges címeit és elhelyezi őket egy lenyíló listában. A felhasználó kiválasztja a feladó címet. Küldéskor generálódik
egy csatolás aminek a neve egy meghatározott GUID. A másik egy SMTP Event Sink ami figyeli, hogy a levél tartalmaz-e egy,
a speciális GUID névvel rendelkező csatolást, ha igen, akkor kiolvassa belőle az alternatív címet, ellenőrzi, hogy az
adott felhasználónak van-e ilyen címe, és ha igen, akkor kicseréli az összes feladó mezőben (From, Sender, ReplyTo).
A második megoldáshoz használatához szükséges dolgok:
Az SMTP Event Sink regisztrációja a szokásos módon történik a szükséges parancsokhoz mellékeltem mintát. Az Outlook form
egy teljesen más eset. Ahhoz, hogy a felhasználó a megszokott levélküldésnek megfelelő módon tudja használni két dologra
van szükség.
1. A form-ot publikálni kell az Outlookban. Ezt több különböző helyre megtehetjük, ezeknek a helyeknek megvannak
a maguk előnyei és hátrányai. Erről most nem kívánok bővebben értekezni, akit komolyabban érdekel
itt talál
egy angol nyelvű cikket a témáról.
2. Tudatnunk kell az Outlook-kal, hogy a saját form-unkat használja küldésnél. Ezt egy registry bejegyzéssel tudjuk
megtenni. A bejegyzés utasítja az Outlookot, hogy a levél küldésre az alapértelmezett IPM.Note form helyett, az általunk
publikált IPM.Note.Alternate form-ot használja.
Mellékeltem egy pici script-et ami képes a felhasználó Outlookjában a fenti két lépést elvégezni. A script alapvetően
Outlook 2003-hoz készült, és a form-ot a felhasználó Beérkezett üzenetek (Inbox) mappájába publikálja. Ha valakinek ez a
megoldás nem jó, akkor vagy kézzel kell elvégezni a szükséges lépéseket, vagy módosítani kell a "telepítő" scriptet.
A megoldáshoz tartozik még egy opcionális elem, ami megoldja, hogy a felhasználó Elküldött üzenetek (Sent Items) mappája
alatt különböző mappákba szortírozza feladó szerint a leveleket. Ez a kiegészítő elem
egy időzítendő JScript formájában készült el és a cikk végén található a
dokumentációjával együtt.
Hiányosságok:
Számomra tudottan ennek az "Alternatív Feladó" nevezetű script csomagnak van néhány hiányossága amiket mindenképp figyelembe
kell vennie annak aki használni szeretné. Terveim közt szerepel, hogy ezen hiányosságok egy részét a jövőben kijavítsam, ugyanakkor
biztos vagyok abban, hogy ezek a javítások nem fogják teljeskörűen megoldani az itt jelzett problémákat:
- Nem működik RPC over HTTP környezetben
- Nem műödik az OWA, az OMA valamint az ActiveSync for Exchange (PDA, SmartPhone) környezetben
- Válasz üzenetként mindíg a felhasználó elsődleges e-mail címét jelöli ki a listán (nem tudja megállapítani, hogy az
eredeti levél melyik címre érkezett)
- Az elküldött üzenetben a Display Name mindíg a felhasználó eredeti AD-ban levő neve, tehát nem tudunk különböző
neveket rendelni a különböző levélcímekhez
- Az elküldött üzenetben a Sender, a From és a ReplyTo mezőkben cseréljük ki az címet. Az EventSink script futási pontján az SMTP boríték
küldő mezője (http://schemas.microsoft.com/cdo/smtpenvelope/senderemailaddress) már csak olvasható, így az SMTP borítékban mindíg az
eredeti cím marad. Ez különböző levelező listákon és SPAM szűrőknél gondot okozhat.
Az SMTP Event Sink:
as.js:
<SCRIPT LANGUAGE="JScript">
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
This code is free for both personal and commercial use, but you are
expressly forbidden from selling.
**************************************************************************
FILE NAME:
as.js
DESCRIPTION:
This is an SMTP transport event sink used to help the impelentation of the
alternative sender function for the Exchange Server
COPYRIGHT:
Copyright (c) Zoltán Gömöri 2004-2006.
All rights reserved.
NOTES:
The original version of this source code and the article that
includes this source code can be found at:
http://www.gomori.hu
CREATED:
2005.01.20
LAST MODIFIED:
2006.03.06
VERSION:
v2.0 Build 2
TO DO:
**************************************************************************
*/
// declare "constants"
var cdoRunNextSink = 0;
var cdoSkipRemainingSinks = 1;
var ForReading = 1;
var ForAppending = 8;
function ISMTPOnArrival::OnArrival(Msg, EventStatus)
{
var i;
var AttIndex;
var AttStream;
var AlternateMail;
var OrigMail;
var arrEMail = new Array();
AttIndex = 0;
for(i=1;i <= Msg.Attachments.Count;i++)
if(Msg.Attachments(i).FileName == "{4F729183-BFB2-4cdc-9648-1A6E600BAB9A}.txt")
AttIndex = i;
if(AttIndex != 0)
{
AttStream = Msg.Attachments(AttIndex).GetDecodedContentStream();
AlternateMail = AttStream.ReadText();
AttStream.Close();
Msg.Attachments.Delete(AttIndex);
AlternateMail = AlternateMail.match(/<[^<>]*@[^<>]*>/);
OrigMail = Msg.From.match(/<[^<>]*@[^<>]*>/);
if(AlternateMail != null && OrigMail != null)
if(ValidateAS(ExtractMail(OrigMail[0]),ExtractMail(AlternateMail[0])))
{
Msg.From = Msg.From.replace(OrigMail[0],AlternateMail[0]);
Msg.ReplyTo = Msg.ReplyTo.replace(OrigMail[0],AlternateMail[0]);
Msg.Sender = Msg.Sender.replace(OrigMail[0],AlternateMail[0]);
}
Msg.DataSource.Save();
}
EventStatus = cdoRunNextSink;
}
/*
This function Validates against the AD if the Sender has a right to change
the address to the supplied one
*/
function ValidateAS(OrigSender, AltSender)
{
var i;
var MailArr;
// Get actual AD domain
rootDSE = GetObject("LDAP://rootDSE");
ADDN = rootDSE.Get("defaultNamingContext");
// Open an ADSI OleDB connection to the AD
objConnection = new ActiveXObject("ADODB.Connection")
objConnection.Open("Provider=ADsDSOObject;");
objCommand = new ActiveXObject("ADODB.Command");
objCommand.ActiveConnection = objConnection;
// Find the user object
objCommand.CommandText = "<LDAP://" + ADDN + ">;" +
"(&(objectCategory=User)(mail=" + OrigSender + "));" +
"proxyAddresses;" +
"subtree";
objRecordSet = objCommand.Execute();
// Determine if the user object has a proxyAddress witch equals the
// AltSender parameter
if(!objRecordSet.EOF)
{
MailArr=objRecordSet.Fields("proxyAddresses").Value.toArray();
for(i=0;i<MailArr.length;i++)
{
if((MailArr[i].substr(0,5).toLowerCase() == "smtp:") && (MailArr[i].substr(5) == AltSender))
return true;
}
}
return false;
}
function ExtractMail(mailaddress)
{
return mailaddress.substring(1,mailaddress.length-1);
}
</SCRIPT>
Az SMPT Event Sink regisztrációja:
cscript smtpreg.vbs /add 2 OnArrival AlternateSender CDO.SS_SMTPOnArrivalSink "mail from=*"
cscript smtpreg.vbs /setprop 2 OnArrival AlternateSender Sink ScriptName "c:\Scripts\SMTP\AS\as.js"
Az Outlook form script:
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
' EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
' WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' This code is free for both personal and commercial use, but you are
' expressly forbidden from selling.
' **************************************************************************
' FILE NAME:
' Mail.Alternate.En.oft
' DESCRIPTION:
' This is an Outlook Form used as part of the impelentation of the
' alternative sender function for the Exchange Server
' COPYRIGHT:
' Copyright (c) Zoltán Gömöri 2004-2005.
' All rights reserved.
' NOTES:
' The original version of this source code and the article that
' includes this source code can be found at:
' http://www.gomori.hu
' CREATED:
' 2004.06.26
' LAST MODIFIED:
' 2005.04.21
' VERSION:
' v1.1 Build 1
'TO DO:
' **************************************************************************
Function Item_Open()
Dim DefMailIndex
Dim CurrMailIndex
Const ADS_SCOPE_SUBTREE = 2
Set myNamespace = Application.GetNameSpace("MAPI")
Set cbxSender = Item.GetInspector.ModifiedFormpages(1).Controls("cbxSender")
Set rootDSE = GetObject("LDAP://rootDSE")
ADDN = rootDSE.Get("defaultNamingContext")
Set objConnection = CreateObject("ADODB.Connection")
Set objCommand = CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Timeout") = 30
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
objCommand.Properties("Cache Results") = False
objCommand.CommandText = "Select proxyAddresses, mail from 'LDAP://" & ADDN & "' where legacyExchangeDN='" & myNameSpace.CurrentUser.Address & "'"
Set objRecordSet = objCommand.Execute
If Not objRecordSet.EOF Then
AddrArr = objRecordSet.Fields("proxyAddresses")
For i = 0 to UBound(AddrArr)
If UCase(Left(AddrArr(i),5)) = "SMTP:" Then
cbxSender.AddItem Mid(AddrArr(i),6,Len(AddrArr(i)))
CurrMailIndex = cbxSender.ListCount - 1
End If
If LCase(Mid(AddrArr(i),6,Len(AddrArr(i)))) = LCase(objRecordSet.Fields("mail").Value) Then
DefMailIndex = CurrMailIndex
End If
Next
End If
If cbxSender.ListCount > 0 Then
cbxSender.ListIndex = DefMailIndex
End If
End Function
Function Item_Send()
Const olByReference = 4
Const olByValue = 1
Const olEmbeddedItem = 5
Const olOLE = 6
Set cbxSender = Item.GetInspector.ModifiedFormpages(1).Controls("cbxSender")
Set FSO = CreateObject("Scripting.FileSystemObject")
Set WshShell = CreateObject("WScript.Shell")
Set AttachFile = FSO.CreateTextFile(WshShell.ExpandEnvironmentStrings("%Temp%") & "\{4F729183-BFB2-4cdc-9648-1A6E600BAB9A}.txt")
AttachFile.WriteLine("<" & cbxSender.Text & ">")
AttachFile.Close
Item.Attachments.Add WshShell.ExpandEnvironmentStrings("%Temp%") & "\{4F729183-BFB2-4cdc-9648-1A6E600BAB9A}.txt", olByValue, 0, "{4F729183-BFB2-4cdc-9648-1A6E600BAB9A}.txt"
End Function
Az ezzel a scriptel és a megfelelő design-al ellátott Outlook form-ot Outlook 2003 Angol
és Outlook 2003 Magyar verzióban mellékeltem a letölthető csomagban.
Annak aki korábbi verziójú Outlook-ot használ, létre kell hoznia a form-ot a minta form-ok
és a fenti script alapján, valamint módosítania kell a form telepítőt, mert a registry bejegyzések
verziófüggőek.
A telepítő script:
as_publish_en.js:
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
This code is free for both personal and commercial use, but you are
expressly forbidden from selling.
**************************************************************************
FILE NAME:
as_publish.js
DESCRIPTION:
This is the setup script of the Alternate Sender Outlook Form
COPYRIGHT:
Copyright (c) Zoltán Gömöri 2005.
All rights reserved.
NOTES:
The original version of this source code and the article that
includes this source code can be found at:
http://www.gomori.hu
CREATED:
2005.04.21
LAST MODIFIED:
2005.04.22
VERSION:
v1.0 Build 1
TO DO:
**************************************************************************
*/
// Script parameters
var OftFileName = "IPM.Note.Alternate.En.oft";
var FormDisplayName = "Alternate Sender";
var FormName = "Alternate";
var OutlookVersion = "11.0";
// declare "constants"
var olDefaultRegistry = 0;
var olFolderRegistry = 3;
var olOrganizationRegistry = 4;
var olPersonalRegistry = 2;
var olFolderInbox = 6;
// declare variables
var OftFile;
var OlApp;
var OlItem;
var OlForm;
var OlFolder;
var OlNamespace;
var ScriptFolder;
var WshShell;
var RegKey;
// Get the script's path
ScriptFolder = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf("\\") + 1);
// Set the name of the installable Outlook Form File
OftFile = ScriptFolder + OftFileName;
// Publish the form
OlApp = new ActiveXObject("Outlook.Application");
OlNamespace = OlApp.GetNameSpace("MAPI");
OlFolder = OlNamespace.GetDefaultFolder(olFolderInbox);
OlItem = OlApp.CreateItemFromTemplate(OftFile);
OlForm = OlItem.FormDescription;
OlForm.Name = FormName;
OlForm.DisplayName = FormDisplayName;
OlForm.PublishForm(olFolderRegistry,OlFolder);
// Register the form as the default IPM.Note
WshShell = WScript.CreateObject("WScript.Shell");
RegKey = "HKCU\\Software\\Microsoft\\Office\\" + OutlookVersion + "\\Outlook\\Custom Forms\\";
WshShell.RegWrite(RegKey, "", "REG_SZ");
WshShell.RegWrite(RegKey + "Compose\\", "", "REG_SZ");
WshShell.RegWrite(RegKey + "Read\\", "", "REG_SZ");
WshShell.RegWrite(RegKey + "Compose\\IPM.Note", "IPM.Note." + FormName, "REG_SZ");
Itt következik az ígért opcionális elem. Feladata, hogy Eredetileg Exchange Store Sink
formájában készült el, de sajnos ebben a formában nem működik, miután a Sent Items mappára
telepített Store Sink nem hajtódik végre a MAPI kliens által a levél küldéskor oda berakott
levelekre (http://support.microsoft.com/?id=297274).
Használatához a következők szükségesek:
- abba a mappába ahol a script található el kell helyezni egy a script nevével azonos ini fájlt
(SentCategorizer.ini). Ennek a fájlnak a tartalma soronként azon felhasználók Sent Items mappájának
a címe akikre le akarjuk futtatni a scriptet(pl. http://mailserver.domain.hu/exchange/user@domain.hu/Sent Items )
- Annak a felhasználónak akinek a nevében futtatni akarjuk a scriptet megfelelő jogokat kell adni a
felhasználó levelesládájához
- Megfelelően időzíteni kell, hogy az elvárt intervallumonként lefusson
SentCategorizer.js
/*
THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
This code is free for both personal and commercial use, but you are
expressly forbidden from selling.
**************************************************************************
FILE NAME:
SentCategorizer.js
DESCRIPTION:
This is the Sent Items Categorizer script. It is an optional component for the
alternative sender solution for the Exchange Server.
It can be used to put the messages sent by various alternative e-mail addresses
to folders coresponding to the sender e-mail.
COPYRIGHT:
Copyright (c) Zoltán Gömöri. 2005.
All rights reserved.
NOTES:
The original version of this source code and the article that
includes this source code can be found at:
http://www.gomori.hu
CREATED:
2005.04.25
LAST MODIFIED:
2005.05.04
VERSION:
v1.0 Build 1
TO DO:
**************************************************************************
*/
// declare "constants"
// ADO constants
var adModeReadWrite = 3;
var adCreateCollection = 8192;
// Error constants
var ERR_PERMISSION_DENIED = -2147217911;
var ERR_ACCESS_DENIED = -2147024891;
var ERR_ALREADY_EXISTS = -2147217768;
// MAPI constants
var MAPI_NS_PROPTAG = "http://schemas.microsoft.com/mapi/proptag/";
var PR_SENDER_NAME = "x0C1A001E";
var PR_SENDER_ADDRTYPE = "x0C1E001E";
var PR_SENDER_EMAIL_ADDRESS = "x0C1F001E";
// Intialize components
ExStore_Init();
// Main Code
var FSO;
var f;
var StorePath;
var Store;
// Create a Store Object
Store = new ExStore();
// Add to the Mail Event an Eventhandler. This will move the mail to
// the target folder
Store.Event_Mail = MoveSentItem;
FSO = new ActiveXObject("Scripting.FileSystemObject");
// Open the list of the Sent Items folders
f = FSO.OpenTextFile(ScriptPath() + "\\SentCategorizer.ini");
// Iterate thru the Sent Items folders
while(!f.AtEndOfStream)
{
StorePath = f.ReadLine();
if(StorePath != "") Store.ProcessMailFolder(StorePath); // Process the Sent Items folders
}
f.Close();
/*
MoveSentItem(Url)
This is an event handler function called by the Store object on each message located in the
Sent Items folder.
This function:
- gets the alternate e-mail address from the message
- creates a folder named after the alternate e-mail address under the Sent Items if it doesn't exists
- removes the attachment containing the alternates e-mail address
- changes the from address of the e-mail to the alternate address
- saves the mail to the folder named after the alternate e-mail
- deletes the original e-mail
Parameters:
Url - Url of the message to process
Returns:
Nothing
*/
function MoveSentItem(Url)
{
var Msg; // The message object (CDO.Message)
var Sender; // The real sender of the mail
var AttStream; // The special GUID named attachment's stream
var AlternateMail; // The alternate mail string
var ParentFolder; // The original folder of the mail (Sent Items)
var FolderName; // The name of the target folder (it is equals to the alternate sender)
var i,j;
j = 0;
Msg = new ActiveXObject("CDO.Message"); // Initialize the Message object
Msg.DataSource.Open(Url); // Bind to the Message
ParentFolder = Msg.Fields("DAV:parentname").Value; // Get the Url of the folder containing the message
Sender = Msg.Fields("urn:schemas:httpmail:fromemail").Value; // Set the initial value of the sender
// Iterate thru the attachments
for(i=1;i<=Msg.Attachments.Count;i++)
{
if(Msg.Attachments(i).FileName == "{4F729183-BFB2-4cdc-9648-1A6E600BAB9A}.txt")
{ // If we found the attachment contains the alternate sender
AttStream = Msg.Attachments(i).GetDecodedContentStream();
AlternateMail = AttStream.ReadText(); // read the mail address from this attachment
AttStream.Close();
AlternateMail = AlternateMail.match(/<[^<>]*@[^<>]*>/); // extract the mail address
if(AlternateMail != null)
{ // if we found a correctly formated mail address
Sender = AlternateMail[0]; // replace the original sender with the real one
j = i;
}
}
if(j!=0) Msg.Attachments.Delete(j); // remove the special GUID named attachment
}
FolderName = ExtractMail(Sender); // Generate the target folder name from the mail address
CreateMailFolder(ParentFolder, FolderName); // and create it
if(Msg.Fields("urn:schemas:mailheader:from").Value.match(Sender) == null)
{ // if the real sender not equals to the original one
// replace the coresponding mail fields
Msg.Fields("urn:schemas:mailheader:from").Value = Msg.Fields("urn:schemas:mailheader:from").Value.replace(/<[^<>]*@[^<>]*>/, Sender);
Msg.Fields("urn:schemas:httpmail:from").Value = Msg.Fields("urn:schemas:httpmail:from").Value.replace(/<[^<>]*@[^<>]*>/, Sender);
Msg.Fields(MAPI_NS_PROPTAG + PR_SENDER_ADDRTYPE).Value = "SMTP";
Msg.Fields(MAPI_NS_PROPTAG + PR_SENDER_EMAIL_ADDRESS).Value = FolderName;
Msg.Fields.Update(); // Write the fields into the memory stream
}
Msg.DataSource.SaveToContainer(ParentFolder + "/" + FolderName); // Save the message to the target folder
DeleteMail(Url); // Delete the original mail
}
/*
ScriptPath()
This function returns the path of the running script's in the filesystem
Parameters:
Nothing
Returns:
The path string
*/
function ScriptPath()
{
var retvalue;
retvalue = WScript.ScriptFullName;
return retvalue.substring(0,retvalue.lastIndexOf("\\"));
}
/*
ExtractMail(mailaddress)
This function extracts the e-mail address from the <name@domain> format
Parameters:
mailaddress - E-mail address in <name@domain> format
Returns:
E-mail address in name@domain format
*/
function ExtractMail(mailaddress)
{
return mailaddress.substring(1,mailaddress.length-1);
}
/*
CreateMailFolder(Url, Name)
This function creates a new mail folder in the Exchange Store if it doesn't exists
Parameters:
Url - Url of the parent folder
Name - Name of the folder
Returns:
0 - If the operation successfull
ERR_ACCESS_DENIED - If you don't have right to create folder
ERR_ALREADY_EXISTS - If the folder already exists
*/
function CreateMailFolder(Url, Name)
{
var ExFolder;
var ExConn;
var retvalue;
retvalue = 0;
ExConn = new ActiveXObject("ADODB.Connection");
ExFolder = new ActiveXObject("ADODB.Record");
ExConn.Provider = "ExOLEDB.DataSource";
ExConn.Open(Url);
try
{
ExFolder.Open(Url + "/" + Name, ExConn, adModeReadWrite, adCreateCollection);
ExFolder.Fields("DAV:contentclass") = "urn:content-classes:mailfolder";
ExFolder.Fields("http://schemas.microsoft.com/exchange/outlookfolderclass") = "IPF.Note";
ExFolder.Fields.Update();
ExFolder.Close();
}
catch(e)
{
retvalue = e.number;
if(e.number != ERR_ALREADY_EXISTS && e.number != ERR_ACCESS_DENIED)
throw(e); // Rethrow the error
}
ExConn.Close();
return retvalue;
}
/*
DeleteMail(Url)
This function deletes a mail from the Exchange Store
Parameters:
Url - Url of the message
Returns:
Nothing
*/
function DeleteMail(Url)
{
var ExConn;
var ExRec;
ExConn = new ActiveXObject("ADODB.Connection");
ExRec = new ActiveXObject("ADODB.Record");
ExConn.Provider = "ExOLEDB.DataSource";
ExConn.Open(Url);
ExRec.Open(Url,ExConn,adModeReadWrite);
ExRec.DeleteRecord(Url);
}
/*
ExStore
This object can be used to navigate thru the Exchange Store
Properties:
Methodes:
ProcessFolder - Iterate thru an Exchange Folder
ProcessMailFolder - Iterate thru an Exchange Mail Folder
Event Handlers:
Event_Mail - Called by the ProcessFolder and the ProcessMailFolder on every containing item
*/
// Initialization
function ExStore_Init()
{
ExStore.prototype.ProcessMailFolder = _ExStore_ProcessMailFolder;
ExStore.prototype.ProcessFolder = _ExStore_ProcessFolder;
}
// Constructor
function ExStore()
{
}
/*
ProcessMailFolder(FolderUrl)
Iterate thru an Exchange Mail Folder
Parameters:
FolderUrl - Url of the Mail folder
Returns:
0 if succed, error code if failed
*/
function _ExStore_ProcessMailFolder(FolderUrl)
{
return this.ProcessFolder(FolderUrl,"\"DAV:ishidden\" = false AND \"DAV:contentclass\" = 'urn:content-classes:message'");
}
/*
ProcessFolder(FolderUrl, Filter)
Iterate thru an Exchange Folder
Parameters:
FolderUrl - Url of the Mail folder
Filter - SQL like filter expression wtich filters the type of the folder
Returns:
0 if succed, error code if failed
*/
*/
function _ExStore_ProcessFolder(FolderUrl, Filter)
{
var SelectStr;
var ExConn;
var retvalue;
retvalue = 0;
if(this.Event_Mail != null)
{
SelectStr = "SELECT \"DAV:href\" FROM SCOPE('SHALLOW TRAVERSAL OF \"" + encodeURI(FolderUrl) + "\"') WHERE " + Filter;
ExConn = new ActiveXObject("ADODB.Connection");
ExRecords = new ActiveXObject("ADODB.RecordSet");
ExConn.Provider = "ExOLEDB.DataSource";
ExConn.Open(FolderUrl);
try
{
ExRecords.Open(SelectStr, ExConn);
for(;!ExRecords.EOF;ExRecords.MoveNext())
this.Event_Mail(ExRecords.Fields("DAV:href").Value);
}
catch(e)
{
retvalue = e.number;
if(e.number != ERR_PERMISSION_DENIED)
throw e; // Rethrow the error
}
ExConn.Close();
}
return retvalue;
}