Here's Where The Story Ends
Written by @marcemarc on Sunday, 13 August 2017
“... and then we publish from Umbraco and one final check, the blog post is there, and we are done”
“Great, I’ll stop the watch, how do you celebrate? A nice cup of tea?”
“.. yes, no, well not quite yet, I’ve just got to tweet this out, it’s a pain, I’ve got to logout of my twitter, log into the twitter account for this blog, cut and paste the url, compose the tweet, tweet it, then remember to logout of the company account and back into my twitter, else I’ll be posting pictures of my lunch on the company blog account, which I actually did once by accident”
“A-ha, I’ll keep the stopwatch running then”.
So I’ve found myself writing what has become a series of blog posts, dubbed, in some of the most unfashionable areas of the internet as the ‘working with editors, not against them trilogy’, and they are all following a common theme - the short recap of which is, at Moriyama we’re helping several groups of editors in different companies adapt their editing workflows within their freshly upgraded shiny Umbraco 7 environments, and at the same time becoming slightly fascinated with the human interactions, reactions and thought processes involved.
Today, I’m kind of highlighting a specific nuance of the flick-flack of editor-developer interaction that is sooo subtle, it might not even exist, so bear with me.
In the illustration above, the editor is expressing a specific problem, “the switching of twitter accounts between personal and work accounts”, to send a company tweet about the blog post they created.
Interestingly earlier in the project one of the backlog items had been a vague creation of a ‘complete social media sharing platform™’ which had been sized as a fairly large T-Shirt(XL) and been dropped out of the scope for the set of ‘upgrade’ sprints.
As a developer though, given a real problem, you immediately start to think of how you might solve it, and as you read this you are probably thinking yourself of a number of different really neat solutions... but when handed a ‘specified solution’, for example: in the case of the ‘complete social media sharing platform™’, you’ve got nothing to go on… you haven’t got the ‘Why?’, there is no spark of an idea, the problem solving part of your brain isn’t triggered… and consequently, more importantly, your enthusiasm has evaporated, it already feels like a slog, and that’s just reading about it here and imagining you might have to implement it one day.
If we’re honest, one of the main drivers for a developer is 'to be the person who solved the problem', you take more ownership of the solution, it’s your idea at stake, so you know you might even ‘test it’ before you show it off on the client demo… it's a giddy exciting feeling when you've made a difference.
I’m not a great fan of 'ego driven' development because it tramples over teamwork (and my teamworks is the best! much better than yours) but there does appear to be some truth in the maxim:
present developers with problems to solve, not solutions to implement.
(Notice I’ve pluralised developers) - I think you end up with better solutions, but even if you don’t, everyone appears a lot happier and excited working on the thing, when it feels like it's 'theirs' - albeit I have no empirical data to prove this.
I said it was subtle, and might not actually exist.
Empathy
The other interesting thing here is the dissonance between what ‘is Umbraco’ and what isn’t… the tweeting part of the journey was perceived as a ‘thing not worth mentioning’, because it was outside of Umbraco, but is actually still a really key part of the whole editor journey. I only seem to uncover (or stumble upon) this kind of information, tangentially, when in conversation with an editor, perhaps during a training/orientation session or in a show and tell progress demo call, I think in those situations it's easier to be empathetic - however it's hard to sell the concept to the client that really they should pay for a developer to 'just watch them’, that's apparently 'a bit too creepy'....
Anyway, Sorry I’m doing that thing of going on about stuff I'm not sufficiently professionally trained to wonder upon publically and you just want me to get to the bit about what we did… and link to some sort of code I must have hacked together.
What we did…
Ok, so the crux of the problem here is the company blog twitter account is owned by the blog - not by the individual, so what can we do about that?
With the wonderful SkyBrud.Social for Umbraco 7, all the hard work of authenticating a Twitter account using OAuth is done for you (Facebook,Google and Instagram too). https://our.umbraco.org/projects/website-utilities/skybrudsocial-for-umbraco-7/
It’s ace, Install it now!
With this installed we can then add an ‘Authenticated Twitter Account’ option on the blog homepage: using the Twitter OAuth, DataType that comes with the SkyBrud package.
You’ll also need to create an ‘app’ with Twitter, to tell them that you are about to start programmatically authenticating and doing stuff with the API, it’s easy to do here: https://apps.twitter.com/ and they’ll give you a ‘Consumer Key’ and ‘Consumer Secret’ that you’ll need to cut and paste into the configuration for the SkyBrud Twitter OAuth DataType.
And if we’re logged into Twitter with the account we want to authorize, we just press the ‘authorize button’ and accept the following message:
And if you authorise the app, you now have an Authenticated Twitter Account associated with your blog:
So great, can we tweet every time something is published?
No! - I mean you could but I think you have confused a twitter account with an RSS Feed.. (and there are services that will schedule tweets from an RSS feed) - tweets should be mildly interesting, have some personality and be written for engagement, in my opinion...
… but we DO want to shave some time off that 'logging out logging in cutting and pasting' journey discussed earlier, how best to send a tweet from here that isn’t automated?
How about a Custom Menu Item?
We can make it only appear on the actions menu when a blog post is loaded and the editor can choose when to tweet
To add this custom menu item you have to write some c# code and hook into the Umbraco Event that fires when a Menu is rendered:
Create a class called ‘RegisterEvents’ that inherits from ‘ApplicationEventHandler’ (or maybe your project already has one) we need to override the ApplicationStarting to add the hook to handle the event:
Tip: Type TreeControllerBase.MenuRendering
and then type: + = Tab Tab
It’s an exciting Visual Studio shortcut combination that will stub out the handler for the event and you should have:
public class RegisterEvents : ApplicationEventHandler { protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { //register custom menu item in the media tree TreeControllerBase.MenuRendering += TreeControllerBase_MenuRendering; }
private void TreeControllerBase_MenuRendering(TreeControllerBase sender, MenuRenderingEventArgs e) {
//implementation here } }
This is great trick if you know the name of the event but there isn’t clear documentation of the event signature to hand…
Anyway the code to add the menu item will look something like this, I’ve commented what’s going on.
// we only want to add this option to the content menu if (sender.TreeAlias == "content") { // get details of the content item var umbracoHelper = new UmbracoUmbracoWeb.UmbracoHelper(UmbracoUmbracoWeb.UmbracoContext.Current); var nodeId = e.NodeId; var contentItem = umbracoHelper.TypedContent(nodeId); // if the content item is a blog post if (contentItem != null && contentItem.DocumentTypeAlias == "BlogPostAlias") { // create the menu item called ‘Tweet This’ var tweetThisMenuItem = new UmbracoUmbracoWeb.Models.Trees.MenuItem("tweetThis", "Tweet This"); //assign an icon tweetThisMenuItem.Icon = "bird"; //separate it from other menu items: tweetThisMenuItem.SeperatorBefore = true; // now this is where we wire up the functionality of what to occur when the menu item is pressed - we tell the menu item to open a slidey out panel (actionView) and load the ‘tweetthis.html’ angularJS view into it: tweetThisMenuItem.AdditionalData.Add("actionView", "/app_plugins/tooorangey.TweetThis/tweetthis.html"); // insert it somewhere in the list of existing menu options e.Menu.Items.Insert(5, tweetThisMenuItem); } }
Great we now have a custom menu item, that appears on a blog post, and when you click it, causes a 404 error on the missing tweetthis view!
We need to create the view, and because we’ll be wanting to add some further functionality we also need to create an angularJS controller and a stylesheet, and finally a package.manifest to tell Umbraco to load these assets whenever the view is loaded:
The package manifest just needs to reference the js and the css assets:
{ javascript:[ "/app_plugins/tooorangey.TweetThis/tweetthis.controller.js" ], css:[ "/app_plugins/tooorangey.TweetThis/tweetthis.css" ] }
So now when the editor clicks the 'Tweet This' menu option, our custom view, the TweetThis.html is loaded into the action panel, and the package manifest file (simply because it's in the same folder as the custom view, loads the angularJS controller and css we need for our Tweet This Textbox).
The textbox measures the number of characters and is preloaded with some suggested text, eg the title of the blog post, and a link to the blog post, (and the template for this default text can be tweaked via a property on the blog homepage)
Which produces something like this:
Notice how it's highlighted 'who you are tweeting as'!
The counting of the number of characters left in a Tweet isn't as straightforward as you would think, all links, in tweets are shortened using t.co, so you can’t just count characters, so you have to adjust the total remaining to allow for this, so any urls entered > 23 chars will not use up anymore of your allowed 140. (23 is the maximum length of a shortened t.co link in twitter, there is an api /help/configuration that will tell you whenever this number changes, but of course I’ve hardcoded this for now, as I like ticking time bombs)
Now when the editor clicks Tweet This, their message is tweeted!
How do we send the tweet?
We have a TweetThis action in an api controller (UmbracoAuthorisedApiController) that the text of the tweet is sent to and again SkyBrud does the hard part:
public IHttpActionResult TweetThis(TweetInstruction tweetInstruction) { try { //read authenticated twitter account details var twitterAccount = getTwitterAccount(tweetInstruction.ContentId); if (twitterAccount != null) { //get twitter service using authenticated twitter details TwitterService service = twitterAccount.GetService(); TwitterStatusMessageResponse response = service.Statuses.PostStatusMessage(tweetInstruction.Message); return Ok(); } } catch (Exception ex) { LogHelper.Error(typeof(TweetThisApiController), "Error Tweeting Message", ex); } return BadRequest("Error"); }
And here is a successful tweet...
notice we’ve implemented 'Twitter Cards' on the site, so whenever the blog post is shared it get's a preview with associated article image.
But it's not my Twitter account - what ‘has’ been tweeted out recently?
Because this isn’t the editors usual twitter account, and on some blogs it’s shared with other editors we’ve kind of defeated the object of this improvement if the editor still has to remember the twitter account, switch to twitter, read the recent tweets, make sure they are not duplicating previous tweet content or style, then switch back to Umbraco to make the tweet. So now that we’ve got Skybrud setup and the Blog Twitter Account authenticated, it’s possible to list the recent tweets out via a custom property editor on each blog’s homepage perhaps on the ‘Social Tab’ in the backoffice:
So what’s the effect on the journey stopwatch?
It's hard to compare fairly the two complete journeys, since a certain amount of time is spent thinking about and composing the tweet, but if we consider 'time until point of composure', It takes a few minutes to switch twitter accounts, so the obvious gain, here is being able to click Tweet This and in 12 seconds you are at the point of composure. Having the 'default text' in place saves further time, but hard to assess, whether this affects the quality of the tweet message, eg does the editor have more time to think about the actual message, or is the default 'good enough' - I'm going to pretend it potentially does both, and focus on the fact that 'time to the celebratory cup of tea' is drastically reduced.
So small little tailored changes like this, might seem unimportant or be brandished as 'gold plating' but any task that involves faff, even if the duration of the task isn't very long, wears us down, and it's particularly draining when you have to switch context or systems, whilst keeping the original task held in your mind, so tiny improvements of this nature can have a big impact on editor happiness and their outlook on an upgraded implementation.
"Umbraco 7 is great, you can tweet from the blog editor page"
Anyway you can have a closer look at the moving parts in this gist of a git repository, if you are interested in the implementation details.