# My GTD - How I Organize Meetings and TODOs in Roam
- How efficient is your workflow for keeping on top of all your meeting notes, action items, contacts, projects and more?
- If you were to bump into someone unexpectedly would you be able to remind yourself of all the relevant topics you wanted to discuss with the person?
- Can you remember all the things you wanted to get done when running your errands?
- Can you keep track of your discussions with all the people you talk to regularly?
In this post I will walk you through my meetings-actions-people workflow in Roam.
![[pexels-pixabay-270694.jpg|My GTD - How I Organize Meetings and TODOs in Roam]]
# If you are new to Roam and Roam42...
Just in case you are not familiar with [Roam](https://roamresearch.com), it is an ultra flexible note taking tool. It's like the Excel for text. If you want to find out more, there is tremendous amount of quality content available on YouTube, just search from "Roam Research". Equally, you can head over to [RoamBrain.com](www.roambrain.com) for all the best links and more.
My workflow is automated using [Roam42](https://Roam42.com) SmartBlocks. If you have Roam, but you don't have Roam42 SmartBlocks installed, check out the video in my post about [[My Book Summaries in Roam Using Tiago's Progressive Summarization]], it demonstrates how to get Roam42 and SmartBlocks up and running in less then 2 minutes.
# My typical workweek
On a typical workweek I will have about 50 meetings. Roughly two third of these are reoccurring meetings with my direct reports, project managers, key stakeholders, steering committees, my peers and my manager. At any given time I need to keep my eyes on 15 to 20 larger (multi-year) projects and about double this amount of smaller projects and issues. Since finding Roam in May 2020 I've been practicing and refining my daily workflow in it. Today I have a system that works very efficiently for me.
# Why Roam?
The reason for switching to Roam was its flexibility and friction free user experience. I've been experimenting with numerous solutions for the past twenty+ years. I can state without hesitation that Roam is by far the most efficient in combining a personal knowledge management (PKM) system with robust customer relationship management (CRM) and task management functionalities. To put it more precisely, Roam provides a very flexible structure and a powerful set of basic features that you can mold into a PKM, CRM and task management system. Today, I handle most of my knowledge work in Roam. This is where I track my work, organize my blog, manage my reading, do my daily journaling, and much more.
# Core components of my meetings-actions-people workflow
My Getting Things Done (GTD) workflow consists of the following elements:
- I manage my work calendar and email in Outlook.
- I have a script to export my daily agenda from Outlook so I can place it on my Daily Notes page in Roam.
- I embed TODOs into my meeting notes.
- I create a separate page in Roam for each of my meetings, contacts, and projects.
- I have a set of special purpose tags. The ones I will cover in more detail are _#discussWith_, _#waitingFor_, _#promisedTo_ and _#errands_.
- I use queries on the Daily Notes page and on the People pages.
- I have a set of SmartBlocks. Some of them mere templates, others a little bit more complex.
- Finally I have a GTD page with a set of queries to catch items that would fall through the cracks. i.e. TODO's that don't have a delivery deadline (INBOX), and those that are AGING (more than 1 month passed the due date). My GTD page also lists _#somedayMaybe_ tasks, that I want to keep track of, but that I don't want to see on a daily basis.
# My Calendar
I manage my work calendar in Outlook. Every morning I run a script in Outlook that produces the following **two artifacts**:
**1) the list of today's meetings** pre-formated for the **Daily Notes** page. The list contains the from-to times of each meeting followed by the subject of the meeting formatted as a Roam page link based on the following pattern: [[meeting/subject]].
![[atZkKyk5t9.png|]]
**2) and, for each of my meetings a pre-populated template** that is ready to be copied to the meeting's page in Roam. This template includes the list of attendees, the time and location of the meeting, the subject of the meeting, a default set of tags of which I delete the ones not relevant (_#1-1_, _#team-meeting_, _#steering-committee, #working-session_), and a placeholder for the meeting notes.
![[tN5sBh4u3j.png|]]
### My Outlook script
This is the scrip I use in Outlook.
_A few notes, should you want to re-use this script: **1)** I have some helper functions at the bottom of the script that transform names from the format they are shown in the corporate address book to how I refer to them in my notes. See the cleanName and the initializeNicks Functions. **2)** The script filters out my name from the list of attendees: you need to initialize sMyself and emailTo at the beginning of the script. **3)** Also the script only lists meetings where I am set as Busy. Tentative meetings as well as meetings with the subject "Focus time" are excluded. Search for "olBusy" in the code to find the if statement._
```vbscript
Sub CreateOverviewAndDetailedListofAppt()
Dim nicknames As New Scripting.Dictionary
Dim CalFolder As Outlook.MAPIFolder
Dim CalItems As Outlook.Items
Dim ResItems As Outlook.Items
Dim sFilter, strSubject, strAppt, strApptSummary As String
Dim itm, apptSnapshot As Object
Dim tStart As Date, tEnd As Date, tFullWeek As Date
Dim wd As Integer
Dim emailTo As String
Dim sMyself As String
strApptSummary = ""
strAppt = ""
' Set myself so I don't add myself to attendees
sMyself = "Your Name"
emailTo = "
[email protected]"
initializeNicks nicknames
' Use the default calendar folder
Set CalFolder = Session.GetDefaultFolder(olFolderCalendar)
Set CalItems = CalFolder.Items
' Sort all of the appointments based on the start time
CalItems.Sort "[Start]"
CalItems.IncludeRecurrences = True
' Set start and end dates for filter
tStart = Format(Date, "Short Date")
tEnd = Format(Date + 1, "Short Date")
tFullWeek = Format(Date + 6, "Short Date") 'Does a full week calendar export on Sunday
wd = Weekday(Date)
' Sun = 1, Mon = 2, Tues = 3, Wed = 4, Thu = 5, Fri = 6, Sat = 7
' get next day appt, do whole week on sunday
If wd >= 2 And wd <= 6 Then 'Mon-Fri
sFilter = "[Start] >= '" & tStart & "' AND [Start] <= '" & tEnd & "'"
ElseIf wd = 1 Then 'Sun
sFilter = "[Start] >= '" & tStart & "' AND [Start] <= '" & tFullWeek & "'"
End If
Set ResItems = CalItems.Restrict(sFilter)
'Loop through the items in the collection.
For Each itm In ResItems
'only include meetings I've accepted. This can be removed
'skip items marked with subject "Focus time"
If (itm.BusyStatus = olBusy) And (itm.Subject <> "Focus time") Then
' Create list of meetings
strApptSummary = strApptSummary & Format(itm.Start, "hh:mm") & "-" & Format(itm.End, "hh:mm ") & "[[meeting/" & Replace(itm.Subject, "/", "-") & "]]" & vbCrLf
' Create Meeting Page template
strAppt = strAppt & "Tag:: #1-1 #[[team-meeting]] #[[steering-committee]]" & vbCrLf
strAppt = strAppt & vbTab & "Subject:: [[meeting/" & Replace(itm.Subject, "/", "-") & "]]" & vbCrLf
strAppt = strAppt & vbTab & "When:: [[" & Format(itm.Start, "mmmm d") & ordinals(Format(itm.Start, "d")) & ", " & Format(itm.Start, "yyyy]] hh:mm") & "-" & Format(itm.End, "hh:mm") & vbCrLf
strAppt = strAppt & vbTab & "Attendees:: " & listAttendees(itm, sMyself, nicknames) & vbCrLf
strAppt = strAppt & vbTab & "Location:: " & itm.Location & vbCrLf
strAppt = strAppt & vbTab & "Summary:: " & vbCrLf
strAppt = strAppt & "Pre-read:: " & vbCrLf
strAppt = strAppt & "Decisions:: " & vbCrLf
strAppt = strAppt & "Notes:: " & vbCrLf & vbCrLf
strAppt = strAppt & "----------------------------------" & vbCrLf & vbCrLf
End If
Next
' Open a new email message form and insert the list of dates
Set apptSnapshot = Application.CreateItem(olMailItem)
With apptSnapshot
.BodyFormat = olFormatHTML
.Body = strApptSummary & vbCrLf & vbCrLf & vbCrLf & "----------------------------------" & vbCrLf & vbCrLf & strAppt
.To = emailTo
.Subject = "Appointments for " & tStart
.Display 'or .send
End With
Set itm = Nothing
Set apptSnapshot = Nothing
Set ResItems = Nothing
Set CalItems = Nothing
Set CalFolder = Nothing
Set nicknames = Nothing
End Sub
'Roam date helper function
Function ordinals(i As Integer)
Select Case i
Case 1, 21, 31
ordinals = "st"
Case 2, 22
ordinals = "nd"
Case 3, 23
ordinals = "rd"
Case Else
ordinals = "th"
End Select
End Function
'To map how people are called in the company directory and in my Roam database
Sub initializeNicks(ByRef nicknames As Scripting.Dictionary)
nicknames("Name in Company Directory 1") = "Nick Name 1"
nicknames("Name in Company Directory 2") = "Nick Name 2"
'....
End Sub
'implement your own function to clean or transform names depending on the naming convention at your company, etc.
'in my case I only keep the part of the name before the opening bracket
Function cleanName(sAtt) As String
bp = InStr(sAtt, "(")
If bp > 0 Then
sAtt = Trim(Left(sAtt, bp - 1))
Else
sAtt = Trim(sAtt)
End If
cleanName = sAtt
End Function
Function listAttendees(ByRef item As Variant, myself As String, ByRef nicknames As Scripting.Dictionary) As String
listAttendees = ""
Dim sAtt As String
For i = 1 To item.Recipients.Count
sAtt = item.Recipients.item(i).Name
sAtt = cleanName(sAtt)
If nicknames.Exists(sAtt) Then
sAtt = nicknames(sAtt)
End If
If sAtt <> myself Then
If listAttendees <> "" Then
listAttendees = listAttendees & ", "
End If
listAttendees = listAttendees & "[[" & sAtt & "]]"
End If
Next
End Function
```
# Meetings
I distinguish 5 different type of meetings:
## 1. Reoccurring Meetings
**Timing:** _#weekly_, _#bi-weekly_, or _#monthly_
**Length:** 15-30-45-60 minutes (typically has a fixed reoccurring calendar entry in Outlook)
**Attendees:** the same person or people every time
**Objective:** to stay in sync, to track progress, to work on a subject
**Pre-work, Decisions, Notes:**
- I don't create a new page for these every time, but always reference the same. This requries a little attention in setting meeting subject in Outlook, but not that much. Really.
- I usually have Roam open during the meeting and I take notes into Roam real-time or right after the meeting has finished, while I still remember what was discussed.
- My notes are organized by date. Every time the meeting repeats I add Today's date as a ((block reference)) from the Daily Notes page to the top nested under Notes (see picture below). With this approach I can easily scroll down to see what was discussed in previous discussions. The reason for the seemingly _strange approach_ of inserting the date as a ((block reference)) has to do with how Roam queries deal with dates. When I add an action in the notes, I only want that {{[[TODO]]}} to show up under the date assigned to the action, not on the day when I took notes in the meeting. I will share more on this later when I explain the **day** and **nw - now** SmartBlocks.
- ![[Bbi8pWPZ0x.png|]]
**Examples:**
- 1-1 meetings with my team and with key stakeholders
- team meetings with my direct reports or my peers
- steering committee meetings
- project status reviews
## 2. Once-off Meetings
**Timing:** pre-scheduled, when needed
**Length:** 30 minutes to three hours
**Attendees:** one or more people depending on the subject
**Objective:** to resolve a current issue or escalation
**Pre-work, Decisions, Notes:**
- Pre-work might be required and distributed few days prior to the meeting.
- Often the meeting is organized to achieve one or more specific decisions.
- A Minutes of Meeting is usually sent after the meeting to summarize the decisions.
**Examples:**
- discussion initiated by a supplier
- escalation of an issue
- a demo session or a deep dive into a specific topic
## 3. Workshops
**Timing:** planned well in advance
**Length:** half-day, full-day or multi-day
**Attendees:** small to mid-size team
**Objective:** to work on a topic in detail, review a broader subject such as annual planning
**Pre-work, Decisions, Notes:** typically involves significant upfront planning and pre-work for the organizers and the participants
- organizer: designing the agenda
- organizer: developing pre-read
- participant: reviewing pre-read
**Examples:**
- leadership or team workshops
- project specific workshops: discovery workshop, planning workshop, design workshop, etc.
## 4. Conferences
**Timing:** planned well in advance
**Length:** full-day or multi-day
**Attendees**: larger crowds
**Objective:** discuss a topic of common interest, learn what's happening elsewhere, network
**Pre-work, Decisions, Notes:** involves significant upfront planning and pre-work primarily falling on the shoulders of the organizers and presenters
- Typically no Minutes of Meeting is distributed after the conference, but the conference papers and recordings of the sessions might be available for viewing or for download to participants.
**Examples:**
- large industry conferences
## Ad-hoc Meetings
**Timing:** ad-hoc
**Length:** few minutes to half and hour
**Attendees**: typically one, maybe few people
**Objective:** discuss a current question or issue, may also be just a social interaction
**Pre-work, Decisions, Notes:**
- No pre-work.
- Decisions might be reached, in which case it is good to send a very brief reminder email afterwards.
**Examples:**
- someone stopping by my office
- bumping into someone at the cafeteria or on the corridor
- receiving a call, or calling someone with a question
- unplanned escalation of an issue
## My templates
I use three different templates.
Reoccurring meetings and once-off meetings are generated from Outlook and the template is embedded into the Visual Basic script included above.
For workshops and conferences I create the page in Roam well in advance of the event using a the **MoM - Minutes of Meeting** SmartBlock.
### MoM - Minutes of Meeting
![[mom.png|]]
```markdown
- #42SmartBlock MoM - Minutes of Meeting
- Tag:: <%INPUT:tags?,%%#1-1 #team-meeting #steering-committee #working-session%>
- Subject:: <%CURSOR%>
- When:: <%DATE:today%>
- Attendees::
- Location::
- Summary::
- Pre-read::
-
- Decision::
-
- Notes::
```
Ad-hoc meetings also have their dedicated page. I use two scripts to generate them. First I use **mn - Meet Now** on Daily Notes to create a page for the ad-hoc meeting and to open it in the sidebar. Then I use **ahm - Ad-hoc Minutes of Meeting** to pre-populate the meeting page with the ad-hoc meeting template.
### mn - Meet Now
```markdown
![[GTD.png|]]
- #42SmartBlock mn - Meet Now
- <%J:```javascript
roam42.smartBlocks.activeWorkflow.vars['page_title'] = 'meeting/' + prompt('Subject of the meeting?');
return roam42.dateProcessing.getTime24Format() + ' ['+'['+roam42.smartBlocks.activeWorkflow.vars['page_title']+']]';```%>
- <%NOBLOCKOUTPUT%><%J:```javascript
let inPut = document.getElementById('find-or-create-input');
inPut.focus();
roam42.common.setEmptyNodeValue( inPut, roam42.smartBlocks.activeWorkflow.vars['page_title'] );
setTimeout(()=>{
roam42KeyboardLib.simulateKey(13,100,{ shiftKey:true});
}, 200);```%>
```
### ahm - Ad-hoc Minutes of Meeting
![[ahm.png|]]
```markdown
- #42SmartBlock ahm Ad-hoc Meeting MoM
- Tag:: #ad-hoc-meeting
- Attendees:: <%CURSOR%>
- Notes::
-
```
# My note taking approach
Meetings get their own page. Ad-hoc meetings I sometimes record on Daily Notes, but only if there are no actions agreed.
Meeting pages are created in specific namespaces: _meeting/_, _workshop/_, _conference/_
Actions are recorded as part of meeting notes.
I capture notes in Reoccurring Meetings as explained above, providing an easy to access log of previous discussions.
![[Bbi8pWPZ0x.png|]]
When meeting with someone I open the page for the person in the sidebar to see if there are any _**#**waitingFor_, _**#**discussWith_, _**#**promisedTo_ items to be discussed. (see below under People)
# Actions
I come across dozens of actions each day. Most of them I delegate. I am extremely selective regarding which actions I record for tracking purposes. I only track high priority actions that I also expect to be chased on, or in which I have something to contribute.
I aim to place **TODO**s to the highest possible level of the bullet-point hierarchy. My TODO blocks contain the name of the action party and a brief ([SMART](https://en.wikipedia.org/wiki/SMART_criteria)) description of the action. I prefer shallow nesting to avoid long snippets of text in query results and action references.
Actions get one or more of the following tags: _**#**discussWith_, _**#**waitingFor_, _**#**promisedTo_ and _**#**errands_
- {{[[TODO]]}} #discussWith [[The Person]] by [[December 24th, 2020]]: Topic of the discussion
- {{[[TODO]]}} #waitingFor [[The Person]] by [[December 31st, 2020]]: The promise I received
- {{[[TODO]]}} I #promisedTo [[The Person]] that by [[December 27th, 2020]] I will...
- {{[[TODO]]}} #errands when visiting [[IKEA]] don't forget to ....
Multiple actions with the same person get nested under a block with the name of the person.
I keep tasks off the daily notes page unless it has yet to be processed. TODOs with due dates are recorded on a page other then the Daily Notes page e.g. project page, meeting page, person page.
# People
Each person gets a page with metadata defined in the **person** SmartBlock.
The person's page includes three queries: _**#**waitingFor_, _**#**discussWith_, _**#**promisedTo_. "Waiting for" are the TODOs I have agreed a person to deliver to me. "Discuss with" are topics - potential future actions -, that I want to discuss with the person next time we meet. "Promised to" are my promises, if someone asked me to help with something and I made a commitment to take action.
I collect examples for performance review meetings during the year by tagging relevant information with _**#**forPRM_ and adding the individual's name. I can filter for these under linked references when the time comes for the performance review meeting.
When I meet with someone, I have made it a habit to open the page for the person in the sidebar, to see if there are any _**#**waitingFor_, _**#**discussWith_, or _**#**promisedTo_ items to be covered.
![[vc-K2DPICt.png|]]
### My person template
My person template takes the name of the person from the title of the page to customize the 3 queries at the bottom of the page.
![[person.png|]]
```markdown
- #42SmartBlock person
- <%NOBLOCKOUTPUT%><%SET:page_title,<%JAVASCRIPT: return document.querySelector('.rm-title-display').textContent;%>%>
- Tag:: <%INPUT:Tags?%%#person #author #businessassociation #colleague #vendor #contractor #speaker #family #friend #sportsassociation %>
- Photo::
- Phone Number::
- Email:: <%CURSOR%>
- Company::
- Location::
- Assistant::
- Role::
- How we met::
- Birthday::
- Interests::
- Spouse & children::
- **Waiting for**
- {{[[query]]: {and: [[<%GET:page_title%>]] [[waitingFor]] [[TODO]] {not: [[query]]}}}}
- **Discuss with**
- {{[[query]]: {and: [[<%GET:page_title%>]] [[discussWith]] [[TODO]] {not: [[query]]}}}}
- **Promised to**
- {{[[query]]: {and: [[<%GET:page_title%>]] [[promisedTo]] [[TODO]] {not: [[query]]}}}}
- Notes::
-
```
# Daily Notes page
The image below shows my daily notes page for tomorrow. There are two things I want to draw your attention to.
![[t87viNbsPy.png|]]
![[Bbi8pWPZ0x.png|]]
First, at the top I have today's date in the second bullet. When calling the **;;day** SmartBlock, it automatically stores the reference to this block in a variable, so whenever I am on a meeting page, I can run **;;nw - Now** and insert a reference to today's date, to create the meeting-log as mentioned above. If you recall the reason I reference today's date in meeting notes like this is to ensure queries only bring up actions based on the due date specified in the action. Else all the actions I record in meetings would show up in the queries below twice: once with the day when they were captured, and second with the due date for the action. This would create clutter.
Second, I try to avoid placing TODO's on the Daily Notes page. The only exception is placing the TODO on a future Daily Note page, to be reminded when the day comes. Changing deadlines and moving tasks to a different date is more cumbersome that way, this is why I prefer placing TODO's on other pages such as Meetings, People, Projects, but also Book Reflections and other notes.
The short video below demonstrates how the process of taking notes in a meeting works. **1)** I shift-click on the meeting to open it in the sidebar. **2)** I use **;;nw - Now** to insert today's date in the meeting log. **3)** I start taking notes and record an action. **4)** The action does not show up in the query as today's task - which is what I wanted! -, however **5)** by clicking the references next to the date block at the top I have an easy way to list all actions recorded on the day. **6)** Finally I also show how, if I would use the [[Date]] instead of the ((block reference to the date)), the new action would wrongly show up as today's action on my daily page, cluttering the view.
As a final note, I do not use the **;;nw - Now** ((date reference)) when I have a once-off meeting, since the date of the meeting is in the metadata section of the meeting and the Note is not nested under this date, thus the problem with the double counting in queries does not arise.
![[t87viNbsPy.png|]]
## My Templates
### day
Download the day template as a Roam.JSON file from [here](https://zsviczian.github.io/DayTemplate.zip).
![[day.png|]]
```markdown
- #42SmartBlock day
- <%J: ```javascript
let UID = document.querySelector("textarea.rm-block-input").id;
localStorage.setItem('today_date_blockRef','((' + UID.substring( UID.length -9) + '))');
return document.querySelector('.rm-title-display').textContent;```%>
- <%NOBLOCKOUTPUT%><%JAVASCRIPTASYNC: ```javascript
var settings = {
"url": "https://api.quotable.io/random",
"method": "GET",
"timeout": 0,
"async": false
};
$.ajax(settings).done(function (response) {
console.log(response);
var jsonQuotes = JSON.stringify(response);
var quote = JSON.parse(jsonQuotes);
roam42.smartBlocks.activeWorkflow.vars['author'] = quote.author;
roam42.smartBlocks.activeWorkflow.vars['quote'] = quote.content + ' #quote';
});
return '';``` %>
- > <%GET:quote%>
[[<%GET:author%>]]
- <%IFDAYOFWEEK:2,3,4,5,6,7%>**Top 3 goals for today**
- <%IFDAYOFWEEK:2,3,4,5,6,7%>
- <%IFDAYOFWEEK:1%>**Top 3 goals for this week**
- <%IFDAYOFWEEK:1%>
- **Meetings**
-
- **Today’s successes**
-
- **How could I have made today better?**
-
- **Notes**
-
- **TODO**
- **Tasks for today**
- {{[[query]]: {and: [[TODO]] {not: {or: [[query]]}} <%DATE:today%> }}}
- **Overdue from previous month**
- {{[[query]]: {and: [[TODO]] {not: {or: [[query]]}} {between: <%DATE:yesterday%> <%DATE:one month ago%>} }}}
```
### nw - Now
![[nw.png|]]
```markdown
- #42SmartBlock nw - Now
- <%JAVASCRIPT: return localStorage.getItem('today_date_blockRef') + ' ' + roam42.dateProcessing.getTime24Format();%>
```
# Information security and other closing thoughts
Finally I wanted to comment on information security. I'd love if I could simply include every information I ever wanted to store and organize in Roam, but this desire needs to be balanced with keeping information safe, both corporate and personal. As closing thoughts I wanted to share some of my related approaches with you.
First, I never upload corporate files to Roam. I include links to files, but never the actual content. I do the same for my personal files as well. I store my files mostly on OneDrive and add links to Roam. Back in May I developed a simple tool to generate markdown formatted links for my OneDrive files that are easy to embedding into Roam and look good as well. Check out [get-my.link](https://get-my.link/). Note that for some reason I couldn't get the OneDrive file picker component from Microsoft to work with either Internet Explore or Edge. The site works well with other browsers.
If I reference emails in my notes, I also never include the email body. What I typically do is include the search term I can copy into Outlook that will pull up the email or the discussion thread. e.g.:
- _subject:"this is the subject" AND from:theSender_
- _category:"my mail category"_
Regarding personal information such as the _#forPRM_ tag, I use the Roam {{encrypted text}} command to safeguard the information.
Finally, I do regular backups.
# I would love to hear what you think
If you have questions, ideas, want to share your own approach, or learned something that you want to experiment with yourself... I would love to hear your feedback! Please leave a comment.
Thank you.
# Other posts you might be interested in
- Containing Roam42 SmartBlocks:
- [[My Book Summaries in Roam Using Tiago's Progressive Summarization]]
- [[De Bono's Algorithms of Thought for Lateral Thinking and Creativity Part 1]]
- [[TOSCA an Algorithm for Framing Problems]]
- [[De Bono's Algorithms of Thought for Handling Disagreements]]
- Productivity:
- [[Pattern for staying connected with your team at work]]