Basic mechanism for "WAP Push" notification application with Exchange Server 2003
When you need to send notifications (server-side) to mobile devices of users about Reminders in their Exchange Calendar or Tasks items, you can get the Reminders information from Exchange Store with the mechanisms inside the code below; try it with a command-line like this one:
HTTPRequest.js SEARCH WebDAVSearchPayload.xml https://exchangeserver/exchange/alias
WebDAVSearchPayload.xml:
<?xml version="1.0"?>
<D:searchrequest xmlns:D="DAV:">
<D:sql>
SELECT "urn:schemas:httpmail:subject","https://schemas.microsoft.com/mapi/remindernexttime"
FROM scope(
'shallow traversal of "https://exchangeserver/exchange/alias/Calendar/" ',
'shallow traversal of "https://exchangeserver/exchange/alias/Tasks/" '
)
WHERE "DAV:ishidden" = false
AND "DAV:isfolder" = false
AND "https://schemas.microsoft.com/mapi/reminderset" = true
AND
"https://schemas.microsoft.com/mapi/remindernexttime"
> CAST("2005-07-06T17:00:00Z" as "dateTime.tz")
AND
"https://schemas.microsoft.com/mapi/remindernexttime"
< CAST("2005-07-06T17:00:10Z" as "dateTime.tz")
</D:sql>
</D:searchrequest>
HTTPRequest.js:
var method=WScript.Arguments(0)
var xml=WScript.Arguments(1)
var url=WScript.Arguments(2)
WScript.Echo("Sending "+method+" "+xml+" to "+url)
var requestdoc=new ActiveXObject("MSXML2.DOMDocument.5.0")
requestdoc.async=false
requestdoc.load(xml)
var request=new ActiveXObject("MSXML2.ServerXMLHTTP.5.0")
request.open(method,url,false,"domain\\alias","here-go-a-secret")
request.setRequestHeader("Content-Type","text/xml")
request.send(requestdoc)
WScript.Echo("status:"+request.status)
WScript.Echo("statusText:"+request.statusText)
WScript.Echo("responseXML:"+request.responseXML.xml)
A sample response is:
<?xml version="1.0" ?>
<a:multistatus
xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/"
xmlns:e="https://schemas.microsoft.com/mapi/"
xmlns:d="urn:schemas:httpmail:" xmlns:c="xml:" xmlns:a="DAV:">
<a:response>
<a:href>https://exchangeserver/exchange/alias/Tasks/testtask1.EML</a:href>
<a:propstat>
<a:status>HTTP/1.1 200 OK</a:status>
<a:prop>
<d:subject>testtask1</d:subject>
<e:remindernexttime b:dt="dateTime.tz">2005-07-05T21:00:00.000Z</e:remindernexttime>
</a:prop>
</a:propstat>
</a:response>
<a:response>
<a:href>https://exchangeserver/exchange/alias/Calendar/AnAppointment.EML</a:href>
<a:propstat>
<a:status>HTTP/1.1 200 OK</a:status>
<a:prop>
<d:subject>AnAppointment</d:subject>
<e:remindernexttime b:dt="dateTime.tz">2005-07-05T22:35:00.000Z</e:remindernexttime>
</a:prop>
</a:propstat>
</a:response>
</a:multistatus>
Then with subject and remindernexttime property values you can send a notification to any wireless gateway.
The above HTTP WebDAV Request code uses basic authentication so the credentials travel naked. System.Net.HttpWebRequest and System.Net.CredentialCache.DefaultCredentials would be a better alternative.
The following code is a managed version of the HTTPRequest above:
HTTPRequest.cs:
using System;
using System.IO;
using System.Net;
using System.Xml;
using w=System.Console;
class exe
{
static void Main(string[] args)
{
try
{
string method=args[0];
string xml=args[1];
string url=args[2];
w.WriteLine("Sending "+method+" "+xml+" to "+url);
XmlDocument requestdoc=new XmlDocument();
requestdoc.Load(xml);
HttpWebRequest request=WebRequest.Create(url) as HttpWebRequest;
request.Credentials=CredentialCache.DefaultCredentials;
request.Method=method;
request.ContentType="text/xml";
request.ContentLength=requestdoc.InnerXml.Length;
Stream payload=request.GetRequestStream();
byte[] bytes=System.Text.Encoding.ASCII.GetBytes(requestdoc.InnerXml);
payload.Write(bytes,0,bytes.Length);
HttpWebResponse resp=request.GetResponse() as HttpWebResponse;
StreamReader r=new StreamReader(resp.GetResponseStream());
w.WriteLine(r.ReadToEnd());
}
catch(Exception err)
{
w.WriteLine(err);
}
}
}