Generating Image Hashtags using Microsoft’s Computer Vision API

Whatever your social media tool of choice is these days, it’s almost guaranteed to be filled with images and their associated hashtags #sorrynotsorry #lovelife #sunnyday

Sometimes coming up with those tags is more work than perfectly framing your latest #flatlay shot.

In the age of amazing image recognition tech, it must be possible to create something that can help us out and give us more time to move that light source around to cast the right shadow over your meal.

Turns out, it is possible! Yay! (of course..)

In this article I’ll show you how to automatically generate image hashtags via a chatbot using Microsoft’s Computer Vision API.

Continue reading

Sentiment Analysis using Microsoft’s Cognitive Services

Now that we are making more conversational interfaces thanks to technology like botframework, interaction with the user is no longer limited to a tap on a link or a button.

Having written language as the primary form of interaction with our systems gives significant difficulties in terms of intent understanding, but also gives great opportunities for further understanding of the user.

Intent understanding has already been tackled by the likes of LUIS; what about the user’s sentiment?

In this article I’m going to introduce Microsoft’s Text Analysis API and show you how to easily get sentiment analysis for a message coming in to your bot.

Continue reading

Virtual Shop Assistant Chatbot with Amazing Image Recognition

There has been some significant progress in “deep learning”, AI, and image recognition over the past couple of years; Google, Microsoft, and Amazon each have their own service offering. But what is the service like? How useful is it?

Everyone’s having a go at making a chatbot this year (and if you’re not, perhaps you should contact me for consultancy or training!) – and although there are some great examples out there, I’ve not seen much in the e-commerce sector worth talking about.

In this article I’m going to show you a cool use case for an image recognition e-commerce chatbot via a couple of clever APIs wired together by botframework.

Continue reading

Sending Proactive Botframework Messages

Having a botframework chatbot up and running and responding to user messages is one thing, but how can you send a new message to bring the user back into the conversation if they haven’t just sent a new message for you to reply to?

The botframework documentation and other tutorials will point you towards using Azure Functions and the new ActivityType.Trigger to handle this which, although being a great use case for Azure Functions, make the underlying implementation harder to understand. It also means you couldn’t easily implement this on AWS, for example.

In this article I’ll show you how to easily implement Proactive Botframework Messaging just using BotFramework fundamentals.

Continue reading

Rich botframework conversation cards

In the last article about bots I covered creating a basic bot using Microsoft’s botframework, setting up Azure, deploying the bot into Azure, and configuring it to work within Skype.

In this article we’re going to investigate the various response types available to us in the botframework to develop a more rich conversational experience.


Luckily you’re not limited to plain text in a bot conversation; we’re able to embed images, add attachments, give headers and subheaders, add a button or link, tap events for various areas, as well as use markdown to format the main text content.

If you’re not already familiar with Markdown, then get on the case! It means you can very easily write HTML by using a shorthand syntax which can easily be converted to HTML.

I’ve been using it for many years for blogging and general documentation; using pandoc you can even convert markdown to PDF or a Word Doc. Using remark.js or the more recent Marp you can use it to easily create PowerPoint-like presentations

markdown example

Botframework messages support using this syntax to make the responses more rich. Of course, for this to work, the attached service needs to know how to render the response (and I’ll get on to this later)

Continue reading

Create your first botframework bot in Azure!

At //Build 2016 Microsoft unleashed something known as the Bot Framework; a set of three products to help you build conversational bots and connect them with services, like Slack, Skype, and even Email and SMS.

The Bot Framework has a number of components including the Developer Portal, Bot Builder, and the Bot Directory:

  • Developer Portal is where you wire your bot up to existing services like Skype and Slack
  • Bot Directory is where you publish your bot to so that others can search for and connect it to their Skype and Slack
  • Bot Builder is what you use to implement a more complex and intelligent conversational flow, optionally leveraging the awesome power of some of the Microsoft Research’s Cognitive Services for language interpretation, image recognition, and much more.

In this article I’m going to take you through the process of creating, deploying, and configuring your own Skype bot.

Continue reading

Getting Browser Location in Chrome and Deprecating Powerful Features on Insecure Origins

A while ago I created the most useful web page I’ve ever written; an extremely basic page to list the bus arrival times, based on your current location anywhere in London!

I have used this page several times a day on an almost daily basis since I created it, as does my wife; every morning we need to know when the next bus will arrive near our house in order to know when to rush out with our children to take them to school.

I used it every morning to check if I needed to rush out the door to catch the rare “express” bus that would get me to the tube much quicker than the usual one.

I discovered just how useful it is whilst in a pub, deciding whether I had time for another drink before heading home; a quick glance at my phone and I could find out that the next bus home wasn’t for 20 minutes – plenty of time!

However, recently it stopped working for me. It still worked just fine on my wife’s iPhone (and hence Safari), but not on my Nexus (Chrome). It works on my laptop too, or at least appeared to.

So what’s going on?

Continue reading

Scripting a StatsD, MongoDB, ElasticSearch metrics server on Azure with Powershell

At Mailcloud I am constantly destroying and rebuilding environments (intentionally!), especially the performance test ones. I also need to gather oodles of metrics from these tests, and I have a simple script to create the VM and another to install all of the tools I need.

This article will cover using a simple Powershell script to create the Linux VM and then a slightly less simple bash script to install all the goodies. It’s not as complicated as it may look, and considering you can get something running in a matter of minutes from a couple of small scripts I think it’s pretty cool!

Stage 1, Creating the VM using Powershell

Set up the variables

# os configuration
# Get-AzureVMImage | Select ImageName
# I wanted an ubuntu 14.10 VM:
$ImageName = "b39f27a8b8c64d52b05eac6a62ebad85__Ubuntu-14_10-amd64-server-20140625-alpha1-en-us-30GB"

# account configuration
$ServiceName = "your-service-here"
$SubscriptionName= "your azure subscription name here"
$StorageAccount = "your storage account name here"
$Location = "your location here"

# vm configuration - setting up ssh keys is better, username/pwd is easier.
$user = "username"
$pwd = "p@ssword"

# ports
## ssh
$SSHPort = 53401 #set something specific for ssh else powershell generates a random one

## statsd
$StatsDInputPort = 1234
$StatsDAdminPort = 5678

## elasticsearch
$ElasticSearchPort = 12345

Get your Azure subscription info

Set-AzureSubscription -SubscriptionName $SubscriptionName `
                    -CurrentStorageAccountName $StorageAccount

Select-AzureSubscription -SubscriptionName $SubscriptionName

Create the VM

Change “Small” to one of the other valid instance sizes if you need to.

New-AzureVMConfig -Name $ServiceName -InstanceSize Small -ImageName $ImageName `

| Add-AzureProvisioningConfig –Linux -LinuxUser $user –Password $pwd -NoSSHEndpoint `

| New-AzureVM –ServiceName $ServiceName -Location $Location

Open the required ports and map them

Get-AzureVM -ServiceName $ServiceName -Name $ServiceName `
| Add-AzureEndpoint -Name "SSH" -LocalPort 22 -PublicPort $SSHPort -Protocol tcp `

| Add-AzureEndpoint -Name "StatsDInput" -LocalPort 8125 -PublicPort $StatsDInputPort -Protocol udp `

| Add-AzureEndpoint -Name "StatsDAdmin" -LocalPort 8126 -PublicPort $StatsDAdminPort -Protocol udp `

| Add-AzureEndpoint -Name "ElasticSearch" -LocalPort 9200 -PublicPort $ElasticSearchPort -Protocol tcp `

| Update-AzureVM

Write-Host "now run: ssh $ -p $SSHPort -l $user"

The whole script is in a gist here

Stage 1 complete

Now we have a shiny new VM running up in Azure, so let’s configure it for gathering metrics using a bash script.

Stage 2, Installing the metrics software

You could probably have the powershell script automatically upload and execute this, but it’s no big deal to SSH in, “sudo nano/vi” a new file, paste it in, chmod, and execute the below.

Set up the prerequisites

# Prerequisites
echo "#### Starting"
echo "#### apt-get updating and installing prereqs"
sudo apt-get update
sudo apt-get install screen libexpat1-dev libicu-dev git build-essential curl -y

Install nodejs

# Node
echo "#### Installing node"
. ~/.bashrc
export "PATH=$HOME/local/bin:$PATH"
mkdir $HOME/local
mkdir $HOME/node-latest-install

pushd $HOME/node-latest-install
 curl | tar xz -strip-components=1
 ./configure -prefix=~/local
 make install

## the path isn't always correct, so set up a symlink
sudo ln -s /usr/bin/nodejs /usr/bin/node

## nodemon
echo "#### npming nodemon"
sudo apt-get install npm -y
sudo npm install -g nodemon

Add StatsD

Here I’ve configured it to use mongo-statsd-backend as the only backend and not graphite. Configuring Graphite is a PAIN as you have to set up python and a web server and deal with all the permissions, etc. Gah.

# StatsD
echo "#### installing statsd"
pushd /opt
 sudo git clone
 cat >> /tmp/localConfig.js << EOF
 port: 8125
, dumpMessages: true
, debug: true
, mongoHost: 'localhost'
, mongoPort: 27017
, mongoMax: 2160
, mongoPrefix: true
, mongoName: 'statsD'
, backends: ['/opt/statsd/mongo-statsd-backend/lib/index.js']

 sudo cp /tmp/localConfig.js /opt/statsd/localConfig.js

Mongo and a patched mongo-statd-backend

You could use npm to install mongo-statsd-backend, but that version has a few pending pull requests to patch a couple of issues that mean it doesn’t work out of the box. As such, I use my own patched version and install from source.

# MongoDB
echo "#### installing mongodb"
sudo apt-key adv -keyserver hkp:// -recv 7F0CEB10
echo 'deb dist 10gen' | sudo tee /etc/apt/sources.list.d/mongodb.list
sudo apt-get update && sudo apt-get install mongodb-org -y
sudo service mongod start
cd /opt/statsd

## Mongo Statsd backend - mongo-statsd-backend
## the version on npm has issues; use a patched version on github instead:
sudo git clone
cd mongo-statsd-backend
sudo npm install

Ready to start?

Let’s kick off a screen

# Start StatsD
screen nodemon /opt/statsd/stats.js /opt/statsd/localConfig.js

Fancy getting ElasticSearch in there too?

To pull down and install the java runtime, install ES and the es-head, kopf, and bigdesk plugins, add the below script just before you kick off the “screen” command.

# ElasticSearch
echo "#### installing elasticsearch"
sudo apt-get update && sudo apt-get install default-jre default-jdk -y
elasticsearch/elasticsearch/elasticsearch-1.1.1.deb && sudo dpkg -i elasticsearch-1.1.1.deb
sudo update-rc.d elasticsearch defaults 95 10
sudo /etc/init.d/elasticsearch start

## Elasticsearch plugins
sudo /usr/share/elasticsearch/bin/plugin -install mobz/elasticsearch-head
sudo /usr/share/elasticsearch/bin/plugin -install lukas-vlcek/bigdesk

You can now browse to /_plugin/bigdesk (or the others) on the public $ElasticSearchPort port you configured in the powershell script to see your various ES web interfaces.

The whole script is in a gist here.

Stage 2 complete

I use StatsD to calculate a few bits of info around the processing of common tasks, in order to find those with max figures that are several standard deviations away from the average and highlight them as possible areas of concern.

I have an Azure Worker Role to pull azure diagnostics from table and blob storage and spew it into the Elasticsearch instance for easier searching; still figuring out how to get it looking pretty in a Grafana instance though – I’ll get there eventually.

Upload to Azure Blob Storage using Powershell

I needed to automate the process of uploading images to Azure blob storage recently, and found that using something like the excellent Azure Storage Explorer would not set the Content Type correctly (defaulting to “application/octetstream”). As such, here’s a little script to loop through a directory and do a basic check on extensions to set the content type for PNG or JPEG:

The magic is in Set-AzureStorageBlobContent.

Don’t forget to do the usual dance of calling the following!

These select your publish settings file, and set which subscription is the currently active one:

  • Import-AzurePublishSettingsFile
  • Set-AzureSubscription
  • Select-AzureSubscription


Actually, the Aug 2014 version of Azure Storage Explorer already sets the content type correctly upon upload. Oh well. Still a handy automation script though!