How to: get your location and weather data via AppleScript (and automate it to make your own journaling app)

I’ve been going through love/hate relationships with journaling apps: I like the principle of journaling, but I find the apps are often glorified text editors sold at a premium for a very specific use case and not always have good security. Additionally, I’m increasingly finding that siloing my nascent thoughts in a specific app keeps them separate from my main notes, where they could be leveraged to benefit my ideas more.

So I’ve been thinking: what makes a journaling app? At the core, to me, it’s about

  • Ironclad security (end-to-end encryption)
  • The ability to add some media, especially images
  • Knowing where I wrote something (I live in two vastly different places)
  • Having the weather would be fun to have, but not mandatory

Obsidian ticks all these boxes, apart from the last two pieces. On iOS, it’s trivial to insert that data using Shortcuts, on a Mac it’s harder, and I’ve been thinking, since I mostly use my Mac, could I get all that functionality with nice scripts and maybe Keyboard Maestro?

After doing lots of exploration on various forums, cobbling together half a dozen of scripts, digging blindly into JSON files (and studying especially the DEVONthink journaling template), turns out that you can, here’s how.
Of course, if anything here blows up your computer or your wallet, I take no responsibility whatsoever, use at your own risk, yadda yadda.

Get the tools ready

You need a few helper apps:

Then you need to open two free developer accounts.

Both services listed below are free for a limited usage, and if you don’t hammer the servers with constant requests, you should remain well within the limits of free account for a personal use.

For the weather data:

  • Go to https://openweathermap.org/, open an account, confirm your email.
  • Go to Account → My API keys, request an API key, name it however you like. Keep it handy.
  • Go to the API page, subscribe to “Current Weather Data”.

Beware that Open Weather Map takes up to two hours to activate API keys. If your scripts fail, maybe it’s because your API key is not valid yet. Wait a little.

For the location data:

You can very readily get latitude and longitude with Location Helper, but I wanted a human-readable addresses. For that, we will use Google Maps.

The scripts

They can be activated through anything that can execute scripts, but for the convenience of activating them, either inside other macros or via a string sequence, I keep mine in Keyboard Maestro. Don’t forget to paste your API keys where indicated (keep the quotes!).

Insert weather data (with emojis)

property weatherAPI : "<insert your OpenWeather Map API here>"

tell application "JSON Helper"
	
	try
		
		(* Get my latitude and longitude*)
		tell application "Location Helper"
			set listCoords to get location coordinates
			set _lat to item 1 of listCoords as text
			set _lon to item 2 of listCoords as text
		end tell
		
		set Weather_Display to ""
		
		(* Get current weather from OpenWeather *)
		
		set getWeathersource to fetch JSON from ("https://api.openweathermap.org/data/2.5/weather?lat=" & _lat & "&lon=" & _lon & "&exclude=minutely,hourly&units=metric&appid=" & weatherAPI)
		
		set getWeather to "High: " & temp_max of main of getWeathersource & return & return & "Low: " & temp_min of main of getWeathersource & return & return & "Current: " & temp of main of getWeathersource & return & return & "Humidity: " & humidity of main of getWeathersource & return & return & "Conditions: " & description of item 1 of weather of getWeathersource
		set Current_Temp to (round (temp of main of getWeathersource)) & "°"
		set Daily_Temp to "Min " & (round (temp_min of main of getWeathersource)) & "° " & "to a " & "Max " & (round (temp_max of main of getWeathersource)) & "°"
		set Weather_Display to "## Weather" & return & return & getWeather & return & return
		
	end try
	
end tell

if Weather_Display contains "clear" then
	set WeatherIcon to "☀️ Ensoleillé,"
else if Weather_Display contains "thunderstorm" then
	set WeatherIcon to "🌧⚡️ Orages,"
else if Weather_Display contains "drizzle" then
	set WeatherIcon to "🌦 Bruine,"
else if Weather_Display contains "rain" then
	set WeatherIcon to "🌧 Pluie,"
else if Weather_Display contains "snow" then
	set WeatherIcon to "❄️ Neige,"
else if Weather_Display contains "sleet" then
	set WeatherIcon to "❄️ Neige fondue,"
else if Weather_Display contains "mist" then
	set WeatherIcon to "🌫 Brume,"
else if Weather_Display contains "fog" then
	set WeatherIcon to "🌁 Brouillard,"
else if Weather_Display contains "squalls" then
	set WeatherIcon to "💨 Bourrasques,"
else if Weather_Display contains "smoke" then
	set WeatherIcon to "🔥 Fumée,"
else if Weather_Display contains "haze" then
	set WeatherIcon to "🌫 Voilé,"
else if Weather_Display contains "clouds" then
	set WeatherIcon to "⛅️ Nuages,"
else
	set WeatherIcon to "🌡"
end if

set theForecast to ""
set theForecast to WeatherIcon & " " & Current_Temp

return theForecast

Of course, translate the weather to your own language if you don’t want to use French. But why wouldn’t you, you monster?

Insert geolocation data

This script returns your location as a human-readable address instead of raw latitude and longitude.

tell application "JSON Helper"
	
	tell application "Location Helper"
		
		set listCoords to get location coordinates
		set _lat to item 1 of listCoords as text
		set _lon to item 2 of listCoords as text
		
		set getLocation to reverse geocode location with API key "<Insert your Google Maps API key here>"
		set location to formatted_address of item 1 of results of getLocation
		
	end tell
	
end tell

return location

Make it Markdown

Now we want something pretty. Since we have macros that return plain text, it’s easy to add some Markdown formatting, and build for instance clickable links for our location data that take us to a visual map on the Internet. But since I’m a contrarian son of a killer whale, I was not happy with having my outbound links going to Google Maps. I’m happy using it as service, but I wanted my links to go to Apple Maps. (Yeah, I know, Google will still have my data, but… it was fun to do.)

If you want your location to be formatted as a Markdown link going to Apple Maps, use this script instead if the previous one (once again, don’t forget to add you API key).

on findAndReplaceInText(theText, theSearchString, theReplacementString)
	set AppleScript's text item delimiters to theSearchString
	set theTextItems to every text item of theText
	set AppleScript's text item delimiters to theReplacementString
	set theText to theTextItems as string
	set AppleScript's text item delimiters to ""
	return theText
end findAndReplaceInText

tell application "JSON Helper"
	
	tell application "Location Helper"
		
		set listCoords to get location coordinates
		set _lat to item 1 of listCoords as text
		set _lon to item 2 of listCoords as text
		
		set getLocation to reverse geocode location with API key "<Insert Google Maps API key here>"
		set location to formatted_address of item 1 of results of getLocation
		
	end tell

end tell

set _lat to findAndReplaceInText(_lat, ",", ".")
set _lon to findAndReplaceInText(_lon, ",", ".")

set markdownLocation to "[" & location & "]" & "(https://maps.apple.com/?ll=" & _lat & "," & _lon & ")"

return markdownLocation

Combine everything… and add it automatically to your Obsidian daily notes

Now we have two macros, one for weather and one for location in a humanly readable format. Since Obsidian uses plain Markdown files on your disk, it’s very easy to have Keyboard Maestro watch the folders where you want your new files to have your weather and location data automatically inserted. In my case, I’m watching my Daily notes folder, where I journal, for new files. The trigger is: “This folder” (insert your folder path) “adds an item”.

I simply have a macro built of the two scripts, which inserts geolocation and weather, in the middle (Insérer emplacement et météo). Anytime I create a daily note, I have a nicely formatted journal template with my location and weather at the bottom and an entry ready to be typed with a h1 title!

One last tip: if you want to avoid the macro the fire when you manipulate files in your vault, put it into a Keyboard Maestro group that’s only enabled when Obsidian is active. That way, the data will only be inserted when you create notes from within Obsidian.

Have fun!

1 Like

If you want the current weather from a know location copied into the clipboard:

This:
curl ‘wttr.in/Paris?format=4’ | pbcopy
Will get you:
Paris: :sun_behind_rain_cloud: :thermometer:+9°C :wind_face:→30km/h

1 Like

Ah that’s a lot simpler :grinning_face_with_smiling_eyes: