Skip to content

Instantly share code, notes, and snippets.

@tav
Created December 18, 2010 13:48
Show Gist options
  • Save tav/746520 to your computer and use it in GitHub Desktop.
Save tav/746520 to your computer and use it in GitHub Desktop.

At the heart of it, the site is very much like Twitter. You type your message, press enter, and boom! It appears in the stream of everyone who is following you.

Well, it's a lot better than Twitter because your messages actually get sent in real-time. No need to click or refresh the page, new messages simply appear like with chat/IM.

There's also a separate "To:" field like with email. Here you can state that the message is to a:

  • specific user, e.g. @olasofia
  • public space, e.g. #espians
  • controlled space, e.g. +family

This simple addition, combined with the ability to trust people for specific spaces (Trust Maps), means that you can limit spaces to only contain messages from those that you trust.

So if I only trust @evangineer for the #bigsociety space, I'll see messages from him when I look at #bigsociety, but won't see what he's sending to spaces I don't care about, e.g. #android.

In each space, you can also switch to seeing messages from everyone and browse everyone else's Trust Maps to discover others that you might want to add to your own Trust Maps.

It is worth noting here that we take a fairly unique approach to privacy control. Instead of marking your messages as public or private, privacy is determined by where you send messages to.

Everyone can send messages to and see messages sent to public spaces, e.g. #bigsociety. The style of public space names was chosen to be similar to Twitter #hashtags and IRC #channels.

However, we also introduce a new type of space, a "controlled" space. These spaces can be created by anyone and access to them is determined by whether you have an appropriate "access key".

These access keys specify whether you can:

  • send a message to the space
  • read messages sent to the space
  • delete messages from the space
  • set admin options for the space
  • send messages to a space as another specific user

And any constraints on its validity, e.g.

  • it can only be used N number of times
  • it has to be used before a specific date/time

These access keys are both revocable and transferable. That is, once someone gives you one, it can be revoked whenever they want — but you can also give it to someone else if you want.

Access keys enable a range of different setups. For example, you might give paying subscribers access to read messages from a space, but limit the ability to send messages to just yourself.

In fact, the individual @spaces, e.g. @jeffarch, are just very special controlled spaces. By default, the respective user has an access key with all the privileges.

And whenever they connect with anyone (e.g. adding them to a Trust Map), they give the other user an access key to send messages to their @space.

The @space also has an admin option set to allow those without access keys to also send messages to it if they pay the amount (in Amp Creds) set by the user.

So, if I'd set the option to 0.2 Amp Creds, then whenever someone whom I'm not connected with sends a message to @tav, they'll have to pay 0.2 Amp Creds.

The idea behind this is to:

  • provide an effective anti-spam protection
  • enable people's attention to be really valued

For now, the @space names are global. That is, whenever anyone refers to @jeffarch, they all mean the same @jeffarch. However, all other controlled spaces are not global.

Instead, they are unique to each individual user and represented with a leading plus sign, e.g. +family. People can call these spaces whatever they want — including the ones that others give them access.

And in addition to the respective @space, a number of default controlled spaces are created for a user:

  • +drafts
  • +settings

The +drafts space is used to auto-save your messages as you're writing them in case your browser crashes. And +settings is used to store your various custom settings.

You can view multiple spaces at the same time thanks to a very useful user interface innovation that thruflo has termed "dolumns" — dynamic columns.

This is a bit like the columns on TweetDeck which allow you to see multiple spaces at the same time, but with the ability to re-arrange and minimise them with ease.

The number of spaces you can see at any one time is dependent on your screen size which is auto-detected — but works well on everything from iPhones to 27-inch iMacs.

Now that spaces are hopefully a bit clearer, let's switch focus back to messages. Your messages don't need to be just plain text. For starters the following are auto-linked for you:

All shortened links, e.g. http://tinyurl.com/24ot9no are automatically expanded so that you know where they lead to and warnings shown for sites on the Google Safe Browsing blacklist.

All links to music, photos, videos and info on the following sites are specially marked so that you can view them without having to leave the site:

  • Flickr
  • GitHub
  • Skitch
  • SoundCloud
  • TwitPic
  • Vimeo
  • YouTube

All linked mp3 and video files (including SoundCloud recordings and YouTube videos) can be queued up to be played in the builtin media player.

Similarly, PDF and Powerpoint links can be viewed inline using the Google Docs viewer without having to separately download and open them.

You can also directly attach rich data to your message:

  • Files up to 2 gigabytes in size. If these are image files then a thumbnail is automatically created for them.
  • Geolocation — you can specify the exact location (latitude, longitude) by dropping a marker on a Google Map.
  • Date/time which can be described in a number of natural languages, e.g. "next Friday" and is fully aware of timezones with daylight saving adjustments, etc.
  • Number value, e.g. 1.61803398874989
  • Currency value, e.g. ¥500
  • Transboolean value, i.e. yes/no/maybe
  • List and choice values.
  • Rich text up to 100 kilobytes in size.
  • Links — which automatically show the title, description and let you choose a preview image just like on Facebook.

Besides attaching these values to a message, you can also use those values to define an "aspect" of something. These aspects are denoted with a leading slash, e.g. /price.

And you can make up whatever /aspect you like, e.g.

/need
/offer
/intention
/like

This simple addition enables people to define structured data really easily, e.g.

/intention Take a break somewhere warm.

/price £14.00

/need Some advice on sound setup for recording voice-overs.

In fact, much of the functionality of the site is implemented by using /aspects behind the scenes. For example, when you trust someone for a specific space, you're actually doing something like:

/trust <#literature> @sbp

The <about> can be left out normally. By default, it's assumed that you are defining an /aspect about the space you're sending the message to, i.e. if I send a message to #literature, it can just be:

/trust @sbp

You can define aspects about #spaces, @users, http/https links and even specific messages! You can refer to a specific message by using the special amp link style, e.g.

~tav/2491

This is constructed by using the tilde sign followed by the username of the sender and the unique numeric id associated with each message.

But since numbers are not necessarily easy for most of us to remember, you can also create "named links" which can point to a specific message, e.g.

~tav/some-article  ->  ~tav/2491

Not only does this make it easier to remember, but since named links can be updated, you can use it to point to updated content (i.e. another message) in the future.

This is complimentary to the fact that messages are versioned and you can redirect them to new versions. You can quickly correct typos in your previous message with a new one saying:

s/complimentary/complementary/

Instead of sending a message with that text, it will instead send a message with the fixed-up content of your previous one and set a redirect on your previous message to the new one.

Now, as you might have guessed, you can also refer to named links in your messages and define /aspects about them, e.g.

/intention <~tav/books> read the Abyssinian Moon by @sbp

/location <~lcl/party> 42 Brick Lane, London

For bonus points, you can connect your Facebook and Twitter accounts and have the option of cross-posting individual messages to any of those accounts.

Note however that we allow messages to be up to 1,000 bytes long which is compatible with Facebook but not with the 140 character limit on Twitter.

Connecting your external social network accounts also enables you to see those on the site who you're already connected to on Twitter and Facebook to further help with discovering people.

And when browsing, in addition to the usual message view, you can also render the messages using custom views:

  • calendar view
  • map view
  • network view
  • trend view

The calendar view shows items in an easy to use calendar setting and also generates output in iCal format so that it can be used with Google Calendar, etc.

There's also a builtin app which provides an easy way for groups of people to decide on the best time for everyone to attend an event, e.g. a meeting.

This app is aware of timezone differences — so confusions over the right time for international meetings can hopefully be a thing of the past. It also provides a helpful countdown too, e.g.

6 hours and 23 minutes left before the meeting.

The map view plots the items on a Google Map and includes a cool "auto-zoom" functionality, which zooms up/down from your map's centre to find the level with the adequate number of results.

We also support voice search on the map view which lets you do searches using voice in some browsers — which can be useful on your mobile when you're on the move.

The network view shows a pretty network timeline similar to GitHub's network graph:

The intention behind this view is to enable Confluence by helping people to see how their intentions are evolving and aligning around conditions over time.

The trend view shows useful statistics about what's trending right now. Unlike Google trends, this is personal to you and those that you trust and is also used to prioritise the various autocompletion fields in the user interface.

You can affect what's trending through your interactions on the site and you can help the works of others to trend by "amping" their messages.

This is a bit like retweeting on Twitter, but works a little better. By amping a message, you combine three actions into one:

  • re-send a message into different spaces
  • attach your own comment to the message (optional)
  • allocate some Pecus to those who created and amped the message

By default, one of your Pecus is allocated to the creator of the message and 0.5 Pecus are equally split amongst everyone who amped the message before it reached you.

You can configure this in settings and you can do Pecu payouts using PayPal to everyone who you've given Pecus to. Note: you can only payout to users who've connected their PayPal accounts.

You can view the top and trending links in a space for the last day, week and month. However, to act as a dampener against the "Top 40" effect, any amping that results in following a link from this view is not incorporated in the top list.

You can filter spaces using a search mechanism. In fact, the entire site is built on top of a powerful search system. So when you look at say #espians, you're actually doing a search for:

  • to:#espians

All search results get continuously updated in real-time and a number of search operators are supported:

  • simple keywords, e.g. bradley manning wikileaks
  • phrase searches, e.g. "inform 7"
  • to: operator, e.g. to:#espians
  • from: operator, e.g. from:@tav
  • aspect search, e.g. /intention
  • aspect comparison search, e.g. /rating ≥ 3

The different operators can be used together and the aspect comparison search is triggered if any of the following appear after an /aspect:

is    ==
>=    ≥     >
<=    ≤     <

And the special near and within can be used to do geo-queries, e.g.

café /location near ~tav/brushfield-riva

Or perhaps more specifically:

café /location near:200m ~tav/brushfield-riva

You can also specify near me which will use the Geolocation to find out where you are and use that to centre the results around you.

The search mechanism is clever enough to handle case differences in various languages. So when you search for "Straße", the results will also include messages with "strasse".

And on a related note, there is extensive support for Unicode. So you can write messages in whatever language you want and even have usernames in foreign scripts, e.g. @建国, @வாகீசன், etc.

You can also specify which languages you know and then messages in other languages will be automatically translated into your primary language for you!

And, finally, a key feature of the site is that it's extremely "programmable". This is enabled by the "rich text" that you can attach to your messages.

By default, any rich text is presumed to be a simple paste that you want to share with others. But if you start the text with a #! shebang line then it behaves quite differently.

The simplest one which does nothing to your content is:

#!raw

You can also include code in various programming languages and have them syntax highlighted, e.g.

#!code ruby

But the one that people are most likely to use is:

#!text

This means you can write articles using the a subset of the relatively popular Markdown syntax which also allows you to embed HTML directly into the text:

You can use most HTML tags and even a fair amount of CSS styles to present your content as you want to. You can create links like in messages using [[double square bracket]] syntax, e.g.

[[~tav/some-article]]

[[http://www.youtube.com/watch?v=WL5ud5_K-GY]]

[[#espians]]

And even define custom link text, e.g.

[[~tav/some-article | info about Ampify]]

Mathematicians will be pleased to know that they'll be able to embed equations using TeX/LaTeX formats and it'll be rendered correctly, e.g.

<div class="math">
  \[P(E) = {n \choose k} p^k (1-p)^{n-k} \]
</div>

There's also super cool support for {{transclusion}} to include content from other messages:

For example, to create a summary of an event, you could simply include the various messages with explanatory text, e.g.

#!text

The event started with John giving an introduction:

{{~john/78132}}
{{~john/78134}}
{{~john/78135}}

Nadine chipped in with a very insightful comment:

{{~nadine/6396}}

The messages inside the {{curly brackets}} will be rendered as they normally get rendered. You can render just the content or any attached value with, e.g.

{{~john/78132.content}}
{{~nadine/6396.value}}

You can also include specific sections from other texts, e.g.

{{~tav/some-article#intro}}

Or even specific lines, e.g.

{{~tav/some-article#L12-20}

Note that in these cases it'll be implicitly using the attached text value. In fact, behind the scenes, the above is being rewritten into a service call:

{{get-lines ~tav/some-article.value 12 20}}

And the plain:

{{~nadine/6396}}

Is actually a shortcut for the service call:

{{render ~nadine/6396}}

There are a fair number of builtin services, e.g.

{{convert $23 to: GBP}}

{{find from: @tav}}

You can mix them together by enclosing them in parentheses or putting them into a piped stream, e.g.

{{convert (get-value ~tesco/nutella/price) to: GBP}}

{{find from: @tav | translate $_ from: en to: fr | render}}

You can also use a markdown text as a template for another text, e.g. let's define a ~tav/blog-template:

#!text
----
title: Default Title
value: Blog Post Content
----

<h1>{{$title}}</h1>
<div>
  {{$value}}
</div>

This makes use of $variables, which can be passed in via service calls explicitly, e.g.

{{~tav/blog-template title: "Hello World" value: "Boo!"}}

If no variables are passed in, then it will try to use any default metadata found inside the triple-dashed section, i.e.

---
title: Default Title
value: Blog Post Content
---

The template can also be used by another text explicitly, e.g.

#!tav/blog-template title: $this.title value: $this.value
---
title: 7 Days of Templates
---

On the first day ...

Or even simpler by using the utility template service which will pass the variables in automatically:

#!template ~tav/blog-template
---
title: 7 Days of Templates
---

On the first day ...

You can also define your own services using the beautiful CoffeeScript syntax:

For example, to define a service that counts the number of words in a message:

#!coffee

main = (message) ->
    message.content.length

You can also call other services using the builtin call function, e.g.

call("~thruflo/count ~sbp/abyssinian-moon")

There are a number of other builtins, e.g.

open("http://inamidst.com/stuff/sappho/").read()

memcache.set("rate", 12.12)

send(message)

getUser()

Services using the more dangerous builtins, e.g. send which sends a message on the user's behalf, would need to first get an appropriate access key from the user.

Services can also be directly called from the message input box by prefixing the command with a full stop (period), e.g.

.convert ¥23 to: GBP

There's also the builtin help service which displays some help info for the given service:

.help convert

The help service also has a minimal shortcut:

? convert

The output of a service can be formatted differently when it's called via an {{include}} and when it's called from the message input box.

This is determined by the values for the /include-formatter and /command-formatter aspects respectively. You can point these aspects at other services or templates.

Some services may not have any display to format though, e.g. the .pause service which simply pauses what's currently playing on the builtin media player.

Now, all of this functionality is likely not going to be used by the majority of users, and the site will be more than useful for them without having to use these features.

But creating services and templates should hopefully be easy enough for the class of users who are not yet programmers but are comfortable making Excel spreadsheets and installing WordPress plugins.

For security, all interactions with the site happens over HTTPS, i.e. it's encrypted. This turned out to be quite a challenge as most APIs, e.g. Flickr, don't support HTTPS.

But, on the flip side, everyone can now use the platform without having to worry about attacks like Firesheep:

All image/form references except for those to trusted sites like Google Charts are also rewritten and proxied as part of the broader sanitation of user input against XSS attacks.

The whole site needs JavaScript to run, but the features are progressively enhanced and thus will work well on everything from the ancient IE 6 to modern iPhone/Android browsers.

And, to finish with, all user accounts have a usage quota in terms of the number of controlled spaces and sensors they can create and the total size (in gigabytes) of their messages and attached data.

@h4rrydog
Copy link

I really like this. Will comment more when I have digested all of this and think about the implications of what you are proposing. Awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment