view release on metacpan or search on metacpan
1.200000  2015-06-14
  * Nothing to report.
1.143070  2014-11-03 21:06:51 Europe/London
  * [#5] ExpandDL support for expanding distribution lists (FunkyShu)
1.141040  2014-04-14 21:05:15 Europe/London
  * Retrieve other user calendar items (retupmoca)
1.131710_001 2013-06-20 23:07:20 Europe/London
  * Retrieval of mailbox folder entries and their sizes (G. Shaw)
  * Calendar invitees will show name and routing in addition to email address (G. Shaw)
1.130570  2013-02-26 20:15:48 Europe/London
  * Next stable release.
examples/demo.pl view on Meta::CPAN
use EWS::Client;
use DateTime;
my $ews = EWS::Client->new({
    server      => 'exchangeserver.example.com',
    username    => 'oliver',
    password    => 's3kr1t', # or set in $ENV{EWS_PASS}
    use_negotiated_auth => 1, # only for NTLM
});
my $entries = $ews->calendar->retrieve({
    start => DateTime->now(),
    end   => DateTime->now->add( months => 1 ),
});
print "I retrieved ". $entries->count ." items\n";
while ($entries->has_next) {
    my $e = $entries->next;
    print $e->Subject, ' at ', $e->Start, "\n";
}
lib/EWS/Calendar/Role/RetrieveWithinWindow.pm view on Meta::CPAN
    croak "Fault returned from Exchange Server: ($opts->{impersonate}) $response->{Fault}->{faultstring}\n"
        if ( exists $response->{Fault} );
    foreach my $msg ( $self->_list_messages($kind, $response) ) {
        my $code = $msg->{"${kind}ResponseMessage"}->{ResponseCode} || '';
        croak "Fault returned from Exchange Server: ($opts->{impersonate}) $code\n"
            if $code ne 'NoError';
    }
}
sub _list_calendaritems {
    my ($self, $kind, $response) = @_;
    return map { $_->{CalendarItem} }
           map { @{ $_->{Items}->{cho_Item} || [] } }
           map { exists $_->{RootFolder} ? $_->{RootFolder} : $_ } 
           map { $_->{"${kind}ResponseMessage"} }
               $self->_list_messages($kind, $response);
}
# Find list of items within the view, then Get details for each one
lib/EWS/Calendar/Role/RetrieveWithinWindow.pm view on Meta::CPAN
            Version => $self->client->server_version,
        },
        Traversal => 'Shallow',
        ItemShape => {
            BaseShape => 'IdOnly',
        },
        ParentFolderIds => {
            cho_FolderId => [
                { DistinguishedFolderId =>
                    {
                        Id => "calendar",
                        (exists $opts->{email} ? (
                            Mailbox => {
                                EmailAddress => $opts->{email},
                            },
                        ) : ()), # optional
                    },
                },
            ],
        },
        CalendarView => {
lib/EWS/Calendar/Role/RetrieveWithinWindow.pm view on Meta::CPAN
            EndDate   => $opts->{window}->end->iso8601,
        },
    );
    return EWS::Calendar::ResultSet->new({items => []})
        if !defined $find_response;
    $self->_check_for_errors('FindItem', $find_response, $opts);
    my @ids = map { $_->{ItemId}->{Id} }
                  $self->_list_calendaritems('FindItem', $find_response);
    my @items;
    # Exchange (at least versions 2007,2010) have a limit of 250 items for a
    # GetItem call. To be safe, we just pull 200 items at a time until we fetch
    # everything
    while (@ids) {
        my $get_response = scalar $self->client->GetItem->(
            (exists $opts->{impersonate} ? (
                Impersonation => {
lib/EWS/Calendar/Role/RetrieveWithinWindow.pm view on Meta::CPAN
            },
            ItemShape => {
                BaseShape => 'IdOnly',
                AdditionalProperties => {
                    cho_Path => [
                        map {{
                            FieldURI => {
                                FieldURI => $_, 
                            },  
                        }} qw/ 
                            calendar:Start
                            calendar:End
                            item:Subject
                            calendar:Location
                            calendar:CalendarItemType
                            calendar:Organizer
                            item:Sensitivity
                            item:DisplayTo
                            calendar:AppointmentState
                            calendar:IsAllDayEvent
                            calendar:LegacyFreeBusyStatus
                            item:IsDraft
                            item:Body
                            calendar:OptionalAttendees
                            calendar:RequiredAttendees
                            calendar:Duration
                            calendar:UID
                        /,
                    ],
                },
            },
            ItemIds => {
                cho_ItemId => [
                    map {{
                        ItemId => { Id => $_ },
                    }} splice(@ids, 0, 200)
                ],
            },
        );
        $self->_check_for_errors('GetItem', $get_response, $opts);
        push(@items, $self->_list_calendaritems('GetItem', $get_response));
    }
    return EWS::Calendar::ResultSet->new({ items => [ @items ] });
}
no Moose::Role;
1;
lib/EWS/Client.pm view on Meta::CPAN
    is => 'ro',
    isa => 'EWS::Client::Contacts',
    lazy_build => 1,
);
sub _build_contacts {
    my $self = shift;
    return EWS::Client::Contacts->new({ client => $self });
}
has calendar => (
    is => 'ro',
    isa => 'EWS::Client::Calendar',
    lazy_build => 1,
);
sub _build_calendar {
    my $self = shift;
    return EWS::Client::Calendar->new({ client => $self });
}
has folders => (
    is => 'ro',
    isa => 'EWS::Client::Folder',
    lazy_build => 1,
);
lib/EWS/Client.pm view on Meta::CPAN
 use DateTime;
 
 my $ews = EWS::Client->new({
     server      => 'exchangeserver.example.com',
     username    => 'oliver',
     password    => 's3krit', # or set in $ENV{EWS_PASS}
 });
Then perform operations on the Exchange server:
 my $entries = $ews->calendar->retrieve({
     start => DateTime->now(),
     end   => DateTime->now->add( months => 1 ),
 });
 
 print "I retrieved ". $entries->count ." items\n";
 
 while ($entries->has_next) {
     print $entries->next->Subject, "\n";
 }
 
 my $contacts = $ews->contacts->retrieve;
=head1 DESCRIPTION
This module acts as a client to the Microsoft Exchange Web Services API. From
here you can access calendar and contact entries in a nicely abstracted
fashion. Query results are generally available in an iterator and convenience
methods exist to access the properties of each entry.
=head1 AUTHENTICATION
Depending on the configuration of the Microsoft Exchange server, you can use
either HTTP Basic Access Auth, or NTLM Negotiated Auth, from this module. The
default is HTTP Basic Access Auth, so if using NTLM, the following additional
option to C<new()> is required:
 use_negotiated_auth => 1,
=head1 METHODS
=head2 EWS::Client->new( \%arguments )
Instantiates a new EWS client. There won't be any connection to the server
until you call one of the calendar or contacts retrieval methods.
=over 4
=item C<server> => Fully Qualified Domain Name (required)
The host name of the Exchange server to which the module should connect.
=item C<username> => String (required)
The account username under which the module will connect to Exchange.
lib/EWS/Client.pm view on Meta::CPAN
API. They are shipped with this module so your providing this is optional.
=item C<server_version> => String (optional)
In each request to the server is specified the API version we expect to use.
By default this is set to C<Exchange2007_SP1> but you have the opportunity to
set it to C<Exchange2007> if you wish using this option.
=back
=head2 $ews->calendar()
Retrieves the L<EWS::Client::Calendar> object which allows search and
retrieval of calendar entries and their various properties. See that linked
manual page for more details.
=head2 $ews->contacts()
Retrieves the L<EWS::Client::Contacts> object which allows retrieval of
contact entries and their telephone numbers. See that linked manual page for
more details.
=head2 $ews->folders()
lib/EWS/Client/Calendar.pm view on Meta::CPAN
 use EWS::Client;
 use DateTime;
 
 my $ews = EWS::Client->new({
     server      => 'exchangeserver.example.com',
     username    => 'oliver',
     password    => 's3krit', # or set in $ENV{EWS_PASS}
 });
Then perform operations on the calendar entries:
 my $entries = $ews->calendar->retrieve({
     start => DateTime->now(),
     end   => DateTime->now->add( months => 1 ),
 });
 
 print "I retrieved ". $entries->count ." items\n";
 
 while ($entries->has_next) {
     print $entries->next->Subject, "\n";
 }
=head1 DESCRIPTION
This module allows you to perform operations on the calendar entries in a
Microsoft Exchange server. At present only read operations are supported,
allowing you to retrieve calendar entries within a given time window. The
results are available in an iterator and convenience methods exist to access
the properties of each entry.
=head1 METHODS
=head2 CONSTRUCTOR
=head2 EWS::Client::Calendar->new( \%arguments )
You would not normally call this constructor. Use the L<EWS::Client>
constructor instead.
Instantiates a new calendar reader. Note that the action of performing a query
for a set of results is separated from this step, so you can perform multiple
queries using this same object. Pass the following arguments in a hash ref:
=over 4
=item C<client> => C<EWS::Client> object (required)
An instance of C<EWS::Client> which has been configured with your server
location, user credentials and SOAP APIs. This will be stored as a weak
reference.
=back
=head2 QUERY AND RESULT SET
=head2 $cal->retrieve( \%arguments )
Query the Exchange server and retrieve calendar entries between the given
timestamps. Pass the following arguments in a hash ref:
=over 4
=item C<start> => DateTime object (required)
Entries with an end date on or after this timestamp will be included in the
returned results.
=item C<end> => DateTime object (required)
lib/EWS/Client/Calendar.pm view on Meta::CPAN
=item C<impersonate> => String (optional)
Passing the primary SMTP address of another account will retrieve the entries
for that Exchange user instead, assuming you have sufficient rights to
I<Impersonate> that account. If you do not have rights, an error will be
thrown.
=back
The returned object contains the collection of calendar entries which matched
the start and end criteria, and is of type C<EWS::Calendar::ResultSet>. It's
an iterator, so you can walk through the list of entries (see the synposis,
above). For example:
 my $entries = $cal->retrieve({start => '', end => ''});
=head2 $entries->next
Provides the next item in the collection of calendar entries, or C<undef> if
there are no more items to return. Usually used in a loop along with
C<has_next> like so:
 while ($entries->has_next) {
     print $entries->next->Subject, "\n";
 }
=head2 $entries->peek
Returns the next item without moving the state of the iterator forward. It
lib/EWS/Client/Calendar.pm view on Meta::CPAN
Returns an array ref containing all the entries returned by the C<retrieve>
server query. They are each objects of type C<EWS::Calendar::Item>.
=head2 ITEM PROPERTIES
These descriptions are taken from Microsoft's on-line documentation.
=head2 $item->Start
A L<DateTime> object representing the starting date and time for a calendar
item.
=head2 $item->End
A L<DateTime> object representing the ending date and time for a calendar
item.
=head2 $item->TimeSpan
A human readable description of the time span of the event, for example:
=over 4
=item * 25 Feb 2010
=item * Feb 16 - 19, 2010
=item * 24 Feb 2010 15:00 - 16:00
=back
=head2 $item->Subject
Represents the subject of a calendar item.
=head2 $item->Body (optional)
Text attachment to the calendar entry which the user may have entered content
into.
=head2 $item->has_Body
Will return true if the event item has content in its Body property, otherwise
returns false. Actually returns the length of the Body text content.
=head2 $item->Location (optional)
Friendly name for where a calendar item pertains to (e.g., a physical address
or "My Office").
=head2 $item->has_Location
Will return true if the event item has content in its Location property,
otherwise returns false. Actually returns the length of the Location text
content.
=head2 $item->Type
The type of calendar item indicating its relationship to a recurrence, if any.
This will be a string value of one of the following, only:
=over 4
=item * Single
=item * Occurrence
=item * Exception
lib/EWS/Client/Calendar.pm view on Meta::CPAN
=item * Personal
=item * Private
=item * Confidential
=back
=head2 $item->DisplayTo (optional)
When a client creates a calendar entry, there can be other people invited to
the event (usually via the To: box in Outlook, or similar). This property
contains an array ref of the display names ("Firstname Lastname") or the
parties invited to the event.
=head2 $item->has_DisplayTo
Will return true if there are entries in the C<< $item->DisplayTo >> property,
in other words there were invitees on this event, otherwise returns false.
Actually returns the number of entries in that list, which may be useful.
=head2 $item->Organizer
The display name (probably "Firstname Lastname") of the party responsible for
creating the entry.
=head2 $item->IsCancelled
True if the calendar item has been cancelled, otherwise false.
=head2 $item->AppointmentState
Contains a bitmask of flags on the entry, but you probably want to use
C<IsCancelled> instead.
=head2 $item->Status (optional)
Free/busy status for a calendar item, which can actually be one of the
following four string values:
=over 4
=item * Free
=item * Tentative
=item * Busy
lib/EWS/Client/Calendar.pm view on Meta::CPAN
This is an alias (the native name, in fact) for the C<< $item->Status >>
property.
=head2 $item->IsDraft
Indicates whether an item has not yet been sent.
=head2 $item->IsAllDayEvent
True if a calendar item is to be interpreted as lasting all day, otherwise
false.
=head1 TODO
There is currently no handling of time zone information whatsoever. I'm
waiting for my timezone to shift to UTC+1 in March before working on this, as
I don't really want to read the Exchange API docs. Patches are welcome if you
want to help out.
=head1 SEE ALSO
share/ews-types.xsd view on Meta::CPAN
      <xs:enumeration value="meeting:HasBeenProcessed"/>
      <xs:enumeration value="meeting:ResponseType"/>
      <!-- Meeting Request -->
      <xs:enumeration value="meetingRequest:MeetingRequestType"/>
      <xs:enumeration value="meetingRequest:IntendedFreeBusyStatus"/>
      <!-- Calendar items and appointments -->
      <xs:enumeration value="calendar:Start"/>
      <xs:enumeration value="calendar:End"/>
      <xs:enumeration value="calendar:OriginalStart"/>
      <xs:enumeration value="calendar:IsAllDayEvent"/>
      <xs:enumeration value="calendar:LegacyFreeBusyStatus"/>
      <xs:enumeration value="calendar:Location"/>
      <xs:enumeration value="calendar:When"/>
      <xs:enumeration value="calendar:IsMeeting"/>
      <xs:enumeration value="calendar:IsCancelled"/>
      <xs:enumeration value="calendar:IsRecurring"/>
      <xs:enumeration value="calendar:MeetingRequestWasSent"/>
      <xs:enumeration value="calendar:IsResponseRequested"/>
      <xs:enumeration value="calendar:CalendarItemType"/>
      <xs:enumeration value="calendar:MyResponseType"/>
      <xs:enumeration value="calendar:Organizer"/>
      <xs:enumeration value="calendar:RequiredAttendees"/>
      <xs:enumeration value="calendar:OptionalAttendees"/>
      <xs:enumeration value="calendar:Resources"/>
      <xs:enumeration value="calendar:ConflictingMeetingCount"/>
      <xs:enumeration value="calendar:AdjacentMeetingCount"/>
      <xs:enumeration value="calendar:ConflictingMeetings"/>
      <xs:enumeration value="calendar:AdjacentMeetings"/>
      <xs:enumeration value="calendar:Duration"/>
      <xs:enumeration value="calendar:TimeZone"/>
      <xs:enumeration value="calendar:AppointmentReplyTime"/>
      <xs:enumeration value="calendar:AppointmentSequenceNumber"/>
      <xs:enumeration value="calendar:AppointmentState"/>
      <xs:enumeration value="calendar:Recurrence"/>
      <xs:enumeration value="calendar:FirstOccurrence"/>
      <xs:enumeration value="calendar:LastOccurrence"/>
      <xs:enumeration value="calendar:ModifiedOccurrences"/>
      <xs:enumeration value="calendar:DeletedOccurrences"/>
      <xs:enumeration value="calendar:MeetingTimeZone"/>
      <xs:enumeration value="calendar:ConferenceType"/>
      <xs:enumeration value="calendar:AllowNewTimeProposal"/>
      <xs:enumeration value="calendar:IsOnlineMeeting"/>
      <xs:enumeration value="calendar:MeetingWorkspaceUrl"/>
      <xs:enumeration value="calendar:NetShowUrl"/>
      <xs:enumeration value="calendar:UID"/>
      <xs:enumeration value="calendar:RecurrenceId"/>
      <xs:enumeration value="calendar:DateTimeStamp"/>
      
      <!-- Task properties -->
      <xs:enumeration value="task:ActualWork"/>
      <xs:enumeration value="task:AssignedTime"/>
      <xs:enumeration value="task:BillingInformation"/>
      <xs:enumeration value="task:ChangeCount"/>
      <xs:enumeration value="task:Companies"/>
      <xs:enumeration value="task:CompleteDate"/>
      <xs:enumeration value="task:Contacts"/>
share/ews-types.xsd view on Meta::CPAN
  <!-- Folder classes -->
  <xs:simpleType name="FolderClassType">
    <xs:restriction base="xs:string" />
  </xs:simpleType>
  <xs:simpleType name="DistinguishedFolderIdNameType">
    <xs:annotation>
      <xs:documentation>URIs for the distinguished folders accessible from a mailbox</xs:documentation>
    </xs:annotation>
    <xs:restriction base="xs:string">
      <xs:enumeration value="calendar" />
      <xs:enumeration value="contacts" />
      <xs:enumeration value="deleteditems" />
      <xs:enumeration value="drafts" />
      <xs:enumeration value="inbox" />
      <xs:enumeration value="journal" />
      <xs:enumeration value="notes" />
      <xs:enumeration value="outbox" />
      <xs:enumeration value="sentitems" />
      <xs:enumeration value="tasks" />
      <xs:enumeration value="msgfolderroot" />
share/ews-types.xsd view on Meta::CPAN
      <xs:element name="Start" type="xs:dateTime" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="NonEmptyArrayOfDeletedOccurrencesType">
    <xs:sequence>
      <xs:element name="DeletedOccurrence" type="t:DeletedOccurrenceInfoType" maxOccurs="unbounded" />
    </xs:sequence>
  </xs:complexType>
  <!-- The main calendar item from which all others derive -->
  <xs:complexType name="CalendarItemType">
    <xs:complexContent>
      <xs:extension base="t:ItemType">
        <xs:sequence>
          <!-- iCalendar properties -->
          <xs:element name="UID" type="xs:string" minOccurs="0" />
          <xs:element name="RecurrenceId" type="xs:dateTime" minOccurs="0" />