This is the fifth article in a series of unknown length discussing using a tool written in Lua to publishing posts on a WordPress blog.
- Part 1 showed how to use XML-RPC and
wp.newPost
- Part 2 added file reading to make a minimal working utility.
- Part 3 added amenities and made the utility useful.
- We digressed to talk about OAuth and using it at WordPress.com.
- Part 4 switched to cURL, REST, and OAuth, but can’t yet post.
Soon we will restore the ability to make a post, and add the ability to include categories and tags with the new post.
But first, some cleanup
(The changes described in this section are checked in at 870da6391b.)
Authorization of the app is still clumsy, and requires a manual copy and paste. We won’t be fixing that yet, but we can at least make it easier to handle.
As described in all its gory detail earlier, you need to authorize the application to have access to your blog by visiting this authorization link or its equivalent if you have registered for your own WP application. When you finish filling out the form to grant access, you will be redirected to the app’s registered redirect URL. At present, that is a page at this blog but that could change if we streamline the authorization process in the future.
When you arrive on the redirection page, click in your browser’s URL field and copy the entire URL to the clipboard.
Then at a command prompt open with our REST version of wppost.lua
available, enter the command (on one line):
wppost.lua --tokenurl "PASTE_IN_THE_WHOLE_TOKEN_HERE" --blog "yourblog.wordpress.com" --writeconfig
and be very sure to include the quotation marks around the pasted URL. That will update the privately stored file rest.ini
(found at C:\Users\Ross\.wppost\rest.ini
on my Windows 7 box, and likely in a similar place on your Windows box) to contain a copy of the OAuth 2.0 access token and its expiration date. If you aren’t granting access to curiouser.cheshireeng.com
(which you really shouldn’t be able to do if you aren’t me anyway) you will need to remember to include the --blog
option with the full domain name of your blog as known to WordPress and/or JetPack.
Of course, you can still peek at the saved configuration with the --showconfig
option.
Here is the code that implements the --tokenurl
parsing:
-- Parse the useful data out of a token redirect URL -- Keep the token, confirm the other details. -- -- http://<BaseURL>/#access_token=<URL-Encoded-Token>&expires_in=<seconds>&token_type=bearer&site_id=73256621 -- if args.tokenurl and #args.tokenurl >= 64 then local base,rest = args.tokenurl:match"^([^#]+)%#(.+)$" if not rest then lapp.error("Please provide the entire URL and be sure to quote it.") else local t={} for k,v in rest:gmatch"([^&=]+)=([^&=]+)" do t[k] = v end args.token = t.access_token args.expires = tostring(os.time() + (tonumber(t.expires_in) or 0)) end end
This first splits the provided URL into the base (everything before the #
character) and the rest. We ignore the base, but in principle it could be tested to verify that the URL you pasted came from the expected redirection.
The rest of the URL is matched for all sequences that smell like name=value
where neither the name nor the value can contain =
or &
characters. Since this text was copied directly from an URL, it can be assumed to be URL encoded and making sure that no part of the URL misuses #
, ?
, &
and =
characters is the whole point of URL encoding. For this code, we completely ignore the URL encoding. As discussed in part 4 it is useful to leave the token encoded, and we don’t expect any of the other fields that describe the token to actually need to be encoded. That assumption lets us use a for
loop over string.gmatch()
to collect all k,v
pairs and add them to the temporary table t
. When the loop completes, we explicitly pick out the access_token
and expires_in
fields and copy them to the args
table where they can get written to the configuration file.
One thing to notice is that WordPress provides the expiration as the number of seconds the token has to live. We simply add the current value of os.time()
to that and save the result. That is valid assuming that you request the token and then run wppost.lua --tokenurl
without undue delays. Since the only thing we do with the expiration time is display it rounded to a tenth of a day, we won’t be lying to you later unless you waited more than half that time or about 72 minutes from request to --tokenurl
.
Once that is done (don’t forget to include --blog
and --writeconfig
) the access token will be remembered until you replace it, but according to WordPress it will stop working after the expiration date they specified.
As a reminder of the token’s expiration date we can compute its time to live in days and print it:
args.expires = tonumber(args.expires) if args.expires then local ttl = (args.expires - os.time()) / (24. * 3600.) if ttl < 0 then print(("WP Access Token expired %.1f days ago"):format(-ttl)) else print(("WP Access Token expires in %.1f days"):format(ttl)) end end
As expected, the token I just retrieved is marked to expire in 14 days.
Say my name
(The changes described in this section are also checked in at 870da6391b.)
The REST endpoint /me
provides useful information about the owner of the access token. This is similar to the collection of information that is shown in a balloon when you hover over a user name anywhere in the blog in a browser, along with the name and Gravatar shown on blog pages.
The previous script from part 4 simply dumped the raw JSON data blob returned from the /me
endpoint. We can improve on that by parsing the JSON and printing only the most useful information.
The first thing we’ll need is a JSON parser for Lua. Luckily, LuaJSON is included in the Lua for Windows distribution that these posts all have assumed we are using so far. (That link wen’t to its documentation which you might find useful…)
For this case, using it to extract a few facts from the returned JSON is easy:
local json = require "json" local me = wp_showme() local t = json.decode(me) if args.debug then local pretty = require "pl.pretty" io.write("/me = ", pretty.write(t), 'n') end print("Token user:", t.display_name or t.username) if t.email_verified then print(" email:", t.email or "unknown") end
The JSON decoder transformed the provided JSON string into a Lua value. JSON objects become tables with named fields. Arrays become tables with numeric indices starting at 1 as is conventional in Lua. Strings, numbers, and booleans translate naturally to their simple Lua equivalents. It has a lot of options, but we are assuming in this code that the default configuration of the decoder is sensible.
If you want to see the complete block of information returned from /me
and decoded to a Lua table, use the --debug
option which here uses the nifty table display provided by Penlight’s pl.pretty
module.
As a friendly subset of the large amount known about the user, I’ve chosen to print either the display name or user name, and include the email address if the JSON indicates that the email has been verified by WordPress.com.
I’ve left using cURL to retrieve the user’s Gravatar and then displaying it as ASCII art in the terminal as an exercise to the reader. If you do do that, be sure to brag about it!
And soon…
With these changes in place and a valid token cached in the config file we get (why yes, I did redact some irrelevant details):
C:...wprest>wppost.lua -v WP Access Token expires in 13.9 days Token user: rberteig email: rberteig@example.com wppost:Must name a file to post.
Which does look friendly, but continues to remind us that we haven’t actually implemented the ability to create a post from the REST API yet.
We really will be able to post again soon!
Written with StackEdit.