send meeting request to a resource
hy,
The next code send a meeting request. It must reserve a ressource
automaticaly, but it don't do it. It's necessary to accept manualy the
request. why?
For a manualy meeting request, all is ok.
I think there is a problem with the header on the CreateMeetingRequest
sub :
[...]
strHeaderInfo = "<header:to>" & strReqAttendees & "</
header:to>" & _
"<header:cc>" & strOptAttendees & "</header:cc>" & _
"<header:bcc>" & strMtgResources & "</header:bcc>"
[...]
Someone can confirme or not that I must use "<header:bcc>" for the
resources?
thank you.
'************************************************************************************
'* SUB : CreateMeetingRequest( ByVal strExchSvrName, ByVal
strMailbox, _
'* ByVal strReqAttendees, ByVal
strOptAttendees, ByVal strMtgResources, _
'* ByVal strUserName, ByVal
strPassWord, _
'* ByVal ApptDateStart, ByVal
ApptDateEnd, ByVal ApptBusyStatus, _
'* ByVal ApptMeetingStatus, ByVal
ApptSubject, ByVal ApptLocation, _
'* ByVal ApptItem, ByVal Periodicity
As Boolean, ByVal PeriodFREQ As String, _
'* ByVal PeriodCOUNT As Integer,
ByVal PeriodINTERVAL As Integer, ByVal PeriodBYDAY As String, _
'* ByVal PeriodWKST As String)
'*
'* Input : - strExchSvrName As String : Exchange server name
'* strMailbox As String : Mailbox folder of the
meeting organizer
'* CalendarFolder As String : Calendar folder used
'* strReqAttendees As String : Required meeting
attendees
'* strOptAttendees As String : Optional meeting
attendees
'* strMtgResources As String : Meeting resources
'* strUserName As String : Username of meeting
creator
'* strPassWord As String : password of meeting
creator
'* ApptDateStart As String : Date Start of meeting
("2007-10-25T10:37:00.000Z")
'* ApptDateEnd, As String : Date End of meeting
("2007-10-25T11:37:00.000Z")
'* ApptBusyStatus As String : Busy Status
'* ApptMeetingStatus As String : Meeting Status
'* ApptSubject, As String : Meeting Subject
'* ApptLocation As String : Meeting Location
'* ApptItem As String : Meeting Filename.eml
'* Periodicity As Boolean : Periodicity of the
meetings (ex : "True")
'* PeriodFREQ As String : Frequency of the
periodicity (ex : "DAILY")
'* PeriodCOUNT As Integer : Interval count of
periodicity (ex : "5")
'* PeriodINTERVAL As Integer : Interval (ex : "1")
'* PeriodBYDAY As String : Day of the
periodicity (ex : "MO,TU,WE,TH,FR")
'* PeriodWKST As String : Week start (ex :
"SU")
'* ExceptedDate As String : Excepted dates (ex :
"<x:v>2007-11-15T00:00:00.000Z</x:v><x:v>2007-11-21T00:00:00.000Z</
x:v>")
'* Caution : The
excepted dates must exist on the appointment dates created.
'*
'* Output : - Return string : format date like aaaa-mm-jjThh:mm:ss.
000Z
'*
'************************************************************************************
Sub CreateMeetingRequest(ByVal strExchSvrName As String, ByVal
strMailbox As String, ByVal CalendarFolder As String, _
ByVal strReqAttendees As String, ByVal
strOptAttendees As String, ByVal strMtgResources As String, _
ByVal strUserName As String, ByVal
strPassWord As String, _
ByVal ApptDateStart As String, ByVal
ApptDateEnd As String, ByVal ApptBusyStatus As String, _
ByVal ApptMeetingStatus As String, ByVal
ApptSubject As String, ByVal ApptLocation As String, _
ByVal ApptItem As String, ByVal
Periodicity As Boolean, ByVal PeriodFREQ As String, _
ByVal PeriodUNTIL As String, ByVal
PeriodINTERVAL As Integer, ByVal PeriodBYDAY As String, _
ByVal PeriodWKST As String, ByVal
ExceptedDate As String)
'http://msdn.microsoft.com/library/default.asp?url=/library/en-
us/e2k3/e2k3/_sending_a_meeting_request_webdav.asp
'Need to add msxml6.dll : http://forums.asp.net/p/1060342/1522104.aspx
'for this go to project/build/add_reference/browse and select
the c:\windows\system32\msxml6.dll)
'or add reference : Microsft XML,v6.0
'Sub SendMeetingRequest()
' Variables
Dim strMtgUri As String
Dim strMtgRequestUri As String
Dim strMtgRequest As String
Dim strCalInfo As String
Dim strHeaderInfo As String
Dim strMailInfo As String
Dim strXMLNSInfo As String
Dim bResult As Boolean
Dim strUID As String
Dim strCCInfo As String
Dim strMapiInfo As String
Dim strSubmissionUri As String
'' Exchange server name.
'strExchSvrName = "eint11" '"ExchangeServer"
'' Mailbox folder of the meeting organizer.
'strMailbox = "mfz@heig-vd.ch" '"user1@example.com"
'' Required meeting attendees.
'strReqAttendees = "mfz-full@heig-vd.ch"
'"user1@example.com;user2@example.com"
'' Optional meeting attendees.
'strOptAttendees = "mfz-full@heig-vd.ch; miguel-
angel.fernandez@heig-vd.ch" '"user3@example.com"
'' Meeting resources
'strMtgResources = "" '"meetingroom1@example.com"
'' Username and password of meeting creator.
'strUserName = "einet\mfz" '"Domain\user1"
'strPassWord = "+Usr75Mfz" '"!Password"
' Conversion DateTime to UTC time for the appointment creation
on Exchange server
ApptDateStart =
ConvertFormatDateTimeToDateAppt(CDate(ConvertFormatDateApptToDateTime(ApptDateStart)).ToUniversalTime().ToString())
ApptDateEnd =
ConvertFormatDateTimeToDateAppt(CDate(ConvertFormatDateApptToDateTime(ApptDateEnd)).ToUniversalTime().ToString())
' URI of the meeting item.
strMtgUri = "http://" & strExchSvrName & "/exchange/" & _
strMailbox & "/" & CalendarFolder & "/" & ApptItem
' URI of the meeting request item.
strMtgRequestUri = "http://" & strExchSvrName & "/exchange/" &
_
strMailbox & "/" & CalendarFolder & "/" & "Request_" &
ApptItem
' XML namespace info for the WebDAV request.
strXMLNSInfo = "xmlns:g=""DAV:"" " & _
"xmlns:e=""http://schemas.microsoft.com/exchange/"" " & _
"xmlns:mapi=""http://schemas.microsoft.com/mapi/"" " & _
"xmlns:mapit=""http://schemas.microsoft.com/mapi/proptag/""
" & _
"xmlns:x=""xml:"" xmlns:cal=""urn:schemas:calendar:"" " & _
"xmlns:dt=""urn:uuid:c2f41010-65b3-11d1-
a29f-00aa00c14882/"" " & _
"xmlns:header=""urn:schemas:mailheader:"" " & _
"xmlns:c=""urn:schemas:calendar:timezoneid"" " & _
"xmlns:mail=""urn:schemas:httpmail:"""
If Periodicity Then
' Set the meeting item properties.
strCalInfo = "<cal:location>" & ApptLocation & "</
cal:location>" & _
"<cal:dtstart dt:dt=""dateTime.tz"">" & ApptDateStart &
"</cal:dtstart>" & _
"<cal:dtend dt:dt=""dateTime.tz"">" & ApptDateEnd & "</
cal:dtend>" & _
"<cal:timezoneid dt:dt=""int"">4</cal:timezoneid>" & _
"<cal:instancetype dt:dt=""int"">0</cal:instancetype>"
& _
"<cal:busystatus>" & ApptBusyStatus & "</
cal:busystatus>" & _
"<cal:meetingstatus>" & ApptMeetingStatus & "</
cal:meetingstatus>" & _
"<cal:alldayevent dt:dt=""boolean"">0</
cal:alldayevent>" & _
"<cal:responserequested dt:dt=""boolean"">1</
cal:responserequested>" & _
"<cal:rrule dt:dt=""mv.string"">" & _
"<x:v>FREQ=" & PeriodFREQ & ";UNTIL=" &
DateAMJcompact(PeriodUNTIL) & ";INTERVAL=" & PeriodINTERVAL & _
";BYDAY=" & PeriodBYDAY & ";WKST=" & PeriodWKST & "</
x:v>" & _
"</cal:rrule>" & _
"<cal:exdate dt:dt=""mv.dateTime.tz"">" & _
ExceptedDate & _
"</cal:exdate>" & _
"<cal:reminderoffset dt:dt=""int"">2</cal:reminderoffset>"
Else
' Set the meeting item properties.
strCalInfo = "<cal:location>" & ApptLocation & "</
cal:location>" & _
"<cal:dtstart dt:dt=""dateTime.tz"">" & ApptDateStart &
"</cal:dtstart>" & _
"<cal:dtend dt:dt=""dateTime.tz"">" & ApptDateEnd & "</
cal:dtend>" & _
"<cal:timezoneid dt:dt=""int"">4</cal:timezoneid>" & _
"<cal:instancetype dt:dt=""int"">0</cal:instancetype>"
& _
"<cal:busystatus>" & ApptBusyStatus & "</
cal:busystatus>" & _
"<cal:meetingstatus>" & ApptMeetingStatus & "</
cal:meetingstatus>" & _
"<cal:alldayevent dt:dt=""boolean"">0</
cal:alldayevent>" & _
"<cal:responserequested dt:dt=""boolean"">1</
cal:responserequested>" & _
"<cal:reminderoffset dt:dt=""int"">2</cal:reminderoffset>"
End If
' Set the required and optional attendees of the meeting
' and the meeting resources.
strHeaderInfo = "<header:to>" & strReqAttendees & "</
header:to>" & _
"<header:cc>" & strOptAttendees & "</header:cc>" & _
"<header:bcc>" & strMtgResources & "</header:bcc>"
' Set the subject of the meeting.
strMailInfo = "<mail:subject>" & ApptSubject & "</
mail:subject>" & _
"<mail:htmldescription>" & ApptLocation & "</
mail:htmldescription>"
' Build the XML body of the PROPPATCH request.
strMtgRequest = "<?xml version=""1.0""?>" & _
"<g:propertyupdate " & strXMLNSInfo & ">" & _
"<g:set><g:prop>" & _
"<g:contentclass>urn:content-classes:appointment</
g:contentclass>" & _
"<e:outlookmessageclass>IPM.Appointment</
e:outlookmessageclass>" & _
strMailInfo & _
strCalInfo & _
strHeaderInfo & _
"<mapi:finvited dt:dt=""boolean"">1</mapi:finvited>" & _
"</g:prop></g:set>" & _
"</g:propertyupdate>"
bResult = False
' Create the meeting item in the organizer's calendar folder.
bResult = CreateMeeting(strMtgUri, _
strMtgRequest, _
strUserName, _
strPassWord)
If bResult Then
' Get urn:schemas:calendar:uid property, which needs to be
included in the meeting request.
strUID = FindMeetingUID(strMtgUri, _
strMailbox, _
strPassWord)
If strUID <> "" Then
' Set the meeting request item contentclass and
outlookmessage class properties.
strCCInfo = "<g:contentclass>urn:content-
classes:calendarmessage</g:contentclass>" & _
"<e:outlookmessageclass>IPM.Schedule.Meeting.Request</
e:outlookmessageclass>"
' Set the meeting request item MAPI properties.
strMapiInfo = "<mapi:finvited dt:dt=""boolean"">1</
mapi:finvited>" & _
"<mapi:responsestatus dt:dt=""int"">1</
mapi:responsestatus>" & _
"<mapi:responsestate dt:dt=""int"">0</
mapi:responsestate>" & _
"<mapi:response_requested dt:dt=""boolean"">1</
mapi:response_requested>" & _
"<mapi:apptstateflags dt:dt=""int"">3</
mapi:apptstateflags>" & _
"<mapi:busystatus dt:dt=""int"">1</
mapi:busystatus>" & _
"<mapi:intendedbusystatus dt:dt=""int"">2</
mapi:intendedbusystatus>"
' Build the XML request body of the meeting request
item.
strMtgRequest = "<?xml version=""1.0""?>" & _
"<g:propertyupdate " & strXMLNSInfo & ">" & _
"<g:set>" & _
"<g:prop>" & _
strCCInfo & _
strMailInfo & _
strCalInfo & "<cal:uid>" & strUID & "</
cal:uid>" & _
strHeaderInfo & _
strMapiInfo & _
"</g:prop>" & _
"</g:set>" & _
"</g:propertyupdate>"
' Create the meeting request item in the organizer's
calendar.
bResult = False
bResult = CreateMeeting(strMtgRequestUri, _
strMtgRequest, _
strMailbox, _
strPassWord)
If bResult Then
' Build the mail submission URI of the meeting
organizer.
strSubmissionUri = "http://" & strExchSvrName & "/
exchange/" & _
strMailbox & "/##DavMailSubmissionURI##/"
' MOVE the meeting request item to mail submission
URI (send
' the meeting request).
bResult = False
bResult = SubmitMeetingRequest(strMtgRequestUri, _
strSubmissionUri,
_
strUserName, _
strPassWord)
End If
End If
End If
End Sub
'************************************************************************************
'* FUNCTION : CreateMeeting( _
'* ByVal strURL, _
'* ByVal strMtgRequest, _
'* ByVal strUserName, _
'* ByVal strPassWord)
'* As Boolean
'*
'* Input :
'* - strURL As String : URI of the meeting item
'* - strMtgRequest As String : Meeting request
'* - strUserName As String : Username of meeting
creator
'* - strPassWord As String : Password of meeting
creator
'*
'*
'* Output : - Return Boolean
'*
'************************************************************************************
Function CreateMeeting( _
ByVal strURL, _
ByVal strMtgRequest, _
ByVal strUserName, _
ByVal strPassWord) As Boolean
' Use MSXML 4.0
Dim xmlReq As MSXML2.XMLHTTP40
On Error GoTo ErrHandler
' Create the XMLHTTP object.
xmlReq = CreateObject("Microsoft.XMLHTTP")
' Open the request object with the PROPPATCH method and
' specify that it will be sent asynchronously.
xmlReq.open("PROPPATCH", strURL, False, strUserName,
strPassWord)
xmlReq.setRequestHeader("Content-Type", "text/xml")
' Send the request.
xmlReq.send(strMtgRequest)
' The PROPPATCH request was successful.
If (xmlReq.status >= 200 And xmlReq.status < 300) Then
'MsgBox("Meeting item created successfully.")
Console.WriteLine("Meeting item created successfully.")
CreateMeeting = True
' Get error info.
Else
MsgBox("CreateMeeting : Meeting item not created
successfully. PROPPATCH status: " & xmlReq.status & _
": " & xmlReq.statusText)
Console.WriteLine("CreateMeeting : Meeting item not
created successfully. PROPPATCH status: " & xmlReq.status & _
": " & xmlReq.statusText)
CreateMeeting = False
End If
ErrExit:
xmlReq = Nothing
Exit Function
ErrHandler:
MsgBox("CreateMeeting ErrHandler: Error creating meeting item:
" & Err.Number & ": " & Err.Description)
Console.WriteLine("CreateMeeting ErrHandler: Error creating
meeting item: " & Err.Number & ": " & Err.Description)
CreateMeeting = False
'Throw New ArgumentException("Error at CreateMeeting." &
Chr(13) & "(" + Err.Number + ": " + Err.Description + ")")
'Exit Function
End Function
'************************************************************************************
'* FUNCTION : FindMeetingUID( _
'* ByVal strURL, _
'* ByVal strMtgRequest, _
'* ByVal strUserName, _
'* ByVal strPassWord)
'* As Boolean
'*
'* Input :
'* - strURL As String : URI of the meeting item
'* - strMtgRequest As String : Meeting request
'* - strUserName As String : Username of meeting
creator
'* - strPassWord As String : Password of meeting
creator
'*
'*
'* Output : - Return Boolean
'*
'************************************************************************************
Function FindMeetingUID(ByVal strURL, _
ByVal strUserName, _
ByVal strPassWord) As String
' Variables.
Dim xmlReq As MSXML2.XMLHTTP40
Dim xmldom As MSXML2.DOMDocument
Dim xmlRoot As MSXML2.IXMLDOMElement
Dim xmlNode As MSXML2.IXMLDOMNode
Dim xmlAttr As MSXML2.IXMLDOMAttribute
Dim strUIDRequest As String
Dim baseName As String
On Error GoTo ErrHandler
' Build the PROPFIND request body.
strUIDRequest = "<?xml version='1.0'?>" & _
"<a:propfind xmlns:a='DAV:'>" & _
"<a:prop xmlns:uid='urn:schemas:calendar:'>" & _
"<uid:uid/>" & _
"</a:prop>" & _
"</a:propfind>"
' Create the XMLHTTP object.
xmlReq = CreateObject("Microsoft.XMLHTTP")
' Open the request object with the PROPFIND method and
' specify that it will be sent asynchronously.
xmlReq.open("PROPFIND", strURL, False, strUserName,
strPassWord)
xmlReq.setRequestHeader("Content-Type", "text/xml")
xmlReq.setRequestHeader("Depth", "0")
' Send the PROPFIND request.
xmlReq.send(strUIDRequest)
' The PROPFIND request was successful.
If (xmlReq.status >= 200 And xmlReq.status < 300) Then
'MsgBox("Meeting item urn:schemas:calendar:uid found.")
' Get the urn:schemas:calendar: from the XML response
body.
xmldom = xmlReq.responseXML
xmlRoot = xmldom.documentElement
For Each xmlAttr In xmlRoot.attributes
If xmlAttr.text = "urn:schemas:calendar:" Then
baseName = xmlAttr.baseName
Exit For
End If
Next
' Extract the urn:schemas:calendar:uid property value.
xmlNode = xmlRoot.selectSingleNode("//" & baseName &
":uid")
FindMeetingUID = xmlNode.text
' Get error info.
Else
MsgBox("FindMeetingUID : Failed to find meeting item
urn:schemas:calendar:uid. " & "PROPFIND status: = " & _
xmlReq.status & ": " & xmlReq.statusText)
Console.WriteLine("FindMeetingUID : Failed to find meeting
item urn:schemas:calendar:uid. " & "PROPFIND status: = " & _
xmlReq.status & ": " & xmlReq.statusText)
FindMeetingUID = ""
End If
ErrExit:
xmlReq = Nothing
xmldom = Nothing
xmlRoot = Nothing
xmlNode = Nothing
xmlAttr = Nothing
Exit Function
ErrHandler:
MsgBox("FindMeetingUID ErrHandler : Error finding meeting item
urn:schemas:calendar:uid. " & Err.Number & ": " & Err.Description)
Console.WriteLine("FindMeetingUID ErrHandler : Error finding
meeting item urn:schemas:calendar:uid. " & Err.Number & ": " &
Err.Description)
FindMeetingUID = ""
End Function
'************************************************************************************
'* FUNCTION : SubmitMeetingRequest( _
'* ByVal strSrcURL, _
'* ByVal strSubmissionURL, _
'* ByVal strMailbox, _
'* ByVal strPassWord)
'* As Boolean
'*
'* Input :
'* - strSrcURL As String : URL of the meeting
Source
'* - strSubmissionURL As String : URL of the meeting
Submission
'* - strMailbox As String : Mailbox folder of the
meeting organizer
'* - strPassWord As String : Password of meeting
creator
'*
'*
'* Output : - Return Boolean
'*
'************************************************************************************
Function SubmitMeetingRequest(ByVal strSrcURL, _
ByVal strSubmissionURL, _
ByVal strMailbox, _
ByVal strPassWord) As Boolean
' Use MSXML 4.0.
Dim xmlReq As MSXML2.XMLHTTP40
On Error GoTo ErrHandler
' Create the XMLHTTP object.
xmlReq = CreateObject("Microsoft.xmlhttp")
' Open the request object with the MOVE method and
' specify that it will be sent asynchronously.
xmlReq.open("MOVE", strSrcURL, False, strMailbox, strPassWord)
xmlReq.setRequestHeader("Destination", strSubmissionURL)
xmlReq.setRequestHeader("Content-Type", "message/rfc822")
' Send the MOVE request.
xmlReq.send()
' The MOVE request was successful.
If (xmlReq.status >= 200 And xmlReq.status < 300) Then
'MsgBox("Meeting request successfully sent.")
SubmitMeetingRequest = True
' Permissions error.
ElseIf xmlReq.status = 401 Then
SubmitMeetingRequest = False
MsgBox("SubmitMeetingRequest : You don't have permission
to send the meeting request.")
Console.WriteLine("SubmitMeetingRequest : You don't have
permission to send the meeting request.")
' Get error info.
Else
SubmitMeetingRequest = False
MsgBox("SubmitMeetingRequest : Meeting request not
successfully sent. MOVE status: " & xmlReq.status & ": " &
xmlReq.statusText)
Console.WriteLine("SubmitMeetingRequest : Meeting request
not successfully sent. MOVE status: " & xmlReq.status & ": " &
xmlReq.statusText)
End If
ErrExit:
xmlReq = Nothing
Exit Function
ErrHandler:
MsgBox("SubmitMeetingRequest ErrHandler : Error sending
meeting request: " & Err.Number & ": " & Err.Description)
Console.WriteLine("SubmitMeetingRequest ErrHandler : Error
sending meeting request: " & Err.Number & ": " & Err.Description)
SubmitMeetingRequest = False
End Function
date: Mon, 26 Nov 2007 07:41:09 -0800 (PST)
author: Angel