none
E-mail based sharing - EWS to multipart form data RRS feed

  • Question

  • I've been searching for sample code for a while, but to no avail. Here's the scenario:

    - users share images from mobile phones using e-mail sharing.

    - on Exchange Server 2010 a mailbox is configured to receive these messages.

    - we need a trigger on the Exchange Server that will fire on new mail arriving in said mailbox.

    - a script should distinguish sender address, subject, and attachment.

    - the script should convert these 3 elements to a multipart/form-data http POST request.

    - the POST request should be submitted to a web-based handler, which will do the necessary to make sure the image is saved on a webserver and an accompanying record is created in a database. The handler exists and currently works from an HTML form.

    What I can't find out: how to trigger the script to run on the Exchange server (through EWS that is, I can do it with SMTP hooks, but those were deprecated); how to convert the mail item fields to form data.

    Any help greatly appreciated.

    Wednesday, July 10, 2013 1:17 PM

All replies

  • To trigger something to happen after a message has arrived in a Mailbox you should look at EWS notifications. On 2010 you can use Streaming notifications http://msdn.microsoft.com/en-us/library/exchange/hh312849(v=exchg.140).aspx .

    Generally you would be better to write an application for this see http://ewsstreaming.codeplex.com/ which is a good sample. You can also do it in Powershell eg

    ## Get the Mailbox to Access from the 1st commandline argument
    $MailboxName = $args[0]
    
    ## Load Managed API dll  
    Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll"  
      
    ## Set Exchange Version  
    $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2  
      
    ## Create Exchange Service Object  
    $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)  
      
    ## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials  
      
    #Credentials Option 1 using UPN for the windows Account  
    $psCred = Get-Credential  
    $creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())  
    $service.Credentials = $creds      
      
    #Credentials Option 2  
    #service.UseDefaultCredentials = $true  
      
    ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates  
      
    ## Code From http://poshcode.org/624
    ## Create a compilation environment
    $Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
    $Compiler=$Provider.CreateCompiler()
    $Params=New-Object System.CodeDom.Compiler.CompilerParameters
    $Params.GenerateExecutable=$False
    $Params.GenerateInMemory=$True
    $Params.IncludeDebugInformation=$False
    $Params.ReferencedAssemblies.Add("System.DLL") | Out-Null
    
    $TASource=@'
      namespace Local.ToolkitExtensions.Net.CertificatePolicy{
        public class TrustAll : System.Net.ICertificatePolicy {
          public TrustAll() { 
          }
          public bool CheckValidationResult(System.Net.ServicePoint sp,
            System.Security.Cryptography.X509Certificates.X509Certificate cert, 
            System.Net.WebRequest req, int problem) {
            return true;
          }
        }
      }
    '@ 
    $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
    $TAAssembly=$TAResults.CompiledAssembly
    
    ## We now create an instance of the TrustAll and attach it to the ServicePointManager
    $TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
    [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll
    
    ## end code from http://poshcode.org/624
      
    ## Set the URL of the CAS (Client Access Server) to use two options are availbe to use Autodiscover to find the CAS URL or Hardcode the CAS to use  
      
    #CAS URL Option 1 Autodiscover  
    $service.AutodiscoverUrl($MailboxName,{$true})  
    "Using CAS Server : " + $Service.url   
       
    #CAS URL Option 2 Hardcoded  
      
    #$uri=[system.URI] "https://casservername/ews/exchange.asmx"  
    #$service.Url = $uri    
      
    ## Optional section for Exchange Impersonation  
      
    #$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName) 
    
    
    $fldArray = new-object Microsoft.Exchange.WebServices.Data.FolderId[] 1  
    $Inboxid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)  
    $fldArray[0] = $Inboxid  
    $stmsubscription = $service.SubscribeToStreamingNotifications($fldArray, [Microsoft.Exchange.WebServices.Data.EventType]::NewMail)  
    $stmConnection = new-object Microsoft.Exchange.WebServices.Data.StreamingSubscriptionConnection($service, 30);  
    $stmConnection.AddSubscription($stmsubscription)  
    Register-ObjectEvent -inputObject $stmConnection -eventName "OnNotificationEvent" -Action {  
        foreach($notEvent in $event.SourceEventArgs.Events){      
            [String]$itmId = $notEvent.ItemId.UniqueId.ToString()  
            $message = [Microsoft.Exchange.WebServices.Data.EmailMessage]::Bind($event.MessageData,$itmId)  
            "Subject : " + $message.Subject + " " + (Get-Date) | Out-File c:\temp\log2.txt -Append   
        }   
    } -MessageData $service  
    Register-ObjectEvent -inputObject $stmConnection -eventName "OnDisconnect" -Action {$event.MessageData.Open()} -MessageData $stmConnection  
    $stmConnection.Open()  
    Cheers
    Glen
    Friday, July 12, 2013 7:06 AM
  • Thanks Glen, this looks promising. I'll look into it.
    Friday, July 12, 2013 8:41 AM