As reported by Pingdom, Embedly’s uptime for the month of April has been 100%. We pay Pingdom to manage these checks and have configured them to properly monitor the API’s health.

We were pretty surprised when Verelo started reporting on Twitter that we were down. If you have never heard of Verelo (neither had I), they monitor uptime like Pingdom and were recently acquired by Dyn.

Apparently they are also into public shaming to try to drum up business, so we are going to return the favor.

Verelo runs a site called whatsdowntoday.com where they hook up their services to a bunch of sites without notifying them first. They ping them and tweet out at @verelostatus when one fails to pass it’s status check.

They nicely have Tweet and Facebook buttons to share downtime, but no links to the service they are actually checking.

Embedly’s API is one of these services, however, their check is not configured correctly. Verelo does not include an API key in the URL, so when they hit our usage limit for unauthenticated requests we throw errors. If you rely on Verlo we have been down for most of the last 2 days.

Funny enough, this is their API call:

http://api.embedly.com/1/oembed?&maxwidth=400&maxheight=300&urls=https://t.co/04SmeCDl

That t.co url redirects to a reddit post for their own press release: https://t.co/04SmeCDl. Zero comments, whomp whomp.

I’m all for trying to to acquire new business, but by publicly shaming people via whatsdowntoday.com is down right dirty.

Attracting customers starts with building relationships, not alienating your target market. Your viral growth hack has turned into spam, time to go back to the drawing board.

If you would like to see Embedly’s actual status, you can check out Pingdom: http://stats.pingdom.com/q1pr2ct042w3

Posted 1 year ago by screeley
Embed This
Tagged:

This is the second post in our series on Ember. We will be building off the development environment we set up in the first post.

In practice, everything is based off the router and templates. Ember handles the dynamic creation of views and controllers. You really don’t need them until you start dealing with data and events.

By default Ember sets up two routes for you: application and index. application is the container for your entire application while index is the route for the root of your site ‘/’. You can create the two templates for these routes in the templates directory.

$ touch app/templates/application.handlebars
$ touch app/templates/index.handlebars

And for good measure we will create a global nav.

$ touch app/templates/nav.handlebars

The application template is a good place to create scaffolding; things that need to be on every page and also inside the scope of the application. Here is our simple application.handlebars:

{{ render "nav" }}
<div class="row">
 <div class="large-12 columns">
  {{outlet}}
 </div>
</div>

We just introduced two handlebars helpers that Ember uses: render and outletHandlebars helpers are a part of the Handlebars template language that is included with Ember. The render and outlet helpers are added by Ember.

About render from the docs:

Renders the named template in the current context using the singleton instance of the same-named controller.

render allows you to include one template into another. It’s much like the template helper, but also allows you to pass data along. In this case you could use either.

outlet is a placeholder that allows you to specify where the child node’s content will be rendered. They are much like {% block %} tags in Django or <%= yield ==%> in ERB.

Since application.handlebars is the base route the content from index.handlebars will be rendered where this outlet is. We can create a simple index.handlebars to prove this.

$ echo "<h1>Welcome To My App</h1>" > app/templates/index.handlebars

Routes

Routes are URL paths. To add a new page, you need to add a new route. So to add our about page, we need to add a route to our router.

App.Router.map(function(){
  this.route('about');
});

Ember is creating AboutRoute, AboutView, and AboutController. We don’t really need those for this exercise, but we do need a template with some content.

$ echo "<h1>About To My App</h1>" > app/templates/about.handlebars

If you visit ‘/#/about’ you will see the content.

Resources

When you want to start grouping routes, i.e. “/company/contact” and “/company/team” resources come in to play. The benefit here is that they share common templates. While you could so something like this:

App.Router.map(function(){
  this.route('contact', {path:'/company/contact'});
  this.route('team', {path:'/company/team'});
});

It becomes a mess really quickly. Instead you should use a resource.

App.Router.map(function(){
  this.resource('company', function(){
    this.route('contact');
    this.route('team');
  });
});

It is however a little more confusing when it comes to templates. Like the application route, we need to create a base container for all the leaf routes. This could be as simple as:

$ echo "{{outlet}}" > app/templates/company.handlebars

In this case, everything will just be added to the outlet in the application.handlebars. If you want every company page to have common display attributes, you can change the template:

<h1>Company</h1>
<div class="row">
  <div class="large-9 columns">
    {{outlet}}
  </div>
  <div id="sidebar" class="large-3 columns">
    {{outlet sidebar}}
  </div>
</div>

You’ll notice here that we added a named outlet. By default all content from the leaf routes will go into the {{outlet}} unless we tell it to go somewhere else instead.

We can then create the leaf templates.

$ mkdir app/templates/company
$ touch app/templates/company/index.html
$ touch app/templates/company/contact.html
$ touch app/templates/company/team.html

This is one of the nice things about having ember_templates set up and compiling templates for you. Ember expects the templates to be put into EM.TEMPLATES hash as ‘resource/route’ or you need to declare the templateName on the view. The former is less code.

Custom Routes

We set up that outlet earlier, it’s time that we use it. In order to use named outlets we need to modify the Routes behavior. Here we will change that Company Team Route to add a sidebar. In the main.js file we are going to add:

App.CompanyTeamRoute = Em.Route.extend({
  renderTemplate: function(controller, model){
    // Render the base template
    this._super(controller, model);
    // Render the bios template into the sidebar
    this.render('bios', {outlet: 'sidebar'});
  }
});

And then add the bios template:

$ echo "<h2>Bios</h2>" > app/templates/bios.handlebars

When you visit /#/company/team you will see the bios section in the template.

Alright, that was a quick primer into the Router and Templates, you can see the final code here: https://github.com/screeley/ember-demo-environment/tree/router. Next week, we’ll go into using View and Controllers.

Posted 1 year ago by screeley
Embed This

Hello there embedders! You might have noticed that we have recently released a couple new products — today we’re going to talk about a couple features of the new /1/extract endpoint. Extract is great when you want to not only embed a URL but get a deeper understanding of its contents.

Let’s write up a quick application that scrapes the front page of any given subreddit and uses the extract endpoint to see what people are talking about by totaling all keywords and entities. Keywords are probably what you expect them to be, while entities are essentially just proper nouns. Note that you’ll need an Embedly API key to run this demo — you can get one for free if you don’t already have one!

First thing’s first: let’s grab the frontpage of a subreddit using reddit’s awesome JSON API. This is just a simple HTTP request to the subreddit frontpage with .json appended to the URL.  We also define a function to extract all of the URLs from this blob:

import sys
import json
import urllib

import requests

def reddit(sub):
    """
    Retrieve the json representation of the given subreddit
    """
    url = 'http://reddit.com/r/%s.json' % sub
    resp = requests.get(url)
    return json.loads(resp.text)

def reddit_urls(js):
    """
    Return all the URLs in the given json blob of reddit data
    """
    return [x['data']['url'] for x in js['data']['children']]

The above code depends on one external package: the excellent requests package, which makes performing HTTP requests very simple.

Now that we have a list of URLs, let’s call embedly’s extract endpoint. For URLs that have any significant amount of text this response will include keywords and entites that summarize the text (take a look at an example response if you’d like to see what else is returned).

def embedly(url, key):
    """
    Call the embedly API and return the json blob. Returns None if there
    is an error processing the URL (e.g., HTTP 404)
    """
    quoted = urllib.quote(url)
    api = 'http://api.embed.ly/1/extract?url=%s&key=%s' % (quoted, key)
    resp = requests.get(api)
    if resp.status_code != 200:
        sys.stderr.write('Failed to process URL %s :(\n' % url)
        return None
    return json.loads(resp.text)

Okay, now we can just loop over all of the responses and sum together all of the counts and take the, say, ten highest counts. The code below operates on entities, but by changing ‘entities’ to ‘keywords’ in the line above sum_counts you can have it look at keywords instead!

def sum_counts(item_lists):
    """
    Takes a list of lists of items and mashes them all together into a dict
    mapping item_name -> item_score. The input items are either entity or
    keyword lists, which look like {'name': 'Dennis', 'count': 10} or
    {'name': 'sports', 'score': 33}, respectively.
    """
    ret = {}
    for item_list in item_lists:
        for item in item_list:
            # get either score or count so we can work with both
            # keywords and entities
            name, count = item['name'], item.get('count', item.get('score', 0))
            ret[name] = ret.get(name, 0) + count
    return ret

def top_n(item_dict, n):
    by_count = sorted(item_dict.iteritems(), key=lambda x: x[1],
        reverse=True)
    return by_count[:n]


def main(subreddit, key):
    urls = reddit_urls(reddit(subreddit))
    embeds = [embedly(url, key) for url in urls]
    # change 'entities' to 'keywords' to check out the keyword extraction!
    items = [x['entities'] for x in embeds if x]
    all_counts = sum_counts(items)

    top = top_n(all_counts, 10)
    print '\n'.join('%s %s' % (x[0], x[1]) for x in top)


if __name__ == '__main__':
    if len(sys.argv) < 3:
        sys.stderr.write('Usage: demo.py <subreddit> <your-embedly-key>\n')
    else:
        main(sys.argv[1], sys.argv[2])

Let’s try it out on /r/sports!

$ python demo.py sports <your-embedly-key>
NCAA 13
Ware 3
Sharks 2
Daily Caller 2
Kevin Ware 2
Louisville 2
Cal 2
Taylor Branch 1
San Jose Sharks 1
National Collegiate Players Association 1

Here we can see that the NCAA is by far the most popular entity mentioned, which should be no surprise considering we’re in the height of the March Madness tournament. Kevin Ware also makes an appearance, no doubt due to his unfortunate injury in Sunday’s game.

How about /r/worldnews?

$ python demo.py worldnews <your-embedly-key>
North Korea 66
India 30
Pakistan 27
U.S. 21
China 19
UN 17
Bolkovac 16
United States 14
EU 13
Novartis 13

Looks like North Korea is big right now, which isn’t too surprising considering what’s been going on over there.

Go grab the source if you’d like to play around. There are all sorts of ways to extend this — extract also pulls image metadata, so maybe you could make an image wall sorted by keyword or entity of what’s going on right now. Or use the related article feature to curate content on the current hottest topic. Speaking of related articles, we’ll be showcasing that feature in an upcoming post!

Sign up for a free account to start using Extract and run this example, or check out the other features and demos available for Extract.  Other thoughts? Continue the conversation on Twitter

Posted 1 year ago by thejohnnest
Embed This

This is John.

image

John works at Embedly and he seems like a normal guy. He likes ultimate Frisbee, a good joke and time with friends. He has 10 fingers and 10 toes, but John was born with a great affliction. From the second he was put on this earth he had to endure overwhelming odds against him. 

You see when John was delivered the doctor held him up, as Rafiki did to Simba, and proclaimed “April Fools.” Yes, John was born on the 1st of April.

Gasp, I know. Let that sink in for a second.

Like millions of “Foolies”, as they call themselves, he was subjected to a childhood of bad jokes. “Your parents must of thought you were a joke…” “Here little Johnnie, I got you the TMNT action figure you wanted. Nope, Ha, April Fools.” “John, we got you a car for your Birthday. Ha, April Fools, here’s a Frisbee.” “John, you were adopted… April Fools!” The courage that it takes, I can’t imagine.

The Foolies are a fellowship. Once a year, while everyone is out pranking they meet at a bar. They drink raspberry beer and not a single giggle is heard. They sit in peace as the world burns around them.

We at Embedly support the Foolies. We will not be participating in what tech has deemed a day of bad jokes thought up by insensitive marketing people to show their company has a “fun side.” It hurts real people like John and we cannot condone such actions.

There will be no scratch and sniff embeds and you will not be hearing Rick Astley.

Instead we will be silent in solemn solace with those less fortunate than us. John, we will not be pranking anyone today, we love you, stay strong.

- Sean

Posted 1 year ago by screeley
Embed This
Tagged:

Every time I see Ember on Hacker News it’s being trashed, like MongoDB trashed. It sucks for an open source project when the herd mentality kicks in and it becomes cool to hate. Sadly, I’m not one of the cool kids.

Ember is excellent. We use it extensively here at Embedly for our developer dashboard. While none of us here are JavaScript experts, Ember has made us incredibly productive.

We are going to do a series of posts on Ember at Embedly. Mostly tips and tricks that have made us successful. These are not aimed at the pro, but the amateur.

A lot goes in to baking a production-quality website, and Ember adds to that. As a result, there is a lot of boilerplate when it comes to setting up the development environment. Rest assured that once you fight through the boilerplate, you’ll be able to iterate at an impressive rate.

Okay, so you have a new awesome idea of what you are going to build, how do you get started?

Yeoman/Grunt

Grunt is the Javascript Task Runner. It makes the set up of common tools like jshint, compass, uglify and development servers dead simple. We use it in almost every project now and it has made development a whole lot easier.

Yeoman is a thin wrapper around Grunt that really just builds out a directory structure and a few files. One member of your team will use it once and never think about it again.

So, let’s get started.

$ mkdir demo
$ cd demo
$ npm install -g yo grunt-cli bower

At the time of writing, the ember generator for yeoman is hosed, so you can do what you wish with that information. We can just use the default webapp generator.

$ yo webapp
$ npm install & bower install

This will build a pretty simple directory structure.

  app /
    index.html
    scripts/
      main.js
    styles/
      main.css
  Gruntfile.js
  package.json
  test /

Yeoman sets up the project so it can immediately be used. Run grunt’s server to launch your new web app.

$ grunt server

Tada, a browser will open to http://localhost:9000/ and show a nice little Allo message.

Getting Ember

Bower is Twitter’s package management tool for the Web. Let’s get Ember installed using bower.

$ bower install ember

Bower will handle getting all the right dependencies and install them in a components directory. You will then need to add Ember and Handlebars to your index.html file.

$ vim app/index.html

You can put the following lines near the bottom but above main.js:

<script src="components/handlebars/handlebars.js"></script>
<script src="components/ember/ember.js"></script>

Grunt will live reload your browser. You now have all the dependencies for a simple Ember app. You can prove it by opening up the console and running Em.

To recap, that was about 5 commands to get Ember completely ready to go:

$ npm install -g yo grunt-cli bower
$ yo webapp
$ npm install && bower install
$ bower install ember
$ vim app/index.html

If you complain about how hard Ember is to set up you are using the wrong tools.

Templates

Here on out is optional, but will probably save you some headaches later down the road. We will set up grunt-ember-templates, an Application and the Router.

The grunt-ember-templates module pre-compiles all your templates on the fly and adds them to Em.Templates, which is where Ember keeps your templates so it can match them to your views, based on naming convention. More on this later.

$ npm install grunt-ember-templates --save-dev
# Create the templates directory.
$ mkdir app/templates
$ touch app/templates/index.handlebars

We are going to have to update the Gruntfile to run ember_templates

Grunt is configured by a Gruntfile.js, which uses JSON to define a bunch of different actions that Grunt can perform for you. This is where we’ll hook up grunt-ember-templates to Grunt.

$ vim Gruntfile.js

In the Gruntfile, you are going to load the task before, I generally put it before the grunt.initConfig

grunt.loadNpmTasks('grunt-ember-templates');

Inside the grunt.initConfig you will need to set up the compile task to point at all the templates.

ember_templates: {
  compile: {
    options: {
      templateName: function(sourceFile) {
        return sourceFile.replace(/app\/templates\//, '');
      }
    },
    files: {
      "<%= yeoman.app %>/scripts/templates.js": ["<%= yeoman.app %>/templates/**/*.handlebars"]
    }
  }
},

Next tell the watch command to look for changes in the templates directory to make the live reload work correctly:

watch {
  ...
  ember_templates: {
      files: '<%= yeoman.app %>/templates/**/*.handlebars',
      tasks: ['ember_templates']
  },
  ...
}

Lastly, add ember_templates to the server task, you are looking for this line:

grunt.registerTask('server', function (target) {
    ...
    grunt.task.run([
        ...
        'compass:server',
        'ember_templates', // Add this line.
        'livereload-start',
        ...
    ]);
});

Once you restart grunt server, you can take a gander at the app/scripts/templates.js file in scripts. It should look something like this:

Ember.TEMPLATES["index"] = Ember.Handlebars.template
...

Add that script to the index.html file to make sure the browser loads it.

<script src="scripts/templates.js"></script>

That was kind of a detour, you don’t really need to set up ember_templates, you can use inline script tags or Em.Handlebars.compile, but this method offers a nice separation of HTML and javascript. For a quick reference you can see the completed Gruntfile here.

Application

The last step here will be to set up a simple App and Router to take advantage of our setup.

You can add the main.js to the end of index.html and delete whatever is in that file.

<script src="scripts/main.js"></script>

Next set up a rootElement for Ember to use, this will make sure that Ember puts the html where you want it to. Replace the div with the class container with:

<div id="app"></div>

Next add a simple Application to main.js:

App = Em.Application.create({
  rootElement: $('#app'),
});

You can then edit index.handlebars with a simple h1

$ echo "<h1>My App</h1>" > app/templates/index.handlebars

When grunt reloads the server, your browser will have My App as the header. There is a little magic going on here. Ember is creating a Router for you and by default creates and Application Route and an Index Route. This is why just adding an index.handlebars works.

The Router is dead simple to set up as well. In main.js add

App.Router.map(function(){
  this.route('about');
});

And then create the about template

$ echo "<h1>About</h1>" > app/templates/about.handlebars

If you navigate to /#/about, boom, you are now in the About route. You can also link to the about page from index by adding:

{{#linkTo "about"}}About{{/linkTo}}

This all works based on naming conventions. You can create an AboutController, AboutRoute and AboutView, but Ember will take care of that for these simple routes. More on that later.

Recap

Setting up Ember is a lot of boiler plate code, and there are some really good tools out there that do it for you. Nothing I have described above is earth shattering, but it should get you set up for your next Ember project.

I put the complete demo on Github for reference you can find it at github.com/screeley/ember-demo-environment.

For our next post in the Ember series, we will go into Ember basics; Views, Routing and Outlets. Stay tuned.

- Sean

Discuss on Hacker News

Posted 1 year ago by screeley
Embed This

We launched a redesign of our website and developer dashboard yesterday to showcase the three new products that we’ve been working on: Embed, Extract, and Display.

image

After countless bug fixes and beta testing for ages, we created the three products with your feedback in mind. Today Embedly graduates from embedding content on the web to providing you with tools to build a better user experience. Developers have made us the largest embedding platform on the web. We’re serving half a billion API requests per month to over 15,000 developers who have signed up for our service.

The classic embedding you all know and love is Embed. Digging deeper into articles to reveal the important information is Extract. And Display helps make your images appear beautifully within your website. A short blurb on what each product is made of that doesn’t do them justice, but we’ll do it anyway:

  • Embed: Get the world’s most powerful tool for embedding videos, photos, and rich media into websites.
  • Extract: Use the elements-colors, text, keywords, and entities-that you want from articles. Discard the rest automatically.
  • Display Make the images you use look great-and display quickly-on any screen, every time.

These products are only the beginning of a new chapter for Embedly. We want to provide the tools that developers need to build richer, more engaging sites. The products are separated because we think it makes sense for you to pay for what you use, not what you don’t. Moving forward, we’ll continue looking out to see what is possible, and hearing what our customers need. We’ll build what you’re looking for and what developers are scouring the web for in frontend development. We won’t stop until it’s all here, for you to use.

Posted 1 year ago by ninerr
Embed This

As an intern, I tend to get extremely excited about the little things, those things that others in the office are pretty used to after some time. This on the other hand, is no little thing. We’re pretty pumped about the kinds of things you can build with machine learning and text analysis. So much so that we’re sponsoring the Boston NLP/ML Hackday in a couple of weeks.

Boston NLP/ML Hackday is a single day hackathon centered around NLP/ML and Elasticsearch with free food and exceptionally interesting folks in attendance. The event will be hosted by Elasticsearch, co-sponsored by Traackr and space will be provided to us thanks to Hack/Reduce. If you’re into it, that’s great, because we are too. Join us on March 16 from 9AM to 9PM in Cambridge. Registrations are limited so mosey your way on over to the eventbrite page before that other hacker does.

Eventbrite: http://elasticsearchbostonnlphackday-es2004.eventbrite.com/?rank=1

But wait…there’s more.

Over the last several months we’ve written a classifier to determine if a URL is an article or not, and a related articles engine based on LSI Topic Modeling. We’ve also included entity and keyword extraction, and language detection in the API. Along the way we wrote a parser for articles, easily allowing one to pull the content from any article - an essential step when performing any sort of text analysis on a corpus of web articles.

All of these features will be available to use at the Hackday, and we’ll be helping out, giving tips and advice using the tools. Hope to see you there!

Posted 1 year ago by embedly-team
Embed This

Colors!

Happy Valentine’s Day! Whether you’re living it up with your significant other, making out in public, or planning which pint of Ben & Jerry’s ice cream you’re going to be shoveling down while watching the Notebook tonight, alone, we can all agree that this day has one awesome mood booster for all, which is the fabulous color of red. 

Red, commonly associated with passion, fire, beauty and sometimes communism (but we won’t talk about that), has earned it’s highly coveted title as the color of love. Now what’s all this jibber jabber about love and caring, we’re an API company with better things to do than canoodle around with colors that exude feelings? Wrong! We are huge fans of color and that’s why we’re going to show you what you can do with it, using one of our nifty features, conveniently named, Colors.

The feature itself provides our users with the ability to extract up to 5 dominant colors in any given image. Such a simple outcome but the necessity of it is key. Colors play an extremely important role in user satisfaction and retention on a web page. Colors relay emotion and can very easily make something a lot more interesting. If you’re not using colors then you’re probably doing something wrong. Furthermore, understanding which one’s to use when creating something, so as to match your given color options, can be tricky and that’s where our feature comes into play.

Now for the fun part, John, our genius color man, located all the trending images under the color red and we decided to go with the cliche Valentine’s Day images so as to encourage you to be a little bit more cheesy today. Happy Vday, enjoy!

Image Credits: Instagram, Designbolts.com, Flickr, Ow.ly

Check out the feature here and email support@embed.ly for some Beta access.

Posted 1 year ago by embedly-team
Embed This

We came, we saw, we hacked…along with an office full of excited hackers at  DowncityJS in Providence, RI this past weekend. Huge thanks to Betaspring for hosting, Chris Meiklejohn of Basho and all the other sponsors.

A great crowd came out on a chilly weekend to see what hackers from as far as DC could conjure up in a mere 24-hour JavaScript Hackathon. One of the standout projects, David Trejo put together a simple and easy to use color identifier with some surprisingly useful features called Colorslice. Our own Art Gibson created, Grillin Mah Bus, a real time feed which tracks social media interactions of people on a public transit bus.

We provided our API for the event and some prizes for best use of our API as a solo participant and as a group, we were pleased with the outcome!

The winners?

Best use of our API: Cheer Me Üp, a service which allows you to send a friendly and uplifting message to someone having a tough time. They’ll receive it with cat gifs and all, embedded from sites like Tumblr and Reddit using the Embedly API.

Best Solo: Thom Nichols for Xirq.us, they used Embedly to embed photos and media within curated tweets by the location they’re near to let you know in one convenient spot what exactly is going on in an area.

Best Design: Aaron and Aaron created Meet, a dating app that won’t allow you to talk to your match before meeting up with them, it cuts to the chase by only providing the option to meet your match.

Best Team: Ryan Laughlin, Liz Neu, and Kyle Nichols for Thumbwar, which allows users to sync up with a friend over mobile, tablet or laptop connection to play a bundle of mini games with each other to pass the time or to unleash that competitive side if only for a few seconds.


The bottom line is, we had a blast! The four of us, Art, Andy, Kawan and myself enjoyed an engaging and often silly weekend with some new friends and replenished our creativity tanks.Shout out to Gabe, Giles, Samuel, Graham and Vinh 
of Cheer Me Üp and Aaron and Aaron for Meet. We’re looking forward to seeing the real thing and will definitely be sending some pleasant messages to some unsuspecting mopes.

 

Posted 1 year ago by embedly-team
Embed This

Hackers, makers, and designers in Providence, we’re pumped about DowncityJS this weekend.  DowncityJS is a 24-hour hackathon in Providence starting on Saturday and going into Sunday. 

We love using javascript in our applications. In particular, we use NodeEmberjs, and D3, and build it all with Yeoman.  What else do we love about JS? Everything is async.  Also, you can close the gap in the creative process- you change something and immediately see the results. 

Andy, Art, Nina, and I will be coming from the Embedly team.  We’re happy to help out if you want to play with the API, from throwing around ideas to pro-tips.  

Embedly does all the parsing for you, pulling relevant information for embeds given any url.  You can get started by taking a look at some of our endpoints, in particular the power that is objectify. One of my favorite features is the Article Extractor, which parses an article or blog post given a url.   This is great for getting tons of articles ready for some heavy NLP.  Play with the article and media links in your Twitter stream. The best part is that everything supports JSONP, so you can easily build beautiful JS client heavy apps. 

Oh yeah, one more thing.  There will be several special features you can use that we will talk about at the hackathon, so swing by and get a sneak peek.

Update: I’m bringing a Kinect and Andy will be bringing a helicopter. 

Posted 1 year ago by embedly-team
Embed This