Configure Google Calendar For Calcurse with systemd sync and bonus NeoMutt sync.

I recently set up NeoMutt with GMail updated by systemd sync (bonus content down below) and thought it would be cool to have my Calendar in Calcurse and sync it as well.

I found the info on the subject around the net that was not so clear, or even correct, causing me to fumbled around until I got things working. This is to help others who may be as annoyed as I was setting this up.

Disclosure: I am running Manjaro Linux, might make a difference, with HyperLand and Sway, that should not make a difference. Should work with Gnome or anything else. Your paths may or may not be different and your install process may or may not be different as well. I will be using pacman to install everything that is needed.

Google API configuration

I will try my best to explain this as there are a couple ways to get it done and Google doesn’t make things clearer!

The first thing you need to do is create a project in the Google Cloud console. You will need to log on and you should not need to change your account settings unless you have enhanced security enabled. Do not turn off two factor auth, or turn it on if you are not using it. You do not need to create an application password as you will authenticate in a similar manner to you normal account.

This may help you navigate if you get lost in the Google weeds.

Go to Google Cloud Console under IAM. Create a project, name it whatever you like, but I would at least name it so you know what it is for. Don’t forget to save in the sections that require it.

Once your project is created, focus on APIs, GoogleAuth Platform, IAM, and Admin. sections.

On the left side options select APIs & Services. Add Google Calendar API (I selected things that made sense for day to day calendar use, like viewing and saving). I am not sure you can really create, select, or share calendars from Calcurse so it seems useless to select those. Important! Do the same for CalDav APIs. If you do not add this it will not work.

This next part may come before I selected the APIs, I don’t remember to be honest. Either way, everything can be configured out of order as long as you get them all.

Go to Credentials and create credentials: Select OAuth Client ID, select as desktop. When it’s done, download the file. It has your client id, secret, and redirect url that needs to go in the CalCurse-CalDav config file.

I created a consent, although, not sure I needed to. I gave it a name and added my email so I could complain to myself when things break. I also did not point to any sites, I left them blank. I did give myself access as a user. Not sure I needed to do that since I am owner, but I did it for good measure.

To navigate to add yourself as a valid user, and other goodies, select the hamburger menu at the top left and select APIs and Services. From there select Credentials. The menu on the left should change. Select OAuth Consent. The menu on the left will change again. Select Audience. There you can add your email to grant access. Also, in Audience verify that the User type is set to External. That should be the default and already set if all is going well.

Yay, the most irritating part is done.

Install the software and libraries

Open a terminal for this.

If you have not already done so, install CalCurse! Of course you did or you wouldn’t be reading this. But here it is anyway…

sudo pacman -S calcurse

Now install the required libraries:

sudo pacman -S python-oauth2client

sudo pacman -S python-httplib2

I had to create the following folders so I assume you will too. We will do this in the terminal as well, in order:

cd ~

mkdir .calcurse

cd .calcurse

mkdir caldav

cd caldav

nano config

Add the following contents pulling the client id and secret from the file downloaded from Google:

[General]
Binary = calcurse
Hostname = apidata.googleusercontent.com
Path = /caldav/v2/youremail@gmail.com/events/
AuthMethod = oauth2
SyncFilter = cal
#InsecureSSL = Yes
#HTTPS = Yes
DryRun = No
Verbose = Yes

[OAuth2]
ClientID = ClientID copied from the Google file
ClientSecret = Secret copied from the Google file
Scope = https://www.googleapis.com/auth/calendar
RedirectURI = http://localhost

The redirect url is in the file you downloaded from Google and should match the above. If not, something went wrong and you may need to do the Google setup again. Add your Google email name in the path where noted, i.e., “youremail”.

Save by hitting ctrl s or ctrl w them hit enter. Exit nano with ctrl x

Authenticate and finalize calcurse-caldav.

Still in the terminal we need to run calcurse-caldav, I ran it with –init keep-remote as I did not know what the hell I was doing and got that from somewhere, like so:

calcurse-caldav –init keep-remote

When you run this the web browser should open where you authenticate to Google as normal. You may need to verfiy it’s you in YouTube or whatever. Now when you auth it will die as your redirect “localhost” is not valid. Do not close the browser, copy the path in the address bar between code= and &. That is the auth code.

If you copy commands that require two dashes on a command (–init and –user) that command will likely fail. Remove the dash and type the two dashes in your terminal. It does not translate well from this page to terminal.

One you have that copied we need to run calcurse-caldav again and hand it that authcode, like so:


calcurse-caldav –init two-way –authcode ‘PASTE THE AUTH CODE HERE BETWEEN SINGLE QUOTES’

If you do not get an error, all is working as expected and the calendar should sync! If not, insert quarter and try again. It took me two tries to get it… 🙂

Automating Sync with systemd

Now we will create a timer and a service to sync our calendar. Again, I am on Arch based system so your paths may be different, but likely not.

You can use a text editor if you like or follow along in the terminal.

cd ~/.config/systemd/user/

nano calcurse.timer

In the calcurse.timer file add the following. I sync every 30 minutes, adjust to your needs in OnCalendar=*:0/15 for 15 minutes, etc.

[Unit]
Description=Calcurse synchronisation timer
Requires=calcurse.service

[Timer]
OnCalendar=*:0/30
Persistent=true
AccuracySec=4s

[Install]
WantedBy=timers.target

Save the file.

Now the actual service:

nano calcurse.service

Add the following, verifying that calcurse is at that path. You can check it in the terminal with which calcurse-caldav

[unit]
description=Calcurse synchronisation service

[Service]
Type=oneshot
ExecStart=/usr/bin/calcurse-caldav

[Install]
WantedBy=default.target

Save the file.

Now we need to do three more things and we are done. In the terminal again:

systemctl –user enable calcurse.timer

systemctl –user start calcurse.timer

systemctl –user enable calcurse.service

Create an event on you phone and an event in Calcurse. If everything is working they should appear in both places.

Bonus: NeoMutt mail sync!

I have Google mail in NeoMutt, which I could have likely set up in Google Cloud, but I am not nerdy enough for that level of torture. I decided to setup a AppPassword at Google instead and I configured NeoMutt using Mutt-Wizard. If you configured that way, and set up you password with pass, this should work for you. All you need to do is create another timer and service.

Save these to ~/.config/systemd/user

Add the following and save as neomutt.timer. As before, if you read all this shit, you can adjust the time to your needs. This syncs every 15 minutes.

[Unit]
Description=NeoMutt synchronisation timer

[Timer]
OnBootSec=2m
OnUnitActiveSec=15m
Unit=neomutt.service

[Install]
WantedBy=timers.target

Create a file named neomutt.service and add the following

[unit]
description=NeoMutt synchronisation service
#Requires=gpg-agent.socket

[Service]
Type=oneshot
#Environment="PASSWORD_STORE_DIR=/home/youruserid/.password-store"
#Environment="GNUPGHOME=/home/youruserid/.gnupg"
Environment="XDG_CONFIG_HOME="/home/youruserid/.mbsyncrc"
ExecStart=/usr/bin/mbsync -a

[Install]
WantedBy=default.target

I left the password related stuff in, but for this it was not needed. You do need the .mbsyncrc that mutt-wizard created. This assumes it created it in the same location as me, but verify where that file lives and change the path if need be, and don’t forget your user name in there or it ain’t goin’ to werk.

Enable and start the service(s)

systemctl –user enable neomutt.timer

systemctl –user start neomutt.timer

systemctl –user enable neomutt.service

If you need to set Calcurse up on another machine, simply copy .calcurse and the calcurse folders from .config and .local/share to the same locations and you should be able to sync without reconfiguring. You can copy the .timer and .service files too and just start the service(s).