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);
  }
 }
}