Reminders
Working with note-based reminders
Reminders can be set on individual notes in a user’s Evernote account and allow the user to:
- Receive alerts at a pre-determined time. In the official Evernote client applications, these alerts may be local notifications, icon badges, etc. This will vary by application and will include a daily digest email sent by Evernote with a list of all reminders due that day (provided the user has opted into this feature).
- Place one or more notes at the top of a list of notes (the contents of a notebook, results of a search, when browsing a tag — basically any instance in which notes are listed).
This functionality is controlled by three attributes in the NoteAttributes
data structure: reminderTime
, reminderOrder
and reminderDoneTime
.
reminderOrder
Setting the reminderOrder
attribute, a long integer value, accomplishes three things:
- Sets a reminder on the note that will be synced to Evernote. All other Evernote applications—as well as third-party applications—will have access to the reminder data.
- Forces the note to appear at or near the top of list of notes (depending on the number of visible notes with the attribute set).
- Controls the position of the note within the visible notes with
reminderOrder
set.
The latter effect warrants some additional discussion.
If, for example, a notebook contains 10 notes and three of them have reminderOrder
set, the three notes will be sorted (in descending order) according to the value of reminderOrder
. When set by an official Evernote application, this value will be a Unix timestamp, expressed in milliseconds, indicating when the user marked the note as a reminder. Third-party applications should do likewise when setting the reminderOrder
attribute on a note.
reminderTime
Setting the reminderTime
value on a note indicates that the user wishes to be reminded of that note at the specified date and time. The alert will be triggered, potentially using a variety of platform-specific notification methods, at whatever date and time is stored in the reminderTime
attribute. This value is a Unix timestamp expressed in milliseconds.
Note that if reminderTime
is set on a note that does not currently have reminderOrder
set, the Evernote service will automatically assign a value to reminderOrder
. It is important, however, to understand how reminderOrder
works and how to set it manually.
reminderDoneTime
When a user marks a note containing a reminder as “done”, this attribute is set to the date and time—also a Unix timestamp expressed in milliseconds—when the user performed that action (and should only be manipulated by third-party developers in the same case). Third-party integrations that make use of the reminders functionality may want to account for “completed” reminders in their UIs.
If reminderDoneTime
is unset on a note and reminderTime
is still set, the reminder should be re-enabled in the UI.
Reminder Reordering
Third-party integrations that make use of reminderOrder
may support the arbitrary reordering of notes by the user (though, this is fairly advanced functionality and isn’t a requirement for third-party integrations). For example:
If the user is viewing a list of the same three notes described earlier like so:
- Note A (where
reminderOrder
is set to 10) - Note B (where
reminderOrder
is set to 20) - Note C (where
reminderOrder
is set to 30)
If the user drags Note A between Note B and Note C, the reminderOrder
value for Note A must be reset to fall between the reminderOrder
values for Note B and Note C. In this case, Note A’s reminderOrder
value should be set to 25 in this case. In practice, the reminderOrder
of the note being moved should be set to the average of the reminderOrder
values of the two surrounding notes.
Manual ordering of notes with reminderOrder
set is an advanced operation; most developers will not need to concern themselves with it unless it is beneficial for their particular integration.
Note: while technically allowed, the simple integers in the above example were used to simplify the illustration of the concept and should be avoided in actual use in favor of actual timestamp values.
Sample Code
The following snippet creates a new note object, sets reminderOrder
and reminderTime
within the note’s NoteAttributes
structure and creates the note by calling NoteStore.createNote
. The last line of the snippet sets the reminderDoneTime
attribute to the current time, which marks the reminder as “done”:
# new instance of Note with title and FPO content. | |
note = Types.Note() | |
note.title = "Testing Reminders" | |
note.content = """<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"> | |
<en-note>Hello, World</en-note> | |
""" | |
now = int(round(time.time() * 1000)) | |
then = now + 3600000 # one hour after `now` | |
# init NoteAttributes instance | |
note.attributes = Types.NoteAttributes() | |
note.attributes.reminderOrder = now | |
note.attributes.reminderTime = then | |
try: | |
createdNote = note_store.createNote(note) | |
except Exception, e: | |
print type(e) | |
print e | |
raise SystemExit | |
print "Note created with GUID: %s" % createdNote.guid | |
# Optionally mark the note as "done" by setting reminderDoneTime | |
createdNote.attributes.reminderDoneTime = int(round(time.time() * 1000)) |
# new instance of Note with title and FPO content. | |
note = Evernote::EDAM::Type::Note.new | |
note.title = "Testing Reminders" | |
note.content = '<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"> | |
<en-note>Hello, World</en-note>' | |
now_time = Time.now.to_i * 1000 | |
then_time = now_time + 3600000 # one hour after `now` | |
# init NoteAttributes instance | |
note.attributes = Evernote::EDAM::Type::NoteAttributes.new | |
note.attributes.reminderOrder = now_time | |
note.attributes.reminderTime = then_time | |
createdNote = note_store.createNote(note) | |
puts "Note created with GUID: #{createdNote.guid}" | |
# Optionally mark the note as "done" by setting reminderDoneTime | |
createdNote.attributes.reminderDoneTime = Time.now.to_i |
<?php | |
// new instance of Note with title and FPO content. | |
$note = new Note(); | |
$note->title = "Testing Reminders"; | |
$note->content = '<?xml version="1.0" encoding="UTF-8"?> | |
<!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"> | |
<en-note>Hello, World</en-note>'; | |
$now = round(microtime(true) * 1000); | |
$then = $now + 3600000; // one hour after `now` | |
// init NoteAttributes instance | |
$note->attributes = new NoteAttributes(); | |
$note->attributes->reminderOrder = $now; | |
$note->attributes->reminderTime = $then; | |
try { | |
$createdNote = $noteStore->createNote($note); | |
} catch (Exception $e) { | |
var_dump($e); | |
throw $e; | |
} | |
print "Note created with GUID: " . $createdNote->guid; | |
// Optionally mark the note as "done" by setting reminderDoneTime | |
$createdNote->attributes->reminderDoneTime = round(microtime(true) * 1000); | |
?> |
// new instance of Note with title and FPO content. | |
Note note = new Note(); | |
note.setTitle("Testing Reminders"); | |
note.setContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\"><en-note>Hello, World</en-note>"); | |
long now = System.currentTimeMillis(); | |
long then = now + 3600000; // one hour after `now` | |
// init NoteAttributes instance | |
note.setAttributes(new NoteAttributes()); | |
note.getAttributes().setReminderOrder(now); | |
note.getAttributes().setReminderTime(then); | |
Note createdNote = noteStore.createNote(note); | |
System.out.println("Note created with GUID: " + createdNote.getGuid()); | |
// Optionally mark the note as "done" by setting reminderDoneTime | |
createdNote.getAttributes().setReminderDoneTime(System.currentTimeMillis()); |
// new instance of Note with title and FPO content. | |
note = new Evernote.Note(); | |
note.title = "Testing Reminders"; | |
note.content = '<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE en-note SYSTEM "http://xml.evernote.com/pub/enml2.dtd"><en-note>Hello, World</en-note>'; | |
now = Date.now(); | |
then = now + 3600000; // one hour after `now` | |
// init NoteAttributes instance | |
note.attributes = new NoteAttributes(); | |
note.attributes.reminderOrder = now; | |
note.attributes.reminderTime = then; | |
noteStore.createNote(note, function(createdNote) { | |
if (createdNote.errorCode) { | |
console.log(createdNote); | |
throw createdNote; | |
} else { | |
console.log("Note created with GUID: " + createdNote.guid); | |
// Optionally mark the note as "done" by setting reminderDoneTime | |
createdNote.attributes.reminderDoneTime = Date.now(); | |
} | |
}); |
- (void)createReminder { | |
NSString *noteContent = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
"<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">" | |
"<en-note>" | |
"Hello reminder!" | |
"</en-note>"]; | |
// Include NSDate+EDAMAdditions.h | |
NSDate* now = [NSDate date]; | |
NSDate* then = [now dateByAddingTimeInterval:3600]; | |
// Set the reminder | |
EDAMNoteAttributes* noteAttributes = [[EDAMNoteAttributes alloc] initWithSubjectDate:0 latitude:0 longitude:0 altitude:0 author:nil source:nil sourceURL:nil sourceApplication:nil shareDate:0 reminderOrder:[now enedamTimestamp] reminderDoneTime:nil reminderTime:[then enedamTimestamp] placeName:nil contentClass:nil applicationData:nil lastEditedBy:nil classifications:nil]; | |
// Create note object | |
EDAMNote *ourNote = [[EDAMNote alloc] initWithGuid:nil title:@"Testing Reminders" content:noteContent contentHash:nil contentLength:noteContent.length created:0 updated:0 deleted:0 active:YES updateSequenceNum:0 notebookGuid:nil tagGuids:nil resources:nil attributes:noteAttributes tagNames:nil]; | |
// Attempt to create note in Evernote account with Reminder | |
[[EvernoteNoteStore noteStore] createNote:ourNote success:^(EDAMNote *note) { | |
// Log the created note object | |
NSLog(@"Note created : %@",note); | |
} failure:^(NSError *error) { | |
// Something was wrong with the note data | |
// See EDAMErrorCode enumeration for error code explanation | |
// http://dev.evernote.com/documentation/reference/Errors.html#Enum_EDAMErrorCode | |
NSLog(@"Error : %@",error); | |
}]; | |
} |
To search for notes with reminderOrder
(or any other reminder-related attribute) set, you can use an instance of NoteFilter
in conjunction with NoteStore.findNotesMetadata
:
import evernote.edam.notestore.ttypes as NoteStoreTypes | |
nFilter = NoteStoreTypes.NoteFilter() | |
nFilter.words = "reminderOrder:*" | |
rSpec = NoteStoreTypes.NotesMetadataResultSpec() | |
rSpec.includeTitle = True | |
notesMetadataList = note_store.findNotesMetadata(nFilter, 0, 50, rSpec) | |
print "Found %d notes with `reminderOrder` set." % len(notesMetadataList.notes) | |
print "Here are their titles: " | |
for note in notesMetadataList.notes: | |
print "\t%s" % note.title |
n_filter = Evernote::EDAM::NoteStore::NoteFilter.new | |
n_filter.words = "reminderOrder:*" | |
r_spec = Evernote::EDAM::NoteStore::NotesMetadataResultSpec.new | |
r_spec.includeTitle = true | |
notes_metadata_list = note_store.findNotesMetadata(n_filter, 0, 50, r_spec) | |
puts "Found #{notes_metadata_list.size} notes with `reminderOrder` set." | |
puts | |
puts "Here are their titles: " | |
notes_metadata_list.notes.each do |note| | |
puts "\t#{note.title}" | |
end |
<?php | |
$nFilter = new NoteFilter(); | |
$nFilter->words = "reminderOrder:*"; | |
$rSpec = new NotesMetadataResultSpec(); | |
$rSpec->includeTitle = True; | |
$notesMetadataList = $noteStore->findNotesMetadata($nFilter, 0, 50, $rSpec); | |
print "Found " . count($notesMetadataList->notes) . " notes with `reminderOrder` set."; | |
print "\n"; | |
print "Here are their titles: "; | |
foreach ($notesMetadataList->notes as $note) { | |
print "\t" . $note->title; | |
} | |
?> |
NoteFilter nFilter = new NoteFilter(); | |
nFilter.setWords("reminderOrder:*"); | |
NotesMetadataResultSpec rSpec = new NotesMetadataResultSpec(); | |
rSpec.setIncludeTitle(true); | |
NotesMetadataList notesMetadataList = noteStore.findNotesMetadata(nFilter, 0, 50, rSpec); | |
System.out.println("Found " + notesMetadataList.getNotes().size() + " notes with `reminderOrder` set."); | |
System.out.println(); | |
System.out.println("Here are their titles: "); | |
for (NoteMetadata note : notesMetadataList.getNotes()) { | |
System.out.println("\t" + note.getTitle()); | |
} |
var nFilter = new Evernote.NoteFilter(); | |
nFilter.words = "reminderOrder:*"; | |
var rSpec = new Evernote.NotesMetadataResultSpec(); | |
rSpec.includeTitle = true; | |
noteStore.findNotesMetadata(nFilter, 0, 50, rSpec, function(notesMetadataList) { | |
console.log("Found " + notesMetadataList.notes.length + " notes with `reminderOrder` set."); | |
console.log(); | |
console.log("Here are their titles: "); | |
for (var i in notesMetadataList.notes) { | |
console.log("\t" + notesMetadataList.notes[i].title); | |
} | |
}); |
- (void)createReminder { | |
NSString *noteContent = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" | |
"<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">" | |
"<en-note>" | |
"Hello reminder!" | |
"</en-note>"]; | |
// Include NSDate+EDAMAdditions.h | |
NSDate* now = [NSDate date]; | |
NSDate* then = [now dateByAddingTimeInterval:3600]; | |
// Set the reminder | |
EDAMNoteAttributes* noteAttributes = [[EDAMNoteAttributes alloc] initWithSubjectDate:0 latitude:0 longitude:0 altitude:0 author:nil source:nil sourceURL:nil sourceApplication:nil shareDate:0 reminderOrder:[now enedamTimestamp] reminderDoneTime:nil reminderTime:[then enedamTimestamp] placeName:nil contentClass:nil applicationData:nil lastEditedBy:nil classifications:nil]; | |
// Create note object | |
EDAMNote *ourNote = [[EDAMNote alloc] initWithGuid:nil title:@"Testing Reminders" content:noteContent contentHash:nil contentLength:noteContent.length created:0 updated:0 deleted:0 active:YES updateSequenceNum:0 notebookGuid:nil tagGuids:nil resources:nil attributes:noteAttributes tagNames:nil]; | |
// Attempt to create note in Evernote account with Reminder | |
[[EvernoteNoteStore noteStore] createNote:ourNote success:^(EDAMNote *note) { | |
// Log the created note object | |
NSLog(@"Note created : %@",note); | |
} failure:^(NSError *error) { | |
// Something was wrong with the note data | |
// See EDAMErrorCode enumeration for error code explanation | |
// http://dev.evernote.com/documentation/reference/Errors.html#Enum_EDAMErrorCode | |
NSLog(@"Error : %@",error); | |
}]; | |
} |