God punishes people like you

Do what you’ve always done, get what you’ve always gotten.

That maxim has been part of my thinking for as long as I can remember. So has the simple, one-word slogan “Evolve” – applied to as many aspects of my life as I could manage.

It’s a mode of thought that’s brought me quite far. Every so often, I re-evaluate everything I’m doing, to see if there’s anything I could be doing differently. It made me a very engaged employee (for as long as there were new opportunities), it pushed me over the edge into quitting my first (and longest!) job, and it keeps nudging me into trying different things.

When I quit my job, one of my medium-term plans was to get myself set up for mobility. Partially because I fear South Africa has already sunk past the point of no return, partially because I like the idea of travelling around the world slowly, working and experiencing different ways of life.

I know – both from experience and from empirical research – that it’s precisely that sort of perspective-broadening experience-deepening travel that has a major, positive impact on your sense of self. And ultimately that’s where I’d like to end up, having graduated from an office desk/home desk/bed lifestyle, to one where I’m not afraid to dive into new experiences.

And so, through a set of happy coincidences, I landed a few customers that are based in the Cape Town CBD. Every few weeks I plan on spending a few days over there. In-person meetings really are the best kind (as much a fan as I am of telecommuting), and every trip gives me the chance to spread my wings a little more, acclimatizing to a lifestyle that may define the next few years of my life.

The most recent trip was my longest by far – 1.5 weeks, 3 different Airbnbs, and an overwhelming sense of gratitude that these sharing economy systems exist. I can’t imagine finding trustworthy, low-cost accommodation in a foreign city 10 years ago. Today it’s just another app.

This most recent trip is memorable for another reason, captured in the title. While standing outside the entrance for my final Airbnb room, waiting to hear back about how to actually get into the place, a local beggar came up to me.

I generally don’t like beggars. I’m a generous person by default, and happily share what I can with people that genuinely mean well.

It’s the entitled beggars I can’t stand, and Cape Town has among the most shameless beggars around – exemplified by the beggar that came up to me that afternoon.

My usual response over the years has been a half-hearted fakeout – usually something about not having cash on me (near-universally true). This time around though, looking at the situation for what must have been the hundredth time, I had one of those “eh, fuck it” moments.

So when I told him no, and he asked me why, I looked him dead in the eyes and told him it was because I didn’t want to.

If you ever want to see someone go from fake-pleading to outraged in less than a second, step directly on their sense of entitlement with your own intransigence. It works wonders.

He actually looked taken aback for a moment, then got angry, waved a finger in my face and went “You know what, God punishes people like you.” and walked off.

I thought about that one for a while, and concluded that since I’ve dealt with a decent amount of punishment already, there’s not that much worse I can go through – and besides, if He does show up to punish me, there are a bunch of questions I’d love to ask. 

And then I checked into a very stuffy 1-bedroom apartment for two days.

The real winner was the following night, when a young woman and child pulled up next to me at a kiosk and started begging. There, I’ve found the most effective response is “Are you really teaching this child to beg?”, at which point they usually realize the manipulation isn’t going to work, cut their losses, and run.

Those two incidents were, in their own way, perfectly timed. That night I spoke to the manager of a local restaurant, who bemoaned the fact that the drunk, loud vagrants around Cape Town routinely scare away tourists, hurting his business.

I heard the same from an old friend of mine, when I relayed to him the anxiety I felt sitting in Greenmarket Square. I didn’t recognize the city around me, and I had lived in it for years. Somewhere, somehow, some important things have broken and are not being repaired.

In my case, these things just motivate me to keep pushing for the next milestone. By this time next year, I hope to be travelling, and continuing to set myself up for a new life somewhere else.

Ideally somewhere God doesn’t punish people like me.

Change is coming

It’s nearly six months to the day since I announced my departure from full-time employment, and while I didn’t quite plan for this, it’s a serendipitous turn of events all the same.

I should lead with the headline: Yes, I just unfollowed everyone on Twitter. If my following you was important, I’m sorry for the disappointment but I need to do this for my mental well-being. My mentions and DMs are open and I’d be happy to chat.

Now on to the main event:

When I resigned in April, what I was really beginning was a journey of self discovery. Over the last few months there have been many, many changes for me – most of them good! In my April post I mentioned that:

In future, I might write more openly about the life I came from, the demons I’ve wrestled with over the years, and the moments of breakthrough that have set me free.

And here we are right now, in the future, and I’m holding up my end of the bargain with past-Wogan. This is going to mean a few changes for me.

The way I blog is changing. For about ten years, there was a lot of stuff I was frankly terrified to say. Some poor decisions early in my career (and a tenuous situation at work) meant I self-censored a lot of the things I would otherwise have posted. What little I did write here was filtered, sanitised, and effectively produced with a formal tone and at arms length. Most of my posts could be copied straight into a corporate email and nobody would raise an eyebrow.

I’m not upset about any of that – if anything, I’m grateful. There’s a lot of dumb shit I absolutely could have said, that would have gotten me in far more trouble. With observation came experience, and this time around I’m a lot more sure of where things stand.

Most of the trouble comes from my interest in politics. Actually it’s my interest in most things related to the construction and maintenance of civilised life – from languages, to infrastructure, to the cultural climate within which we relate to eachother. Figuring all these things out (and trying to explain them) is my absolute favourite past-time.

Since resigning, I’ve taken to Twitter a lot more than usual. I found it to be a very stimulating platform, with a massive feed of new information coming in every single day. And I’ve responded to that, tweeting and engaging on a near-24/7 basis.

Jun 2018: Your Tweets earned 47.5K impressions over this 30 day period
Oct 2018: Your Tweets earned 487.4K impressions over this 27 day period

I love doing this – the debates, the arguments (constrained as they are by the 280-character limit, threading, and like-baiting), and meeting like-minded people this way. Unfortunately I can’t keep doing it at the same pace, though – I have new responsibilities.

In April I quit my job to pursue a new set of opportunities. Over the last 6 months, it’s panned out better than I had expected. I’ve been able to accumulate something of a runway, enabling me to do what I really want to do: Carve out large blocks of time to do in-depth SaaS builds on products I think I can sell.

That requires relentless focus, though. While it was easy to spend hours a day on Twitter in the beginning, it’s becoming a distraction now that I’m fully engaged in work. I don’t want to lose any of the momentum I’ve built, so I’m trying something new.

I enjoy thinking about complex things, then discussing my ideas with people who have interesting things of their own to say. It’s hard to do that on Twitter though, thanks to the sheer firehose of data:

After spending an ~hour with @WotanZA having an actual conversation (diverse as it was), and the next hour sitting on a quiet balcony and just processing everything, I felt like I was in a much better mental state. Then I checked Twitter and it all went to shit.

I currently follow many great accounts, and I get a massive amount of new info every day from all sorts of places: left- and right-wing news media, cryptocurrencies, financial services, gaming, mergers, tech industry news, psychological studies, the list goes on.

It’s an addiction I can’t really afford to feed anymore, though. I’ve consciously observed how I use Twitter over the last month, and I’ve noted several things:

  • Opening the app to check for new content has become routine, and I’ve often found myself in the aimless-fridge loop: Opening the same door over and over again even though there’s nothing new.
  • I typically scan the entire timeline every morning, consuming every single tweet
  • I post knee-jerk reactions to a lot of stuff, and more detailed threads when I’ve had the time to think about it
  • I get into arguments quite a lot, which is hard to fit into the platform’s limitations and doesn’t give me a good place to fully express my argument. Most importantly:
  • Every time I open Twitter, even just for a 10-second check, disrupts minutes worth of productivity.

In effect, I lose hours of daylight productivity (which is when my feed is the most active), and have to make up for it in the evenings. It’s led to a disrupted sleep schedule and failures to make and stick to my plans. I’m also pretty sure it’s contributing to weight gain and hypertension, but the disruptions to the first two mean I have no disciplined regime for monitoring the rest.

So for my own health, discipline and mental well-being, I’m trying something new. I’m going to unfollow every single account on Twitter.

This means that the only things I get from the app are things that people send to me directly and deliberately: @-mentions, tweet replies and DMs, which I will happily respond to. As a messenger app, Twitter would be as manageable as WhatsApp, which takes up very little of my time every day.

I’ll still use Twitter to share stuff, but they’ll either be long-form threads or links to posts like this one. I decided months ago that I need to get into the habit of producing more long-form content anyway (part of another long-term goal), and this is a good way to do it.

This does mean that I’ll be quitting a very strong addiction cold-turkey. FOMO is real, and I think I may have developed a dependency on the constant stimulation, so it’s probably not going to go well at first.

After the jitters though, I hope I can direct my writing energies into something more productive: Longer, more detailed posts made on this blog, shared for discussion on Twitter. I think this is the environment that will let me do my best work, while providing quality content to the people that follow me (which is something I take very seriously).

It should also result in more consistent, “on-brand” stuff. Using Twitter like a personal account means I end up shitposting a lot, and long-term that’s not really adding much value for me. Other than being entertaining, of course.

This blog will get a lot less formal, a lot more conversational, and will probably focus on politics and the culture wars as much as technology. I doubt I’ll ever write detailed technical articles here again, but I’ll leave the full history intact – they’re my best-performing posts right now.

I generally leave comments open on my posts, but if you want to get in touch directly and have a private conversation, my details are on the Contact page. Let’s do this!

Consume Laravel APIs from VueJS with Passport

Laravel 5.6 suggests a simple structure for creating API-driven applications. Your API routes are declared in their own routes/api.php file, and can leverage the auth:api Middleware for security. By default, the system uses the built-in API TokenGuard for that, which requires you to come up with your own system for issuing tokens against users. Passport offers a simpler way that doesn’t require you to use the entire system.

Five steps!

To implement this into an existing Laravel project, there’s only a few edits you need to make: 1. Install Passport
$ composer require laravel/passport
Out of the box, Passport sets you up for a full-on OAuth system, which we don’t really need. So to prevent it creating unnecessary tables, add the following to register() in app/Providers/AppServiceProvider:
\Laravel\Passport\Passport::ignoreMigrations();
2. Include the CreateFreshApiToken Middleware Add this Middleware to your web stack, in app/Http/Kernel:
'web' => [
    ...
    \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
]
This will attach a JWT token called laravel_token as a cookie on all future web requests. 3. Include the HasApiToken trait on your User model
class User extends Authenticatable
{
    use Notifiable, \Laravel\Passport\HasApiTokens;
}
This trait looks for the laravel_token field and automatically logs you in if it’s detected – as long as you’re using the passport driver. 4. Use the passport driver for api auth Edit your config/auth.php to set the api driver up:
'guards' => [
  'api' => [
    'driver' => 'passport'
  ]
]
5. Generate the keys Last step, generate the public/private keys for Passport:
$ php artisan passport:keys
Passport will use these within the passport driver to generate and decode the laravel_token JWT payloads, then use that to authenticate the User model with the HasApiToken attached. From this point on, you should be able to use VueJS with your secure APIs out the box.

Sample Project

With the laravel_token cookie being set, and axios headers configured with the defaults (inside bootstrap.js):
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
Any requests you make to a route secured by auth:api will log you in automatically. route/api.php
Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});
resources/views/home.blade.php
resources/js/app.js
const app = new Vue({
    el: '#app',
    data: {
        user: null
    },
    mounted() {
        axios.get('/api/user').then((response) => {
            this.user = response.data;
        });
    }
});
With that all compiled and run, it’ll fetch the logged-in user object and render it out:
Cropped from the default app

It’s just about GDPR time!

(Image credit: Flickr)

I still remember back when the Internet was an escape from the real world. Today, it seems that the real world is an escape from the Internet. Over the last 30 years, a substantial amount of daily life has moved online for billions of people: News, communication, sharing, commerce, banking, and entertainment.

Wherever human activity goes, regulation inevitably follows. This year it seems like the internet is truly going mainstream, with new regulations from 2 of the 3 largest economies in the world: the US’ FOSTA, and Europe’s GDPR.

I’m actually quite a fan of GDPR – or at least, what it’s trying to do. In GDPR, there’s an attempt to extend protection of EU citizens rights across the Internet, following their personal data wherever it may end up. And the regulations make a lot of sense from a consumer perspective: If companies want your personal data, they have to prove they can handle it responsibly, and you retain basically all the rights.

GDPR goes “live” on the 25th of May (just under 3 weeks!), and I’m hoping it heralds a new era of more responsible data practices. I think everything they’re trying to do is achievable, and should be baked into organizational and system design for new businesses (“privacy-first architecture”).

For existing businesses though, it’s going to be hell of a slog. I’ve worked on data audits and compliance for some of the world’s biggest brands, and it’s impossible to overstate how tricky full compliance is going to be. When your database software vendors have gone defunct, when your processes have spiraled out into spreadsheet nightmares, when your primary method of data exchange is email attachments, you’ve got a problem.

Over the last few days I’ve put some stuff live to help with that. For one, there’s already a wave of companies that are blocking the EU from accessing their services outright. It’s a sensible short-term move if you need time to assess the impact, and update your processes to comply. The rights of Erasure and Portability could require non-trivial work if you’ve been historically lax with how you manage data internally.

For that use-case, I pulled together a repo (gdpr-blackhole) of the IP ranges (IPv4 and IPv6) of all 28 EU member states, UK included. Brexit or not, early indications are that the UK will adopt GDPR in its entirety.

Then, since I work mainly in Laravel, I wrapped that up in a simple Middleware class that makes blocking EU IPs straightforward (laravel-gdpr-blocker).

Finally, I’ve just put a short blog post live on Amberstone: “What small businesses need to know about GDPR“. Large businesses already have armies of lawyers, auditors, and officers to assess their liability. Small businesses are not exempt, and if you want to participate in the second-largest economy on the planet, you’re going to need to know a bit about what GDPR asks of you.

Overall, it’s an exciting change. The ICO has already indicated that they’d sooner work with non-compliant organizations to improve their stewardship of personal data, making the eye-watering fines a last resort. And if all goes well, this is exactly the sort of bar-raising work we’ve needed on the world stage.

And with any luck, it means less Excel spreadsheets loaded with personal data. Time will tell 🙂

Oh boy, where to begin.

On the 5th of May, 2008, I started my first day at work.

I doubt I’ll ever forget it: To beat the traffic, I carpooled with an intern from a nearby law firm, arriving in Cape Town at around 6am. I had to wander around the darkness of Kloof Street for a while, trying to keep busy (and warm) until someone showed up to let me in.

It was a surreal morning for me. The preceding family drama is complicated, but the summary of it was that I had absolutely no idea what I was going to do with my life at that point. I ended up on a bus from Pretoria to Cape Town the week before Christmas 2007, and lived with my father for a few (very strained) months before I got any semblance of an act together.

I was nervous as hell. At the time, I didn’t actually think I’d land the job. Luckily I had some experience building websites, and between a meager portfolio and an old friend’s insistence on listing at CareerJunction, a recruiter found me.

I failed my first interview. It still amuses me to know that the person who decided not to hire me back then still works at the company, and we’d ended up working together on a few things over the years. Sometimes I wonder if she regrets not having hired me, but I suspect I wouldn’t have lasted in her team anyway.

Luckily, I passed the second interview – between the recruiter and the HR director, they thought I might have some potential. In the end, I landed in the Paid Search team.

While my dress code (on the whole) has been very informal over the last 10 years, I dressed for the occasion on my first day. And it was while wandering around Kloof Street that the outsole on my right shoe became partially unstuck, making an embarrassing noise every time I walked.

Nervous, overdressed, surrounded by people I didn’t know in a city I’d never lived in, praying that my shoe didn’t completely come apart before I could get home. That was my introduction to the company that would carry me through the next ten years.

I get a weird look when I tell people my first job’s lasted this long. It doesn’t feel that way with all the roles I’ve held since 2008. I’ve done pretty much everything there is to do in digital marketing – search, email, display, analytics, consulting, architecture, compliance, project management, team leadership, training, and staying on top of the never-ending waves of technological and social progress.

Right now it feels more like I’m graduating from one of the most arduous post-secondary education experiences imaginable. I’ve had hundreds of hours of theory and thousands of hours of practice. If Gladwell’s Outliers is to be believed, I’ve sunk the requisite 10’000 hours required to achieve mastery in digital marketing. And then some.

And I’ve traveled. My god, have I traveled.

DbYkZptVQAIgrkH.jpg
Every airport I’ve flushed a toilet in.

I’ve been as far east as Phoenix, Arizona (connecting flight on a return trip from Salt Lake City), and as far west as Melbourne (my first on-site development/consulting gig). It’s been a privilege to see so many different parts of the world, and the exhaustion of business travel has thoroughly disabused my notions of the glamorous lifestyle I once thought it was.

The world has changed. 2008 was a different time: Facebook was only 4 years old, Twitter was a toy that gained some media traction during Barack Obama’s campaign. The iPhone 1 had been released just last year.

opera_2018-04-27_22-11-26.png
The top story that week – food riots in Somalia. Today, there’s food riots in South Africa.

And I’ve changed. In future, I might write more openly about the life I came from, the demons I’ve wrestled with over the years, and the moments of breakthrough that have set me free. For now, it’s enough to acknowledge that 2018 Wogan is a far cry from 2008 Wogan, and I’m grateful for every bit of progress in between.

Today’s my last day. It’s a mixed feeling – strange, to think that I’m moving on after so many years; a relief, knowing I’ve reached the end of this road; anticipation of what the future might bring, and the confidence that comes with real-world experience.

At last, it’s time to move on. I don’t know for sure what the next ten years are going to look like, but I’m eager to find out!

Subscription payments in South Africa

So you’re a South African business that wants to take payments for a subscription-based service. You’re probably going to have a mix of local and international customers, and want to know what services are available.

Well, I’ve got some good news, and some bad news.

The good news is – there are ways of doing this. Even with South Africa’s relative backwardness in global economic participation there are still a few options.

The bad news is: the best options are currently unavailable to you, and are likely to stay unavailable in the long term. If you have the means to do so, incorporating and setting up banking in a major economy might be the better option.

Onwards!

Local Options – EFT

It goes without saying that local EFT is an option. If you don’t want to wait for interbank delays, there are a few vendors that offer Instant EFT solutions:

In my experience, PayFast has the easier onboarding path, but you might have a tougher time integrating it into your application. None of those solutions incorporate any sort of subscription management though – it’s on you to keep the accounts in check.

Depending on your capabilities, debit orders might be an option. If you can obtain debit order mandates from your customers (signed papers, recorded calls, etc), you can use Sage Pay’s NAEDO collection system: https://sagepay.co.za/services/debit-order-collection/

Local Options – Credit Cards

This is where it gets a bit more interesting!

PayFast allows you to accept credit cards online, and is relatively easy to set up if you’re not looking for advanced integration. They will make your life easier on one front – they understand subscription management: https://www.payfast.co.za/subscriptions/

I’ve worked with their API before though, and you’re going to need to exercise extreme patience with it in order to get anything done. I hope their systems and documentation improve over time!

PayGate also offers a subscription product, but they make it obvious that they’re geared towards larger businesses – you have to start the process with a sales inquiry: https://www.paygate.co.za/paygate-products/paysubs/

Global Options

There are too many global vendors to list, but when it comes to what you can feasibly use in South Africa, it narrows down to one pretty quickly: PayPal.

I implemented full-on subscription management using PayPal for Write500 – and it worked quite well. PayPal can accept credit cards, manage subscriptions (including pausing and resuming), and has a solid set of developer tools for integrating it into your application.

You’ll want to create a Billing Plan (your product), then a Billing Agreement (a paid subscription to it), so that Paypal can issue Invoices and settle them automatically. Start here: https://developer.paypal.com/docs/api

The one limitation: You need an FNB account to receive any of that money here in SA.

Going further abroad, you do have the option of incorporating a business remotely. It’s a ton of paperwork (depending on a ton of factors), but one vendor is offering a simple solution to it: Stripe Atlas.

For a one-time fee of $500, and a decent amount of effort, you can incorporate remotely in Delaware – including all the documentation and registration you need to run a corporation within the US. That includes a Stripe.com account, which is basically the global, golden standard for subscription credit card billing.

There’s a couple of major downsides on the administrative side, though – repatriating that money comes with its own set of tax challenges. From what I’ve seen, this is only a really viable option if you’re expecting to do a lot of subscription billing for global customers, and the Stripe fees are a more attractive option.

Other Options

I would be remiss if I didn’t mention PeachPayments – a Cape Town-based company that attempts to make all of the above easier for local companies. If you’re not keen on the idea of getting your hands dirty with integration logic and setting up subscription billing, those will be the folks to talk to.

Then of course, there’s bitcoin. If you really feel like jumping into the murky waters of cryptocurrency for your project, give Coinbase a try. They offer a recurring billing option denominated in Bitcoin. To cash those coins out locally, the simplest option will probably be to hold a Luno.com wallet, and sell those coins on the local exchange to recover your Rands.

I know that there are likely several other services out there, but if I were starting from scratch today, and wanted to be able to accept payments from a global customer base I’d probably still go with PayPal, myself.

It’s time to talk about charts

Have you ever felt annoyed that someone tried using a world map chart to visualize country-level data?

Or is that just me?

(It’s probably just me.)

Over the last few weeks I’ve been picking up more books to read (as part of my drive to write more), one of them being Content Inc – recommended to me as a good introduction to content marketing, and how powerful it can be.

The book vacillates between content production at the individual level, and the corporate level. Some of the stories focus on single-person startups, and how they tested ideas and built businesses off the back of content production. The rest of it, haphazardly, deals with how to maintain that within a larger organization (team structures, responsibilities, and so on).

What struck me about the individual stories though was the relative simplicity of the focus. One person wrote about writing – another, about real estate. A third simply wrote about how to get more value out of your camera. All of those, over time, became profitable businesses – the key ingredients being effort, and no small amount of passion for the target subject.

It got me thinking about an idea I had years ago, when first starting to work with Domo. Without going into too much detail, one of the things that intuitively clicked for me during the first few weeks was the brightline relationship between business management, and data visualization.

Borderline-buzzword sentence, I know.

The practice seemed to hit at the intersection of a few of my interest areas – complex systems, data and numbers, and visual communication – and it wasn’t very long before I was already planning out an enormous series of content on how to get the best value out of different data visualization options.

That content never materialized. I had put it on my internal roadmap; to develop “added value” in the form of training content that our consultants could use to help plan best-practice dashboards.

In the end, Domo themselves reached a new level of maturity on their operating models, and that filtered through to the training we got. For that (and quite a few other reasons) that content was never built.

Reading Content Inc made me dust that idea off again. I know for a fact that I can produce useful, actionable content on this topic, having done it before. I’ve also learned, somewhat accidentally, that this is a passion of mine.

In retrospect it might be obvious, but the revelation really came to me on a recent customer project. We were planning out a series of dashboards, and someone wanted to include a world map chart where there didn’t need to be one. That led to a long (and I want to use the word “vibrant”) discussion on whether or not we should include it.

Afterwards, reflecting on that conversation, I realized how deeply I had internalized the principles I had been learning since 2013 – and how naturally they seemed to fit in with the rest of my thinking.

So between that, and my desire to write and publish content more frequently, I’ve decided to take a stab at maintaining a data visualization blog, with a specific focus on practicality: There are amazing interactive visualizations out there (Jer Thorp in particular will always be in my pantheon of data deities), but most of the visualizations we use in daily life are much more basic.

Software has, I think, tricked too many people into thinking charts are easy. I’ve seen so many presentations, Excel workbooks, and “professional”-level reporting that ends up being hard to get any sort of good understanding from.

Simple rule: If your chart is accompanied by a “how to read this chart” helper, you haven’t built a good chart.

And I think this might be the thing that I tackle next: A bit of theory, but mostly practical advice on how to construct good charts. And there are a lot of scenarios to consider – more than enough to build a solid resource for the “everyman” visualization work.

So I’ll be building out plans and content for this over the next few weeks, and hope to launch a new site before the year is out. If there’s one thing I’ve learned so far, is that good data visualization is timeless.

1786_Playfair_-_Exports_and_Imports_of_Scotland_to_and_from_different_parts_for_one_Year_from_Christmas_1780_to_Christmas_1781.jpg
In particular, we’ve had stacked bar charts since as far back as 1780.

Once it goes live, I’ll be posting about the site here. If you want to be alerted when that happens, consider subscribing to my blog – widget’s on the top right.