Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

10.4: Change iCal attendee attendance status via script Apps
Before Tiger (and iCal 2.0), it was possible to manually set the status of attendees in iCal. This meant you could set an attendee (or an event) to Confirmed, Cancelled, or Undecided, and an icon in the upper right of the event would indicate the current status. iCal 2.0 introduced automatic attendee status: now when you send out event invitations, the recipients reply with specially crafted emails to indicate their status. The problem is that you can't manually modify that status any more.

It turns out, though, that the status is AppleScriptable. So I wrote a small script that allows you to set the status for individual attendees to a given event. Copy and paste the text into a new script window. Then just save it into your user's ~/Library/Scripts folder, turn on the Script Menu, and voila, set status to your heart's content.

[robg adds: I haven't tested this one.]
    •    
  • Currently 1.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (1 vote cast)
 
[8,485 views]  

10.4: Change iCal attendee attendance status via script | 9 comments | Create New Account
Click here to return to the '10.4: Change iCal attendee attendance status via script' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
10.4: Change iCal attendee attendance status via script
Authored by: ephramz on Sep 05, '06 10:03:52AM

Hmm, great looking script, but it doesn't seem to work for me. It runs fine and selects all events in the next 5 days with attendees for me to edit, I can edit them and change their status, but then back in iCal I see no indication of their new status. I even sent out invite emails for an event so that each attendee name would have the little status indicator next to them, but it didn't change when I ran this script either. Any suggestions?



[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: yostinso on Sep 05, '06 03:02:27PM

I just ran into this same problem today, actually, except it's only applying to one attendee of one event. I have yet to discover what the problem is; nothing seems to be special about this one attendee. I'll keep investigating and post anything I find here.

--E.O.



[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: yostinso on Sep 05, '06 03:49:14PM

Okay, I've found a workaround for the problem mentioned in the previous post, at least. Apparently, iCal doesn't bother to update attendee status via AppleScript unless you give it a little nudge by adding and removing an attendee. About 50% of the time for me, it just fails to even draw the little icons unless you do. This script just adds and removes a blank attendee at the end and seems to fix everything; let me know if there are more troubles.

I also addressed an issue where you may have multiple events with the same name, now the chooser includes the date and UID; a little uglier, but a good bit safer.

I've also added some comments and added a variable to set the number of days called the_number_of_days, simply enough. It's currently still set to 5.

If the following code doesn't copy-paste properly, you can download the compiled (but editable) script from here, or for the cautious, the script as a text file from here.


tell application "iCal"
	-- Choose the calendar
	set the_cal_name to (choose from list (title of every calendar as list) with prompt "Choose the calendar to search for events among:") as string
	repeat with this_cal in every calendar
		if the_cal_name as string is equal to the name of this_cal then
			set the_cal to this_cal
		end if
	end repeat
	
	-- Look through the events and choose those in the next the_number_of_days
	set the_number_of_days to 5
	set the_event_list to {}
	set the_name_list to {}
	repeat with the_event in every event in the_cal
		if the start date of the_event is greater than the (current date) 
			and the start date of the_event is less than the ((current date) + (the_number_of_days * days)) then
			if the (count of the attendees of the_event) is greater than 0 then
				set the end of the_event_list to the_event
				set the end of the_name_list to the summary of the_event & " (" & the start date of the_event & ") -" & the uid of the_event
			end if
		end if
	end repeat
	-- If there are no events in the_number_of_days days with attendees, give up
	if (count of the_name_list) is 0 then
		display dialog "No nearby events found." buttons {"OK"} default button 1
		return
	end if
	-- Otherwise, pick the event
	set the_name to (choose from list (the_name_list) with prompt "Choose the event:") as string
	set the_event to null
	-- Note that we're including the name & date for readability, and the uid for specificity
	-- Kind of ugly, but no way to hide the UID when using the "choose" syntax that I know of
	repeat with this_event in the_event_list
		if the_name is equal to the (summary of this_event & " (" & the start date of this_event & ") -" & the uid of this_event) then
			set the_event to this_event
		end if
	end repeat
	-- If the user hit cancel, the event is null, so give up
	if the_event is null then return
	
	-- Get the list of attendees; in this case, we're assuming display name is unique
	set attendee_list to the display name of every attendee of the_event as list
	set the_attendees to choose from list attendee_list with prompt "Choose the attendee(s) to change the status for:" with multiple selections allowed
	-- Find the one we picked
	repeat with the_attendee in every attendee of the_event
		if the display name of the_attendee is in the_attendees then
			set the_old_status to the participation status of the_attendee
			-- If we got some random status that isn't listed, let the user know
			if the_old_status as string is not in {"unknown", "accepted", "declined", "undecided"} then
				set the_extra_prompt to "
				(was " & the_old_status & ")"
			else
				set the_extra_prompt to ""
			end if
			-- Either way, try to pre-select the current status using "default"
			set the_new_status to choose from list {"unknown", "accepted", "declined", "undecided"} 
				with prompt "Choose new status for " & display name of the_attendee & 
				":" & the_extra_prompt default items {the_old_status as string}
			-- Convert the status-as-applescript-constant to status-as-string
			if the_new_status is not false then
				set the_new_status to the_new_status as string
				if the_new_status is equal to "unknown" then set the_new_status to unknown
				if the_new_status is equal to "accepted" then set the_new_status to accepted
				if the_new_status is equal to "declined" then set the_new_status to declined
				if the_new_status is equal to "undecided" then set the_new_status to undecided
				set the participation status of the_attendee to the_new_status
			end if
		end if
	end repeat
	-- Apparently, unless you create and then remove an attendee, iCal may think nothing has happened
	tell the_event
		set fake_attendee to (make new attendee at the beginning of the attendees of the_event)
		delete the fake_attendee
	end tell
end tell


[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: ephramz on Sep 05, '06 09:32:04PM
Still not working for me for some reason. I see it adding the new attendee at the end and then deleting them, but the icon next to it still remains as the little grey arrow for email sent, even if I go to another event and come back or close the info window and reopen it.

One weird thing that might be informative is that when I am in the dialog to set the status, it says "Choose new status for attendee: (was --constant ****E6na--)" even thought the previous status should be "unknown" or something like that. Does that help figure out the problem?

I can get it to work on certain events, but only the first attendee of those events. The only thing different about these events that I can figure out is that there are in published calendars. In unpublished calendars and for second later attendees, even restarting iCal does not make the proper status show up. :(

I did change the code so you don't have to pick a calendar or limit yourself to events only a few days away. I assume you did this for speed but I used

(every event in this_cal whose (start date is greater than the (current date)))

which is a fast way of searching all future events in a particular calendar. Here's the complete code, which still runs reasonably fast on my puny 500 MHz powerbook! :)


tell application "iCal"
	-- Choose the calendar
	
	set cal_future_events to {}
	repeat with this_cal in every calendar
		copy (every event in this_cal whose (start date is greater than the (current date))) to the end of cal_future_events
	end repeat
	
	
	-- Look through the events and choose those in the next the_number_of_days
	set the_number_of_days to 5
	set the_event_list to {}
	set the_name_list to {}
	repeat with the_events in cal_future_events
		repeat with the_event in the_events
			if the (count of the attendees of the_event) is greater than 0 then
				set the end of the_event_list to the_event
				set the end of the_name_list to the summary of the_event & " (" & the start date of the_event & ") -" & the uid of the_event
			end if
		end repeat
	end repeat
	-- If there are no events in the_number_of_days days with attendees, give up
	if (count of the_name_list) is 0 then
		display dialog "No nearby events found." buttons {"OK"} default button 1
		return
	end if
	-- Otherwise, pick the event
	set the_name to (choose from list (the_name_list) with prompt "Choose the event:") as string
	set the_event to null
	-- Note that we're including the name & date for readability, and the uid for specificity
	-- Kind of ugly, but no way to hide the UID when using the "choose" syntax that I know of
	repeat with this_event in the_event_list
		if the_name is equal to the (summary of this_event & " (" & the start date of this_event & ") -" & the uid of this_event) then
			set the_event to this_event
		end if
	end repeat
	-- If the user hit cancel, the event is null, so give up
	if the_event is null then return
	
	-- Get the list of attendees; in this case, we're assuming display name is unique
	set attendee_list to the display name of every attendee of the_event as list
	set the_attendees to choose from list attendee_list with prompt "Choose the attendee(s) to change the status for:" with multiple selections allowed
	-- Find the one we picked
	repeat with the_attendee in every attendee of the_event
		if the display name of the_attendee is in the_attendees then
			set the_old_status to the participation status of the_attendee
			-- If we got some random status that isn't listed, let the user know
			if the_old_status as string is not in {"unknown", "accepted", "declined", "undecided"} then
				set the_extra_prompt to "
				(was " & the_old_status & ")"
			else
				set the_extra_prompt to ""
			end if
			-- Either way, try to pre-select the current status using "default"
			set the_new_status to choose from list {"unknown", "accepted", "declined", "undecided"} 
				with prompt "Choose new status for " & display name of the_attendee & 
				":" & the_extra_prompt default items {the_old_status as string}
			-- Convert the status-as-applescript-constant to status-as-string
			if the_new_status is not false then
				set the_new_status to the_new_status as string
				if the_new_status is equal to "unknown" then set the_new_status to unknown
				if the_new_status is equal to "accepted" then set the_new_status to accepted
				if the_new_status is equal to "declined" then set the_new_status to declined
				if the_new_status is equal to "undecided" then set the_new_status to undecided
				set the participation status of the_attendee to the_new_status
				log ((participation status) of the_attendee) as string
				log the_attendee
				log (display name of the_attendee) as string
			end if
		end if
	end repeat
	-- Apparently, unless you create and then remove an attendee, iCal may think nothing has happened
	tell the_event
		set fake_attendee to (make new attendee at the beginning of the attendees of the_event)
		delete the fake_attendee
	end tell
end tell


[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: ephramz on Sep 06, '06 08:06:29AM

Aha! I figured out what the problem was! It doesn't work on attendees that don't have email for some reason. I realized that I had put in test attendees with no email to make sure it didn't send out email to them by accident, and iCal doesn't seem to like to visually change the status of these attendees. It works fine, even without the add attendee/delete attendee trick at the end.

Not sure if we can get it to work with non-email attendees (give them a dummy email?) since these are exactly the kind of attendees one would like to use them with since we can't email them the invite!



[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: ephramz on Sep 06, '06 08:24:08AM
Yep! That does the trick. It has to be a valid format email address, i.e. something@something.something, not just some random text, and the blank email is set to "nomail" not "", so just add this line
if email of the_attendee is "nomail" then set email of the_attendee to "has@no_email.com"

above this line

set the participation status of the_attendee to the_new_status

in any of the above scripts and it should do the trick!

[ Reply to This | # ]

10.4: Change iCal attendee attendance status via script
Authored by: ephramz on Sep 06, '06 09:59:05PM
Actually that line in the last message should be
if email of the_attendee is "nomail" then set email of the_attendee to (first word of ((display name of the_attendee) as string)) & "_"& (last word of ((display name of the_attendee) as string)) &"_has@no_email.com"
since each attendee needs a unique valid email, so this tries to do that with the first and last name

[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: ephramz on Mar 29, '07 10:23:29PM
I've modified this script to keep a running tally of the different categories of attendees (accepted, undecided, declined, unknown, and total) which it recalculate each time the script is used. It seems to mees up the description (notes)) text a bit (destroys carriage returns) but otherwise works well to see how many people you invited to an event and how many are coming. Forget evite, use this!


tell application "iCal"
	-- Choose the calendar
	activate
	set cal_future_events to {}
	repeat with this_cal in every calendar
		copy (every event in this_cal whose (start date is greater than the (current date))) to the end of cal_future_events
	end repeat
	
	
	-- Look through the events and choose those in the next the_number_of_days
	set the_number_of_days to 5
	set the_event_list to {}
	set the_name_list to {}
	repeat with the_events in cal_future_events
		repeat with the_event in the_events
			if the (count of the attendees of the_event) is greater than 0 then
				set the end of the_event_list to the_event
				set the end of the_name_list to the summary of the_event & " (" & the start date of the_event & ")"
			end if
		end repeat
	end repeat
	-- If there are no events in the_number_of_days days with attendees, give up
	if (count of the_name_list) is 0 then
		display dialog "No nearby events found." buttons {"OK"} default button 1
		return
	end if
	-- Otherwise, pick the event
	set the_name to (choose from list (the_name_list) with prompt "Choose the event:") as string
	set the_event to null
	-- Note that we're including the name & date for readability, and the uid for specificity
	-- Kind of ugly, but no way to hide the UID when using the "choose" syntax that I know of
	repeat with this_event in the_event_list
		if the_name is equal to the (summary of this_event & " (" & the start date of this_event & ")") then
			set the_event to this_event
		end if
	end repeat
	-- If the user hit cancel, the event is null, so give up
	if the_event is null then return
	
	repeat with att in attendees of the_event
		if not (display name of att exists) then set display name of att to email of att
	end repeat
	-- Get the list of attendees; in this case, we're assuming display name is unique
	set attendee_list to the display name of every attendee of the_event as list
	set the_attendees to choose from list attendee_list with prompt "Choose the attendee(s) to change the status for:" with multiple selections allowed
	-- Find the one we picked
	set naccepted to 0
	set ndeclined to 0
	set nundecided to 0
	set nunknown to 0
	repeat with the_attendee in every attendee of the_event
		if the display name of the_attendee is in the_attendees then
			set the_old_status to the participation status of the_attendee
			-- If we got some random status that isn't listed, let the user know
			if the_old_status as string is not in {"unknown", "accepted", "declined", "undecided"} then
				set the_extra_prompt to "
				(was " & the_old_status & ")"
			else
				set the_extra_prompt to ""
			end if
			-- Either way, try to pre-select the current status using "default"
			set the_new_status to choose from list {"unknown", "accepted", "declined", "undecided"} 
				with prompt "Choose new status for " & display name of the_attendee & 
				":" & the_extra_prompt default items {the_old_status as string}
			-- Convert the status-as-applescript-constant to status-as-string
			if the_new_status is not false then
				set the_new_status to the_new_status as string
				if the_new_status is equal to "unknown" then set the_new_status to unknown
				if the_new_status is equal to "accepted" then set the_new_status to accepted
				if the_new_status is equal to "declined" then set the_new_status to declined
				if the_new_status is equal to "undecided" then set the_new_status to undecided
				if email of the_attendee is "nomail" then set email of the_attendee to (first word of ((display name of the_attendee) as string)) & "_" & (last word of ((display name of the_attendee) as string)) & "_has@no_email.com"
				set the participation status of the_attendee to the_new_status
				log ((participation status) of the_attendee) as string
				log the_attendee
				log (display name of the_attendee) as string
				log (email of the_attendee) as string
			end if
		end if
		set the_new_status to participation status of the_attendee
		if the_new_status as text is equal to "unknown" then
			set nunknown to nunknown + 1
		else if the_new_status as text is equal to "accepted" then
			set naccepted to naccepted + 1
		else if the_new_status as text is equal to "declined" then
			set ndeclined to ndeclined + 1
		else if the_new_status as text is equal to "undecided" then
			set nundecided to nundecided + 1
		end if
	end repeat
	-- Apparently, unless you create and then remove an attendee, iCal may think nothing has happened
	tell the_event
		set desc to (description as text)
		if (the first paragraph of desc) as text is "Current tallies of attendedees:" then
			set desc to paragraphs 9 through -1 of desc
		end if
		set description to "Current tallies of attendedees:
	" & naccepted & "	accepted
	" & nundecided & "	undecided
	" & ndeclined & "	declined
	" & nunknown & "	unknown
	-------------------------
	" & nunknown + naccepted + nundecided + ndeclined & "	total

" & desc
		set fake_attendee to (make new attendee at the beginning of the attendees of the_event)
		delete the fake_attendee
	end tell
end tell


[ Reply to This | # ]
10.4: Change iCal attendee attendance status via script
Authored by: RevJoel on Oct 04, '07 06:18:33AM

Does anyone know how to change the default for 'my status' on notifications to Accept instead of Tentative?



[ Reply to This | # ]