If you’re not familiar with it, what3words, is one of those rather wonderful instances where technology solves a mundane problem - easily share the specific location of where you are / need people to go. So rather than a post/zip code which, can be hugely unreliable, each 3m x 3m square on the planet is given its own unique 3 word address. For example, the centre of Stonehenge is:
So, as Drafts already records the location of a draft’s creation/modification, I was wondering if it would be possible to tie this into the what3words API? It would be very handy to be able to share locations of historical and current drafts in this user-friendly format.
This can easily be done with an action. I’m not sure what you want to do with the what3words response, but I’ve created an example action that lets you copy it or open in what3words.
So you don’t write anything in Drafts itself - just run an action which includes templated text and calls w3w based on current location. You can then share via share sheet.
The only benefit here over the w3w app is that you can include a message opposed to just the link when you share with w3w app. Admittedly an iOS shortcut could cover this off.
Historical/noting specific location details: This is where I see it being more beneficial going forward.
You may have taken a draft/notes pertinent to a specific location when at that location. E.g. “This stile had been blocked off on the x walk,” or “should have gone for the fish and chips as the portions were massive.” So when sharing this draft, it would be handy to have an action that rendered it something like:
"As discussed, here are the notes I made:
‘[[original_draft_content]]’
[[original_draft_creation time]]
w3w URL for original draft"
Hope this better articulates the use cases I envisaged.
I updated the action to see if it gets closer to what you were looking for. You could set up a “share & delete” action for either of these, so that the new drafts don’t hang around for long.
Sounds as if w3w are gathering a fair bit of momentum now. Mercedes are on board and TomTom are to adopt 3 word addressing too. It’s a very clever idea and I love the work they have done in Africa etc.
Okay, data seems to be populated by the getWords() function. That writes any API return failures to the console (log). Do you have any details preceding the error you found in the log? when the action runs, it does not look like it will terminate processing when the API call fails. But it also does not look as though it logs a successful API call, only failures. We have to infer at this point what is going on by the presence or absence of the additional info.
My best guess would be the expected value is undefined because the API call did not return the data structure the subsequent processing requires. The most likely reason is that the API call failed, in which case the logged error code and reason should give an indication as to why. Hopefully, that will then help figure out how to resolve your issue.
I’ve just given the action a test, and it worked fine for me, and so there are only two factors at play - Drafts knowing your location, and the validity of the API key.
Assuming you entered the key correctly (mine is similar to ACTORON7), have you enabled location services access at the OS level for Drafts to grab your current location?
Hopefully, something above will get you on the right track.
I changed the script as follows and it works again:
/* Send templates with w3w location */
(() => {
'use strict';
// main() :: Body of script and local functions
const main = () => {
const getWords = () => {
// Create API credential
const credential = Credential.create("what3words API", "Key to access what3words REST API");
credential.addTextField("Api_Key", "API Key");
credential.authorize();
const cLon = draft.createdLongitude,
cLat = draft.createdLatitude,
coordinates = `${cLat},${cLon}`,
key = credential.getValue("Api_Key"),
http = HTTP.create(),
base_url = "https://api.what3words.com/v3/convert-to-3wa?",
params = {
"coordinates": coordinates,
"key": key,
"lang": "en",
"format": "json",
"display": "full"
};
let strs = [];
for (let k of Object.keys(params)) {
strs.push(`${k}=${encodeURIComponent(params[k])}`);
}
const url = base_url + strs.join('&'),
response = http.request({
"url": url,
"method": "GET"
});
if (response.success) {
const text = response.responseText;
return JSON.parse(text);
} else {
console.log(response.statusCode);
console.log(response.error);
}
}
const data = getWords(),
words = data.words,
mapLink = data.map;
if (words) {
// Create prompt
const p = Object.assign(Prompt.create(), {
title: "Location",
message: "Share Location",
isCancellable: true
}),
// Build 2d array of buttons/actions
buttons = [
['Copy to Clipboard', () => app.setClipboard(words)],
['Open in what3words', () => app.openURL(mapLink)],
['Create Template with Loc', () => createTemplateDraft(mapLink)],
['Create Draft Copy with Loc', () => createDraftCopyWithLoc(mapLink)]
],
bMap = new Map(buttons);
bMap.forEach((v, k) => p.addButton(k))
const picked = p.show();
if (picked) {
bMap.get(p.buttonPressed)();
} else {
context.cancel();
}
}
}
// MAIN --------------------------------
// createTemplateDraft :: w3w link -> Template msg
const createTemplateDraft = locLink => {
const msg = `I am waiting here. Give me a call if any issues.\n\n${locLink}`,
d = Draft.create();
d.content = msg;
d.update();
editor.load(d);
};
// createDraftCopyWithLoc :: w3w link -> Copy with loc link and msg
const createDraftCopyWithLoc = locLink => {
const createTime = draft.createdAt.toString("F"),
origText = draft.content,
newText = `As discussed, here are the notes I made:\n\n${origText}\n\n${createTime}\n\n${locLink}`,
d = Draft.create();
d.content = newText;
d.update();
editor.load(d);
};
return main();
})();
only changes in the base URL and the parameters where adapted. Did not test the full functionality of the action. Maybe @comfortablynick wants to update the public action
I generated a new API key on my W3W account and used it with a new version of the action using the script @FlohGro posted above. Once again it works fine for me.
Here is the action updated to use the script from above. The only modification I made is to the name of the credential so I could have both actions with both API keys alongside one another.
Try it and see if that works. Maybe you copied something wrong?