1NAME
2 WebService::Basecamp - Perl interface to the Basecamp API webservice
3
4SYNOPSIS
5 use WebService::Basecamp;
6
7 my $bc = WebService::Basecamp->new( url => 'http://mysite.clientsection.com',
8 user => 'username',
9 pass => 'password' );
10
11 my $test = $bc->ping || die $bc->error();
12
13 my $projects = $bc->projects; # a list of all projects
14
15DESCRIPTION
16 Basecamp is a web based project collaboration tool that makes it simple
17 to communicate and collaborate on projects. Basecamp is built on the
18 Ruby on Rails platform but provides a webservice API to many of the
19 application functions. WebService::Basecamp is a Perl interface to the
20 Basecamp web service API.
21
22 For more information on Basecamp, visit the Basecamp website.
23 http://www.bascamphq.com.
24
25 This module does much of the heavy lifting for you when accessing the
26 Basecamp API. Once initialising a WebService::Basecamp object you can
27 access the API function via method calls. The module takes care of the
28 creation and parsing of the XML (using XML::Simple) that relays the data
29 across the web service, however there is an option to access the XML
30 directly (see new()).
31
32 The documentation for this module is based on the Basecamp API docs
33 available at http://www.basecamphq.com/api. It is recommended you read
34 the official docs to become familiar with the data reference.
35
36METHODS
37 new(url => $url, user => $username, pass => $password, [ xml => $xml ])
38 Call new() to create a new Basecamp object. You must pass the url of
39 your Basecamp account, a username and password.
40
41 my $bc = WebService::Basecamp->new( url => 'http://mysite.clientsection.com',
42 user => $username,
43 pass => $password );
44
45 By default, all methods return a data reference. If you would prefer
46 to receive the raw XML from the webservice you can pass the 'xml'
47 parameter. E.g.
48
49 my $bc = WebService::Basecamp->new( url => 'http://mysite.clientsection.com',
50 user => $username,
51 pass => $password,
52 xml => 1 );
53
54 error()
55 Returns any error messages as a string.
56
57 ping()
58 Tests the connection with the Basecamp web service. Returns 1 for
59 success.
60
61 General Queries
62 projects([$key])
63 This will return a list of all active, on-hold, and archived
64 projects that you have access to. The list is not ordered.
65
66 This method returns a reference to a hash containing an array of
67 file category names and id.
68
69 use Data::Dumper;
70 my $projects = $bc->projects;
71 print Dumper($projects);
72
73 returns:
74
75 $VAR1 = [
76 {
77 'start-page' => 'all',
78 'show-writeboards' => 'false',
79 'status' => 'active',
80 'name' => 'Create World Peace',
81 'created-on' => '2004-05-31',
82 'last-changed-on' => '2004-09-07T02:49:12Z',
83 'id' => '123456',
84 'announcement' => {},
85 'show-announcement' => 'false',
86 'company' => {
87 'name' => 'Earth',
88 'id' => '888'
89 }
90 },
91 {
92 'start-page' => 'log',
93 'show-writeboards' => 'false',
94 'status' => 'active',
95 'name' => 'Basecamp CPAN Module',
96 'created-on' => '2006-07-26',
97 'last-changed-on' => '2006-07-29T04:08:34Z',
98 'id' => '654321',
99 'announcement' => {},
100 'show-announcement' => 'false',
101 'company' => {
102 'name' => 'Internal',
103 'id' => '555'
104 }
105 }
106 ];
107
108 If you pass the optional $key parameter to the method you will
109 recieve a keyed hash of the project data. The key must be either
110 'name' or 'id', e.g.:
111
112 use Data::Dumper
113 my $projects = $bc->projects('name');
114 print Dumper($projects);
115
116 returns:
117
118 $VAR1 = [
119 'Create World Peace' => {
120 'start-page' => 'all',
121 'status' => 'active',
122 'show-writeboards' => 'false',
123 'created-on' => '2004-05-31',
124 'last-changed-on' => '2004-09-07T02:49:12Z',
125 'show-announcement' => 'false',
126 'id' => '123456',
127 'announcement' => {},
128 'company' => {
129 'name' => 'Earth',
130 'id' => '888'
131 }
132 },
133 'Basecamp CPAN Module' => {
134 'start-page' => 'log',
135 'status' => 'active',
136 'show-writeboards' => 'false',
137 'created-on' => '2006-07-26',
138 'last-changed-on' => '2006-07-29T04:08:34Z',
139 'show-announcement' => 'false',
140 'id' => '654321',
141 'announcement' => {},
142 'company' => {
143 'name' => 'Internal',
144 'id' => '555'
145 }
146 }
147 ];
148
149 file_categories($project_id [,$key])
150 This will return an alphabetical list of all file categories in the
151 referenced project. Requires the $project_id to be passed as an
152 argument.
153
154 By default this method returns a reference to an array of hashes. If
155 you would prefer a keyed hash, you can specify the optional key. The
156 available key options are 'name' or 'id'.
157
158 message_categories($project_id [,$key])
159 This will return an alphabetical list of all message categories in
160 the referenced project. Requires the $project_id to be passed as an
161 argument.
162
163 By default this method returns a reference to an array of hashes. If
164 you would prefer a keyed hash, you can specify the optional key. The
165 available key options are 'name' or 'id'.
166
167 Messages and Comments
168 comment($comment_id)
169 Retrieve a specific comment by its id.
170
171 comments($message_id)
172 Return the list of comments associated with the specified message.
173
174 create_comment($message_id, $comment)
175 Create a new comment, associating it with a specific message.
176 Returns a hash containing all of the comment details.
177
178 my $message_id = 1234;
179 my $comment = "This looks too easy!";
180 my $new_comment = $bc->create_comment($message_id, $comment);
181
182 create_message($project_id, $message)
183 Creates a new message, optionally sending notifications to a
184 selected list of people. The available fields are;
185
186 category_id - the id of the message category
187 title - message title
188 body - summary text of main message
189 extended_body - the main body of the message
190 textile - optional boolean value. Set to '1' to use Basecamp's
191 textile
192 formatting for your message. Defaults to '0'.
193 private - optional boolean value. Set to '1' to make this message
194 visible only to the logged in user. Defaults to '0'.
195 notify - optional list of person ids. Each person in this list will
196 receive an email notification of the message.
197
198 Returns a hash containing all of the message details.
199
200 my $project_id = 1234;
201 my $message = { category_id => 654321,
202 title => 'New Message Title',
203 body => 'This text is a summary of the message',
204 extended_body => 'This is the main body of the message',
205 textile => 1, # optional field
206 private => 0, # optional field
207 notify => qw(1234 5678) # optional field
208 };
209 my $data = $bc->create_message($project_id,$message);
210
211 delete_comment($comment_id)
212 Delete the comment with the given id.
213
214 delete_message($message_id)
215 Delete the specified message from the project.
216
217 message('$message_id, [$message_id2, $message_id3, ...]')
218 This will return information about the referenced message. If the id
219 is given as a comma-delimited list, one record will be returned for
220 each id. In this way you can query a set of messages in a single
221 request. Note that you can only give up to 25 ids per request--more
222 than that will return an error.
223
224 message_archive($project_id)
225 This will return a summary record for each message in a project. If
226 you specify a category_id, only messages in that category will be
227 returned. (Note that a summary record includes only a few bits of
228 information about a post, not the complete record.)
229
230 message_archive_per_category($project_id, $category_id)
231 This will return a summary record for each message in a particular
232 category. (Note that a summary record includes only a few bits of
233 information about a post, not the complete record.)
234
235 update_comment($comment_id, $comment)
236 Update a specific comment. This can be used to edit the content of
237 an existing comment. Returns a hash containing all of the comment
238 details.
239
240 my $comment_id = 99999;
241 my $comment = "This looks too easy!!";
242 my $new_comment = $bc->update_comment($comment_id, $comment);
243
244 update_message($message_id, $message)
245 Updates an existing message, optionally sending notifications to a
246 selected list of people. Available fields are as per the
247 create_message method.
248
249 Returns a hash containing all of the message details.
250
251 To-Do Lists and Items
252 complete_item($item_id)
253 Marks the specified item as "complete". If the item is already
254 completed, this does nothing.
255
256 create_item($list_id, $item_data)
257 This call lets you add an item to an existing list. The item is
258 added to the bottom of the list. If a person is responsible for the
259 item, give their id as the party_id value. If a company is
260 responsible, prefix their company id with a 'c' and use that as the
261 party_id value. If the item has a person as the responsible party,
262 you can use the notify key to indicate whether an email should be
263 sent to that person to tell them about the assignment.
264
265 my $list_id = 4321;
266 my $item_data = { content => "Turn the lights out",
267 party_id => 555,
268 notify => 1 };
269 my $new_item = $bc->create_item($list_id, $item_data);
270
271 Returns a hash containing all of the item details.
272
273 create_list($project_id, $list_data)
274 This will create a new, empty list. You can create the list
275 explicitly, or by giving it a list template id to base the new list
276 off of. The available fields are:
277
278 milestone_id - optional id of an associated milestone
279 private - optional boolean value. Set to '1' to make this list visible
280 only to the logged in user. Defaults to '0'.
281 track - optional boolean value. Set to '1' to enable time tracking on
282 items in this list. Defaults to '0';
283
284 Basecamp allows you to create list templates for easy creation of
285 common task lists. When creating a new list using this method you
286 can provide the id of a predefined list template:
287
288 template_id - id of predefined template
289
290 or pass the name and description for the list:
291
292 name - list title
293 description - optional description of list
294
295 my $project_id = 654321;
296 my $list_data = { milestone_id => 5436,
297 private => 0,
298 track => 1,
299 name => 'Closing up procedures',
300 };
301 my $data = $bc->create_list($project_id,$list_data);
302
303 delete_item($item_id)
304 Deletes the specified item, removing it from its parent list.
305
306 delete_list($list_id)
307 This call will delete the entire referenced list and all items
308 associated with it. Use it with caution, because a deleted list
309 cannot be restored!
310
311 delete_list($list_id)
312 This will return the metadata and items for a specific list.
313
314 lists($project_id, [$filter], [$key])
315 This will return the metadata for all of the lists in a given
316 project. You can further constrain the query to only return those
317 lists that are "complete" (have no uncompleted items) or
318 "uncomplete" (have uncompleted items remaining).
319
320 To receive only complete lists pass $filter = 'true' To receive only
321 incomplete lists, pass $filter = 'false' To receive all lists do not
322 pass $filter
323
324 Available keys for this method are 'name' and 'id'. (optional)
325
326 move_item($item_id, $position)
327 Changes the position of an item within its parent list. It does not
328 currently support reparenting an item. Position 1 is at the top of
329 the list. Moving an item beyond the end of the list puts it at the
330 bottom of the list.
331
332 move_list($list_id, $position)
333 This allows you to reposition a list relative to the other lists in
334 the project. A list with position 1 will show up at the top of the
335 page. Moving lists around lets you prioritize. Moving a list to a
336 position less than 1, or more than the number of lists in a project,
337 will force the position to be between 1 and the number of lists
338 (inclusive).
339
340 move_list($item_id)
341 Marks the specified item as "uncomplete". If the item is already
342 uncompleted, this does nothing.
343
344 update_item($item_id, $item_data)
345 Modifies an existing item. Available fields are as per the
346 create_item method.
347
348 update_list($list_id, $list_data)
349 Modifies an the metadata for an existing list. Available fields are
350 as per the create_list method, with the exclusion of the
351 template_id.
352
353 Milestones
354 complete_milestone($milestone_id)
355 Marks the specified milestone as complete.
356
357 create_milestone($project_id, $milestone_data)
358 Creates a single milestone. If a company is responsible, prefix
359 their company id with a 'c' and use that as the party_id value. If
360 the milestone has a person as the responsible party, you can use the
361 notify key to indicate whether an email should be sent to that
362 person to tell them about the milestone. The available fields are:
363
364 title - Title for the milestone
365 deadline - date the milestone is due to be completed. Must be in the format
366 of YYYYMMDD
367 party_id - id of a person or company responsible for the milestone. If it is
368 a company, prefix the id with a 'c', e.g. 'c123'
369 notify - optional boolean value. Set to '1' to send an email about the
370 milestone to the responsible party.
371
372 my $project_id = 654321
373 my $milestone_data = { title => 'Launch Party',
374 deadline => '20060828',
375 party_id => 555,
376 notify => 1 };
377 my $new_milestone = $bc->create_milestone($project_id, $milestone_data);
378
379 Returns a hash containing all of the milestone details.
380
381 delete_milestone($milestone_id)
382 Deletes the given milestone from the project.
383
384 list_milestones($project_id, [$filter])
385 This lets you query the list of milestones for a project. You can
386 either return all milestones, or only those that are late,
387 completed, or upcoming.
388
389 To receive only complete milestones pass $filter = 'complete' To
390 receive only upcoming milesones, pass $filter = 'upcoming' To
391 receive only late milesones, pass $filter = 'late' To receive all
392 milestones do not pass $filter
393
394 uncomplete_milestone($milestone_id)
395 Marks the specified milestone as uncomplete.
396
397 update_milestone($milestone_id, $milestone_data)
398 Modifies a single milestone. You can use this to shift the deadline
399 of a single milestone, and optionally shift the deadlines of
400 subsequent milestones as well. The available fields are as per the
401 create_milestone() method with the addition of two extra fields:
402
403 move_upcoming - optional boolean value. Set to '1' to move subsequent
404 milestone deadlines whne updating the deadline for this
405 milestone
406 move_weekends - optional boolean value. If using the 'move_upcoming'
407 parameter, you can set this value to '1' to make sure that any
408 subsequent milestone deadlines do not get moved to a Saturday
409 or Sunday.
410
411 my $milestone_id = 98765
412 my $milestone_data = { title => 'Launch Party',
413 deadline => '20061028',
414 party_id => 555,
415 notify => 1,
416 move_upcoming => 1,
417 move_weekends => 1 };
418 my $new_milestone = $bc->update_milestone($milestone_id, $milestone_data);
419
420 Returns a hash containing all of the milestone details.
421
422 Time Tracking
423 create_time($data)
424 With this method you can create a new time entry for a particular
425 person and project. The available fields are:
426
427 project_id - id for the project associated with the task
428 person_id - id of the person who completed the work
429 date - date the work took place. Date format = YYYYMMDD, e.g. 20060801
430 hours - time worked, in hours
431
432 If the task being time tracked is an existing item from a to do
433 list, you can pass the item_id:
434
435 item_id - id of an existing to do list item
436
437 or you can provide a description of the task
438
439 description - txt description of the task
440
441 my $project_id = 654321;
442 my $person_id = 555;
443 my $data = { project_id => $project_id,
444 person_id => $person_id,
445 date => '20060801',
446 hours => '1.25',
447 description => 'Meeting with world leaders' };
448 my $new_time = $bc->create_time($data);
449
450 delete_time($project_id, $time_id)
451 Deletes the identified time entry.
452
453 report_time($person_id, $from, $to, [$filter])
454 This method lets you query the time entries in a variety of ways. If
455 you do not want to query by $person_id, put a 0 in that position.
456 Likewise for $from and $to (to use default from/to values). In no
457 case can you query more than 90 days' worth of data. The $filter
458 parameter can be blank, or an id number prefixed by a 'p' (to filter
459 by a specific project) or 'c' (to filter by a specific company).
460
461 my $report = $bc->report_time(5,'20060101','20060207','c7');
462
463 Would return all time entries for the person with id 5, for all projects
464 associated with the company with id 7, between the dates 2006-01-01 and
465 2006-02-07 (inclusive).
466
467 Date values passed for $from and $to must be in the format of
468 YYYYMMDD
469
470 update_time($time_id, $data)
471 With this method you can modify a specific time entry. The available
472 fields are as per the create_time() method.
473
474 Contact Management
475 companies()
476 Returns a list of all companies visible to the given person. This is
477 only accessible to employees of the "firm" (the company assoicated
478 with the account). Client employees will get a 403 response if they
479 attempt to access this method.
480
481 company($company_id)
482 This will return the information for the referenced company.
483
484 people($company_id)
485 This will return all of the people in the given company.
486
487 people_per_project($project_id, $company_id)
488 This will return all of the people in the given company that can
489 access the given project.
490
491 person($person_id)
492 This will return information about the referenced person.
493
494TODO
495 This module does not currently support all of the Basecamp API
496 functions. In particular, the following methods need to be added:
497
498 * File uploads
499
500 * Attaching files to messages
501
502 * batch creation of milestones
503
504 Add more tests
505
506BUGS
507 This is alpha software and as such, the features and interface are
508 subject to change. So please check the Changes file when upgrading.
509
510SEE ALSO
511 <http://www.basecamphq.com/api>, XML::Simple
512
513AUTHOR
514 David Baxter <david@sitesuite.com.au>
515
516CREDITS
517 Thanks to SiteSuite (http://www.sitesuite.com.au) for funding the
518 development of this plugin and for releasing it to the world.
519
520LICENCE AND COPYRIGHT
521 Copyright (c) 2006, SiteSuite. All rights reserved.
522
523 This module is free software; you can redistribute it and/or modify it
524 under the same terms as Perl itself.
525
526DISCLAIMER OF WARRANTY
527 BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
528 FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
529 OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
530 PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
531 EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
532 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
533 ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH
534 YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
535 NECESSARY SERVICING, REPAIR, OR CORRECTION.
536
537 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
538 WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
539 REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE
540 TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR
541 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
542 SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
543 RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
544 FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
545 SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
546 DAMAGES.
547
548