Content promotion on social media

I didn’t come up with the ideas here, these are my notes from a talk on lessons learned in how to do social media by Google’s social media team.

Social media is a way for you to deliver your content to your audience. It’s a way for you to find your audience and for your audience to find you. It allows you to have a conversation with your audience. It allows you to learn about what your audience likes, and what they want more of. This can help you to produce better content that they will like more. It’s also a way to build a community with your audience around your content, and shared interests.

General lessons

Questions to ask for each post:

  • Is this engaging?
  • Is there a call to action?
  • Will this foster and facilitate conversations?

Just like everywhere else, it’s a good idea to try out different things to see what works and what doesn’t, and iterate on the stuff that does work.

Other general learnings

  • Posting scheduling and consistency
  • Comment/reply management
  • Re-sharing/influencer engagement

Think about the split between native on the platform and off behind a link. Images, GIFs, and videos may work much better natively.

G+

Targeted & Technical

  • Long-form content including small code snippets
  • Video embed
  • Photos, GIFs, albums

Think about how your links will populate on G+.

  • Does the image get pulled through?
  • If it looks good, then use it
  • If it doesn’t, maybe use a photo, and add link in the post

Twitter

Quick & engaging

  • GIFs to drive brand awareness or accompanied by a link to more Content
  • Photos or memes
  • Live blogging
  • YouTube links no longer populate a video
  • Use a GIF of the video
  • Make sure to have room in the tweet for an image and link

Using Twitter to promote long-form content elsewhere is a great way to engage people on both platforms.

Facebook

Potential growth… with investment

  • Native video upload
  • Incremental reach

Pay-to-play, need to spend money to get views. Native uploads are more engaging on Facebook.

Organic growth on Facebook

Video & call to action (ask to like the page) will help to grow organically.

Blogs

Good for in-depth content, maybe less personal, whereas the social platforms may be better for a more personal, conversational. Depending on what you are doing. If this is a personal blog, then it should be personal. If it is a corporate blog, then maybe it’s more of the official corporate channel, and the voice should be more of a corporate voice.

Medium

  • Forum for a more opinionated, personalized voice
  • Emerging space for written long-form content

More personal, and conversational, while still allowing for long-form in-depth content.

“If you are persistent, you will get it. If you are consistent, you will keep it.”

Engagement

It is worth engaging with your audience as much as possible in the comments. Obviously, ignore the trolls, and the comments that don’t add value. If you can’t say anything that would add value to the current conversation, then don’t, leave it there. Engage with the comments that provide good feedback, positive or negative, and contribute to the conversation.

It’s also worth re-sharing other people’s content that you think is good. Just don’t go overboard with the re-shares.

Tracking and measuring

Doing social media is throwing spaghetti at the wall. Tracking and measuring is the only way that you know when something’s working, especially when you’re trying a bunch of random things.

  • Outline objectives up front
  • Identify potential data points to prove impact
  • Think of ways to make the data meaningful (e.g. Q/Q growth)

Know your audience. Pay attention to what they’re engaging with and do more of it. If you’re really unsure, ask. This is where tracking can come in handy to help growth. Social media is not just about reach. It’s about thoughtfully engaging.

Funnel

  • Reach - how many people saw our content?
    • followers
    • impressions
    • page views
    • modeled reach
  • Engagement - how many people interacted with the content?
    • types of engagements
    • engagement rates
  • Sentiment - did the content have positive brand impact? May not really be part of the funnel, since it’s so hard to measure.
    • positive
    • negative
    • neutral
  • Conversions - SDK downloads docs visits
    • GA - referrers

Managing Finances (Android Intents Part 5)

This is the fifth post in a series about sharing information between apps. (Series Table of Contents.) In this post, we’re going to create another demo of an Intents based API.

Series Table of Contents

Follow the series on the Table of Contents page.

Finance Management App

Let’s imagine a scenario, Mohammed has built an investing app. It allows users to buy stocks and build up a portfolio. His app is only available on smartphones. There’s no web version of the app, and no public-facing APIs available from our servers.

Now, let’s imagine that his friend Susan is building an Android app to help people manage their finances. She wants to give her users the most complete picture that she can. She already has bank and credit card integrations done, and now she’s looking to build a view of users’ investments. She knows that a lot of her customers are also customers of ours. She asks Mohammed if he can open up an API for her.

All she really needs is a current dollar value of the investments, along with the amount of cash invested. Mohammed decides that he can open up an intent API for her in our app.

For demo purposes, I’m not actually going to build out a stock app, I’m just going to build something that handles the Intent request, and returns a response.

Mohammed wants to have some amount of security, so he comes up with a scheme for calculating a client id and using a shared signature, to try to prevent random, unauthenticated apps from requesting data. Here is what the request looks like:

private void requestStockInfo() {
    Intent intent = new Intent(STOCKY_RECEIVER_ACTION);
    // calculate client_id, based on known algorithm
    intent.putExtra(CLIENT_ID, Hasher.hashIt("stocky_app" + getPackageName()));
    intent.putExtra(CLIENT_SECRET, CLIENT_SECRET);
    startActivityForResult(intent, REQUEST_CODE);
}

Disclaimer: Please do not actually do this with a financial app unless you consult with a security expert first. I would assume that this could be made to be safe, but I am not a security expert. The point is that there are ways of adding layers of security.

finance demo 1

Activity before request to Stocky

Within Stocky, Mohammed’s stock buying app, the intent is handled, checked and result returned:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    String caller = Hasher.hashIt("stocky_app" + getCallingPackage());
    Intent sIntent = new Intent();

    if (Constants.STOCKY_RECEIVER_ACTION.equals(intent.getAction())
            && intent.hasExtra(Constants.CLIENT_ID)
            && intent.hasExtra(Constants.CLIENT_SECRET)) {

        Bundle extras = intent.getExtras();
        String clientId = extras.getString(Constants.CLIENT_ID);

        if (!caller.equals(clientId)) {
            setResult(RESULT_CANCELED, sIntent);
            finish();
            return;
        }

        // hardcoded information, I'm not building a full app here
        sIntent.putExtra(Constants.VALUE, 9830.00);
        sIntent.putExtra(Constants.INVESTED, 10000.00);
        setResult(RESULT_OK, sIntent);
    } else {
        setResult(RESULT_CANCELED, sIntent);
    }

    finish();
}

Then, back in Susan’s finance app, she handles the result:

@Override
public void onActivityResult( int requestCode, int resultCode, Intent data ) {
    if (RESULT_OK != resultCode)
        return;

    Bundle extras = data.getExtras();

    double value = 0L;
    double invested = 0L;
    if (extras.containsKey("VALUE"))
        value = extras.getDouble("VALUE");
    if (extras.containsKey("INVESTED"))
        invested = extras.getDouble("INVESTED");
    double gains = value - invested;
    // do something with the data
    stockInfo(value, invested, gains);
}
finance demo 2

Activity after result from Stocky

That’s it! There is a fully working demo in our repository. ( git checkout -b step8 step8 )

Conclusion

Today, we looked at another example of using public APIs on the phone. We thought through a new example of something that might be useful to do, and built a demo of that.

I have some ideas for the next few posts, but I don’t want to spoil the surprise (which is to say, I have no idea how I’m going to write up the next few posts).

Keep an eye on the Table of Contents for the latest entries in the series.

Editing Images (Android Intents Part 4)

This is the fourth post in a series about sharing information between apps. (Series Table of Contents.) In this post, we’re going to look at an example of an app that provides a public API. Our Aviary example offers a solid example of why this sort of thing might be beneficial, so let’s get right into it!

Series Table of Contents

Follow the series on the Table of Contents page.

Aviary

Aviary (acquired by Adobe not too long ago) is a photo editing app on Android that provides an SDK to allow developers to use Aviary’s image editing tools within their app. The SDK works on Intents being fired at some Aviary provided Activities that you’re supposed to include in your app. This means that you’ve got to bundle Aviary’s SDK into your app, and add UI components which may complicate things for you (especially when you want to change compatibility libraries).

Luckily, Aviary also provides an external Intents API that works as long as you’ve got the Aviary app installed. The external API is really nice because you don’t even need credentials to send images to Aviary to be edited.

While the external API is fairly simple. The example app is going to be sending an Intent and expecting a response. This is a bit different from what we’ve seen before.

Aviary’s documentation actually gives a lot of information about how to do this, so I’ll just give highlights, and a link to the demo repository at this stage.

Our example uses a file that I’ve included in our resources:

String destFileName = "startup_unicorn.jpg";
File file = resToFile(R.drawable.startup_unicorn, destFileName);
log.d("image file: %s", file.getPath());
Uri uri = Uri.fromFile(file);

Once we have our file available in external storage, we can fire off our Intent:

Intent newIntent = new Intent( "aviary.intent.action.EDIT" );
newIntent.setDataAndType(uri, "image/*");
newIntent.putExtra("app-id", getPackageName());
startActivityForResult( newIntent, 1 );

That should send us off to Aviary, and wen we come back, we will need to handle the response:

@Override
public void onActivityResult( int requestCode, int resultCode, Intent data ) {
    if( resultCode != RESULT_CANCELED && requestCode == 1) {
        Bundle extras = data.getExtras();
        Uri imageUri = data.getData();
        File outFile = new File(getExternalFilesDir(null), "startup_unicorn_edited.jpg");
        if (null != extras) {
            if (extras.getBoolean("bitmap-changed"))
                saveFile(imageUri, outFile);
        }
    }
}

Now, we can see our file if we navigate to our demo app’s cache directory, shown in the image below:

aviary edited image

To see a fully working demo of this, check out step 7 in the demo repository. ( git checkout -b step7 step7 )

Conclusion

Today, we looked an example of using public APIs on the phone. We reviewed a real-world, working example with Aviary. Keep an eye on the Table of Contents for the latest entries in the series.

Make your phone talk (Android Intents Part 3)

This is the third post in a series about sharing information between apps. (Part 1 is here, and part 2 is here.) In this post, we’re going to create a public API that allows other apps to use our app to speak something out loud.

Series Table of Contents

Follow the series on the Table of Contents page.

Text to Speech Example

Back to looking at code! Yay!

We want to provide to other apps the ability to fire an intent at us, with some text, that will cause us to speak out the text passed in.

This example uses the text-to-speech API provided by Android. Since we’re discussing intents, and public app APIs, I’m actually going to skip the implementation of this. It doesn’t have much to do with the rest of the discussion, and actually, the ability to skip these sorts of implementation details is exactly what we’re after. That said, all of the code is on GitHub, if you’re interested. There isn’t a whole lot needed to do this.

Here’s what we will look at, providing a public API, and consuming that API.

Provider

On the provider side, it’s very similar to what we have in our BroadcastReceiver example from Part 1. We’ll start with the snip from the AndroidManifest.xml:

<receiver android:name=".say.TtsReceiver" >
    <intent-filter>
        <action android:name="io.ejf.intentexamples.say" >
        </action>
    </intent-filter>
</receiver>

This is our BroadcastReceiver.onReceive implementation:

@Override
public void onReceive(Context context, Intent intent) {
    Intent sIntent = new Intent(context, TtsService.class);

    if (!intent.hasExtra("SAY_TEXT"))
        return;

    sIntent.putExtra("SAY_TEXT", intent.getStringExtra("SAY_TEXT"));
    context.startService(sIntent);
}

Notice that we’re starting a service, as opposed to trying to run the text-to-speech code in the BroadcastReceiver. The reason for that is that there are some asynchronous components of Android’s text-to-speech implementation, and the BroadcastReceiver will die as soon as onReceive is finished executing.

In our Service, we have something like the following:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (!intent.hasExtra("SAY_TEXT"))
        return;
    if (null == textToSpeech)
        return;

    String sayText = intent.getStringExtra("SAY_TEXT");
    textToSpeech.speak(sayText, TextToSpeech.QUEUE_ADD, null, null);

    return super.onStartCommand(intent, flags, startId);
}

The above is a slightly modified version of what’s in the project. I skipped how the textToSpeech object gets instantiated.

Consumer

All we need to do to consume this API is fire off an intent:

Intent intent = new Intent();
intent.setAction("io.ejf.intentexamples.say");
intent.putExtra("SAY_TEXT", "Some string to speak");
sendBroadcast(intent);

The above works from apps other than our demo. This is a public API on the phone. In the example code on GitHub, I actually added the above to a separate app, called “SayLauncher”:

SayLauncher

Check out this tag on GitHub!

(Quick side-note here, if you want to check out the repository at this step, first check out the repo, then run the following command: git checkout -b step5 step5. That will get you a branch at the step1 tag.)

Sharing from any app

What we’re doing is a special case of the public APIs discussion, because there’s already a way of doing this that many apps know about, and use. That is generic text sharing. One note here is that text is generally shared to an Activity, but that’s not a big deal for us, we can simply implement a dummy Activity, forward the Intent, then kill the Activity. Let’s take a look.

First, implement the Activity in the AndroidManifest:

<activity android:name=".say.TtsDummyActivity" >
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="text/plain" />
    </intent-filter>
</activity>

Now, in the TtsDummyActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Intent intent = getIntent();
    String action = intent.getAction();
    String type = intent.getType();

    if (Intent.ACTION_SEND.equals(action) &&  "text/plain".equals(type)) {
        Intent sIntent = new Intent(this, TtsService.class);
        sIntent.putExtra(Constants.SAY_TEXT, intent.getStringExtra(Intent.EXTRA_TEXT));
        startService(sIntent);
    } else {
        Log.w(TAG, "received unknown intent");
    }

    finish();
}
share via screen

Whenever possible, it’s a good idea to use the popular way of providing APIs to other apps. That way, you don’t need specific implementations, and you can rely on the fact that lots of apps are going to be using these mechanisms. Sometimes, it might make sense to offer two ways of doing something, like we did in this example. That way, if there is an app that wants to integrate directly, because they want exactly the behavior that you provide, then they can do that.

Check out this tag on GitHub! ( git checkout -b step6 step6 )

Conclusion

We got a lot done here today. First, we finally got around to discussing why we’re bothering with this whole exercise. We discussed a real-world example of how this sort of thing is helpful to all parties, users, API providers, and API consumers. Then, we went through a concrete example and demonstrated a fun way to both produce and consume a public API on the phone.

Next time, we’ll start thinking of some other applications for APIs on the phone, and we’ll pick out another example to work through.

Why do we want public APIs? (Android Intents Part 2)

This is the second post in a series about sharing information between apps. (Part 1 is here.) In this post, we’re going to discuss why it might be nice to have a public API exposed from a third party app. I’ll be providing videos that cover the text contents of these posts (plus insightful things), so if you want to watch instead of read, check out the video below:

If you watched the video, feel free to skip to Part 3, where we’ll look at some code. This post is simply a text version of the video.

Series Table of Contents

Follow the series on the Table of Contents page.

Why do we want a public API on the phone?

There are three perspectives here, the user is one, and then the producing developer, and consuming developer are the other two. This isn’t as complicated as it sounds.

I’m going to put this in terms of a couple of concrete apps, so that we have some apps that we can look at, and think about, as opposed to talking so much in the abstract. We’ll talk about MyFitnessPal as the producing developer, offering the API. Strava and Withings will be the consuming developers, they consume MyFitnessPal’s APIs.

This discussion may seem kind of long, but it is the central idea of this entire series. I promise we’ll get back to code soon. Again, if you watch the video, you can skip straight to Part 3, because all of the long text part is covered in the video.

I’d also like to mention up front that these apps already do integrate with each other, but they do it via the web, not on the phone. I’ll discuss the difference in the ‘user’ section. There’s also Google Fit, which intends to take care of this particular issue, and IIRC provides some useful integrations on the device side. In short, this particular example is almost completely solved already, but it’s an easy one to think about, so we’re going to keep it.

Producing Developer

MyFitnessPal sketch

MyFitnessPal, lot’s of typing!

Imagine that you’re MyFitnessPal, and an app that does calorie counting. MyFitnessPal provides users a way to enter their food and exercise and your app tells them how many calories they’ve consumed and how many they’ve burned. Now, you care about gathering fitness data from users, but your main method of getting that data is asking users to enter it manually. Then, along comes Strava, they do automatic tracking for bicycle riding and running. If your user is using both Strava and MyFitnessPal, you could open up an API for Strava (and any other activity tracking app) to send data to MyFitnessPal, so that users don’t have to manually input something that was already captured automatically for them.

Withings sketch

Withings, works just like an ordinary scale, but it syncs your weight to its service

It’s the same deal with Withings, they provide some passive tracking hardware, like a digital scale that sends your current weight to their app, an activity tracking watch, as well as some other products. You, as MyFitnessPal, could open another API that would allow Withings to sync up the user’s weight with you. Withings could use the same APIs for exercise tracking that you opened up for Strava.

The apparent downside is that users will no longer need to enter your app to manually enter this data. However, by offering an API for other apps to consume, you’re actually making both your app and the other app more powerful. Now the user needs to do less work, and they’re going to appreciate that they get stuff for free (free data entry, which is a pain to do on your phone). When you start offering APIs that other apps can consume, users are going to like you more because make the their life easier.

Consuming Developer

Strava sketch

Strava doesn’t require much typing, it records your session.

Now, imagine you’re Strava, you do a great job tracking users’ runs and bike rides, but your users are asking for food tracking as well. That’s a difficult problem, and not really your core competency. It’s something that you really don’t want to do yourself. Luckily, you know that MyFitnessPal does food tracking really well, and they also do exercise tracking. What’s more, they offer an API that allows apps like Strava to send them activity data. All you need to do is implement an API, and now you can tell users to install MyFitnessPal when they ask about food tracking. The best part is that it’s automatic and in the background, users don’t need to think about it, and you’ve done almost no work. It’s a win-win!

User

Imagine that you’re a user that wants to count calories, track your weight, and goes running. MyFitnessPal, Withings, and Strava all work together to allow you to do most of this tacking passively, cutting down the amount of manual data entry you have to do, and saving you time. If there’s a run tracking app that you like, but doesn’t integrate with MyFitnessPal, is that extra friction worth it, or are you going to switch over to Strava?

As I mentioned before, these apps already do integrate with one another, and it’s not exclusive to the listed apps, most of the worthwhile fitness apps I’ve come across integrate with each other. The one big downside is that they integrate in the backend, not on the phone. What this means is that users need to sign into different services multiple times on their phones, or set up those integrations on their computers. This is friction. Why not just do it seamlessly on the phone? Is there a reason to even ask the user to log in, when they’re already logged in on the phone in the other app?

Instead of integrating on the backend, it seems possible to integrate on the frontend. The apps just fire intents at each other, and allow the providing app to do the auth in their app. This could be as simple as popping a dialog and asking the user if it’s OK if the other app send it data. What’s more, it means that you don’t need an internet connection for the apps to sync with each other (either via intents, or maybe a combination of intents and content providers). Currently, these services sync up on their own schedule, and it can cause users to manually enter information that will be automatically synced later. Friction.

Integration sketch

The above is a sketch of Withings and Strava talking to MyFitnessPal, if you couldn’t tell. =)

Conclusion

In this post I explained why we’re bothering with this whole exercise. We discussed a real-world example of how this sort of thing is helpful to all parties, users, API providers, and API consumers. Hopefully this has given you some perspective on what this series is all about, and where we might want to go from here. Incidentally, if you have ideas for this series, please feel free to reach out.

Next time, we’ll look at an example that demonstrates a fun way to both produce and consume a public API on the phone.

How to launch an Activity (Android Intents Part 1)

This is the first post in a series about sharing information between apps. It will start with the basics, and move on to discuss how we might leverage this to do some interesting things. Additionally, I’ll be providing videos that cover the text contents of these posts (plus insightful things), so if you want to watch instead of read, check out the video below:

Apologies for the quality of the video. I’m just starting out, and hoping that I’ll be able to get better at this. However, I don’t want to let my lack of skill and inexperience prevent me from moving forward.

Series Table of Contents

Follow the series on the Table of Contents page.

Sharing in Android

In Android, information is shared between apps in few different ways, there’s local files stored in the shared storage area of the device, then there are Content Providers, and Intents. Using local files as information sharing seems pretty hacky, and is wide open for attack, so I’m not going to discuss that. Content Providers are interesting, but this series is going to be discussing Intents. If this goes well, maybe I’ll circle back and cover Content Providers.

I’m going to note the official documentation on sharing right here:

Great, now that that’s out of the way, we can get started.

Prerequisites

You’ll need to have your Android development environment all set up. Here’s a post from Google on setting up your environment. Or, in video form below:

Launch an Activity

Let’s say that you want to open one Activity from another Activity, you’d use an intent like the following:

startActivity(new Intent(this, ActivityTwo.class));

In this example, the ‘information’ that you’re sharing is simply that you’d like ActivityTwo to appear on top of ActivityOne. If you’d like to see a fully working example of this, check this tag on GitHub.

(Quick side-note here, if you want to check out the repository at this step, first check out the repo, then run the following command: git checkout -b step1 step1. That will get you a branch at the step1 tag.)

That’s really it for the first example. You can run it on your device, and should see something like the following:

screen 1 screen 2

In the above example, the ‘LAUNCH INTENT’ button runs the startActivity code described above to launch the second activity.

Launch an Activity with Extras

Next, let’s extend the first example, and add a button to ActivityTwo that points back at ActivityOne. However, instead of just launching ActivityOne, we’ll send back some data along with it, that ActivityOne will display. Here’s the tag on GitHub for this state. ( git checkout -b step2 step2 )

This time, we’ll set an extra on the intent:

Intent intent = new Intent(this, ActivityOne.class);
intent.putExtra("EXTRA_CONTENT", "saw ActivityTwo");
startActivity(intent);

ActivityOne will need to check for the intent extra and then do something with it. Here’s how it looks now:

screen 1 screen 2b screen 1b

Start a Service

First, let’s add a button to the Activity:

screen 1

Next, in the OnClickListener for the button, we’ll add some code to launch the intent:

startService(new Intent(this, MainService.class));

Simple, right?

Now, let’s say that we want to kill the service. What should we do? Well, we can actually kill the service using another intent with startService. Here’s what we’ll add to the Service:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    if (intent.hasExtra("KILL"))
        stopSelf();
    return super.onStartCommand(intent, flags, startId);
}

Then we just put an Extra in the intent in the Activity:

Intent intent = new Intent(this, MainService.class);
intent.putExtra("KILL","");
startService(intent);

If you run that, you’ll see the service getting started then stopped. I added logs to the onStartCommand and onDestroy methods of the service, and here’s what I saw when I clicked the button:

11-04 07:58:23.257 27985-27985/io.ejf.intentexamples I/MainService: starting service
11-04 07:58:23.266 27985-27985/io.ejf.intentexamples I/MainService: stopping service

Check out the code at this point. (git checkout -b step3 step3)

Send a Broadcast

Now, let’s take a look at how to send an intent to a BroadcastReceiver. It’s fairly straightforward, but one little note is that we should add an entry to the AndroidManifest.xml with our intent filter:

<receiver android:name=".MainReceiver" >
    <intent-filter>
        <action android:name="io.ejf.intentexamples" >
        </action>
    </intent-filter>
</receiver>

We need entries for our Services and Activities as well, but when we add an intent-filter it lets the system know what this receiver can handle. (This is our first public API!) Now, we can send a broadcast:

Intent intent = new Intent();
intent.setAction("io.ejf.intentexamples");
sendBroadcast(intent);

I’ve added a log to my receiver, and it seems to work:

11-04 08:28:03.303 25479-25479/io.ejf.intentexamples I/MainReceiver: received broadcast

Check out the code at this point. ( git checkout -b step4 step4 )

Conclusion

That’s it for right now, but you saw a couple of basic things here. We’re now launching an Activity as well as passing some data along. We also now have our first public API! What’s more, our API runs something in the background, and doesn’t bring up another screen. This is an important point that we’ll get into later on. Next, we’ll extend that to start offering something useful.

Android Intents Series Table of Contents

This is the Table of Contents for a series of blog posts and videos about sharing information between apps. It will start with the basics, and move on to discuss how we might leverage this to do some interesting things.

The following is the table of contents for the series:

The code for the series is here.

Here’s the YouTube playlist for the videos in the series:

Fresh Beans

Startup Unicorn Halloween Costume

startup unicorn costume

This year, for Halloween, I was a startup unicorn. I wore my normal clothes (hoodie, t-shirt, and jeans) with a unicorn mask. I also had a thing of bubbles. I don’t think anybody got it (that I didn’t tell). Oh well.

Dino-Woman

dino woman

Last night, we were out to a party on Halloween in a neighborhood that really gets into it. Next door, there was a woman who had made an amazing costume. The photo doesn’t do it justice, she must have been on stilts, and the dino head moved around. It reminded me of the viking women in Kung Fury riding the dinosaurs. I’m not sure if that’s what she was, but either way, it was impressive.