getting social: defining the 'contacts' category

42 views
Skip to first unread message

Michiel de Jong

unread,
Mar 7, 2012, 5:05:17 PM3/7/12
to unhosted
Hi! After a long discussion in the chatroom (http://webchat.freenode.net/?channels=unhosted ) with Melvin, who pointed me to a lot of relevant considerations, i had a go at finally proposing a data format for the 'contacts' category.

Main considerations here are:
- a remark made by Bradfitz in 2007, that the social graph should be like git, not like svn (http://bradfitz.com/social-graph-problem/ )
- the concept from linked data, that we should always try to use global identifiers
- the desire that when you store a contact, collisions and duplicates should ideally be avoided automatically (more about this later).

So I'm turning vcards inside out. A 'contact', to me is a way of contacting a persona. Every person can operate various personas, and may or may not want those to be linked publically. But a person who knows various sides of you /will/ want to link those personas of you together in their addressbook. So we're not talking here about how you represent yourself online, this is about how others model you on their side - probably with a subset of the personas that you put out.

So there are various ways to contact someone (email, phone, facebook mesage, jabber, skype...), and each of these methods define an address namespace. A common way to do an address book is the 'bag of vcards' approach. In terms of linked data, that would also be a pretty standard approach: create documents as vcards, and link those documents together to get your addressbook. But i think we can do better than that.

We can get rid of both collisions and duplicates if we put each contact into the same key-value store, with '[contact method]:[id]' as the key. Instead of keying Full name -> vcard, which is how we often think of an addressbook, we can take advantage of the fact that each contact method will involve exactly one id per persona, and that we can easily list what valid contact methods exist. If we add two vcards that have the same email address on them, then they will automatically map onto each other, because they will map to the same key (mailto:user@host) in our contacts key-value store. This will save us a lot of searching through, and remerging duplicates.

So we do one item per contact, not one item per persona. and to make sure they can get glued together ('glue' in the sense of the Bradfitz blog post mentioned earlier), we add a 'sameAs' field into them. They can also have a 'rel' field, indicating the relation between the contact and its persona. And any info that you may want to have in an addressbook, but that doesn't represent a way of contacting someone, can go into an 'attr' field, which is more informational than functional. So for instance after importing this vcard:

BEGIN:VCARD
FN:Alice
TEL;type=CELL:+34-612345678
EMAIL;type=WORK:al...@example.com
END:VCARD


our contacts category will contain:

var contacts = {
  "mailto:al...@example.com": {
    "rel": "WORK",
    "sameAs": ["tel:+34-612345678"],
    "attr": {
      "FN": ["Alice"]
    }
  },
  "tel:+34-612345678": {
    "rel": "CELL",
    "sameAs": ["mailto:al...@example.com"],
    "attr": {
      "FN": ["Alice"]
    }
  }
};

What would happen now if i import a contact from another device that's got full name 'Mrs. Wonderland' but email address 'al...@example.com'? Exactly, it will correctly coincide, and map onto the existing contact. That's why i made contacts["mailto:al...@example.com"].attr.FN an array.

So what makes 'mailto:' and 'tel:' acceptable schemes here? What does 'mailto:' refer to in this context? I thought about that, and my answer is:

    an id space, in the sense that you can never get two unrelated contacts colliding on the same id, and you can never get duplicate id's for one and the same contact.

This id space should have the following meanings defined for it:
1- the authority chain for giving out and revoking identifiers in the corresponding namespace (in the case of email, that is defined through domain name registration, DNS records, mail server configuration, and ultimately the SMTP spec that defines things like 'User unknown at this host').

2- the authority (chain) for defining and regulating contact methods related to it (again, the SMTP spec, this time the part that defines message sending and delivery).

3- optionally, the authority (chain) for publishing public profile attributes about contacts.

So linked data says we can use document URLs as our URNs. If you ask people what the URN is for Mark Zuckerberg's facebook profile, the will likely give you a URL to a document that has the information you're looking for. All of the following documents refer to the same 'contact':
http://graph.facebook.com/4#
https://graph.facebook.com/4
http://www.facebook.com/zuck

I do not want to have all of those in my contacts list, they would be duplicates. So even though https uniquely defines document identifiers, it does not uniquely define facebook profiles. The best we could do is define https://graph.facebook.com/4# as the canonical one, so that would work, but what we really would be saying by that URN has much more to do with the substring 'facebook' than with the substring 'https' in there. It's facebook who give out and revoke id's in this contact namespace, it's facebook who define contact methods for it (facebook messages, facebook chat, ...), and it's facebook who are authorative to define the 5 or 6 attributes you get back when you query one of the above URLs. For none of these things, 'https' as the first part of that URN is relevant.

So by that reasoning, i propose to use key formats of the form [namespace]:[id], like:

    mailto:us...@example.com
    facebook:123456789
    tel:+1-123456789
    skype:alice123
    twitter:@unhosted

If there is a URL on a vcard, linking to someone's blog, that's not a means of contact. So we convert it to an attribute. I have started writing a few import scripts for this here:

https://github.com/unhosted/experiments/tree/master/liberator/static

and started consolidating my own friendslists from linkedin, gmail, facebook, and my old iPhone into one - quite fun! :) I'll write an app that displays everything nicely - the nice thing is that it will be able to pull in additional data about contacts wherever that's available, and display various avatars from different sources for the same persona into one interface, where you can then manage your contacts independently of the tool from which it was originally imported.

"Facebook and twitter are social tools. *We* are the social network." - Amr Gharbeia

I think we're on the right track with this, please reply if you think otherwise.


Cheers!
Michiel

elf Pavlik

unread,
Mar 7, 2012, 5:32:46 PM3/7/12
to Michiel de Jong, unhosted
Hi Michiel,

Sounds exciting!

Somehow I feel sceptical of mixing URI schemas like mailto: tel: sip: xmpp:
with facebook: twitter: etc.. some facebook account may also have mailto: and xmpp: enabled btw?

what if i use 50 different networks allowing private messaging? i should make up namespaces for them by trimming tld from domains? ;)

otherwise it looks very creative! last days I thought about starting to manage my 'contacts' (not friends) better, played a bit with vcards, researched a bit xml vcards and json vcards but your approach sounds interesting...

also with this sameAs, perpetua...@wwelves.org supports mailto: sip: xmpp: lets say on top of that you can also contact me over psyc: and elf-pavlik on irc.freenode.net and irc.indymedia.org

can you write an example of contacts to a fictional friend with all those channels and also mobile phone, land line, and 2 mailing addresses?

=)
~ elf Pavlik ~


Excerpts from Michiel de Jong's message of 2012-03-07 22:05:17 +0000:

Michiel de Jong

unread,
Mar 7, 2012, 5:57:55 PM3/7/12
to elf Pavlik, unhosted
On Wed, Mar 7, 2012 at 10:32 PM, elf Pavlik <perpetua...@wwelves.org> wrote:
Somehow I feel sceptical of mixing URI schemas like mailto: tel: sip: xmpp:
with facebook: twitter: etc..

yes, but it makes sense. because of some of my contacts i only have a twitter handle to DM to. that is twitter-specific, and i want to suport it. so no better name for it than calling it 'twitter' - the authority defining what a DM is for those contacts.
 
some facebook account may also have mailto: and xmpp: enabled btw?

yeah, so importing such a friend from facebook will result in three entries, glued together via their 'sameAs' fields. none of these is 'the real one' or 'the one to rule them all'. that's the way in which it's like git.
 

what if i use 50 different networks allowing private messaging? i should  make up namespaces for them by trimming tld from domains? ;)

well, there the previous remark is relevant. suppose for a minute that all facebook accounts have smtp and xmpp, and that you can get their profile wall through ActivityStreams over PuSH, and that there are no features you that you miss out on if you have all those. then we can get rid of the 'facebook:' contact type.

for instance, for my linkedin contacts i just used vcard export, which contains a 'mailto:'. so unless you are really into InMail messages, there is no need to use a 'linkedin:' namespace specifically.
 
otherwise it looks very creative! last days I thought about starting to manage my 'contacts' (not friends) better, played a bit with vcards, researched a bit xml vcards and json vcards but your approach sounds interesting...

i think vcards are the wrong way around; importing contacts from one source may incorrectly merge with vcards of another source, so you get infinite collisions and duplicates. it's much cleaner to keep it keyed per contact method namespace, and do the glue on top of that.
 
also with this sameAs, perpetua...@wwelves.org supports mailto: sip: xmpp: lets say on top of that you can also contact me over psyc: and elf-pavlik on irc.freenode.net and irc.indymedia.org

can you write an example of contacts to a fictional friend with all those channels and also mobile phone, land line, and 2 mailing addresses?

so there will be 10 entries, you can either refer to all 9 others in each one, or you could create a ring and consider 'sameAs' to be transitive. either way, when you retrieve one of them, you can traverse to the other 9 and pull up a really complete addressbook card.


cheers!
Michiel

Thad Guidry

unread,
Mar 7, 2012, 10:57:07 PM3/7/12
to unho...@googlegroups.com

So by that reasoning, i propose to use key formats of the form [namespace]:[id], like:

    mailto:us...@example.com
    facebook:123456789
    tel:+1-123456789
    skype:alice123
    twitter:@unhosted


Your absolutely on the right track.  And exactly what you should be doing with namespace and id. 

--
-Thad
http://www.freebase.com/view/en/thad_guidry

Jan Wildeboer

unread,
Mar 8, 2012, 5:19:03 AM3/8/12
to unho...@googlegroups.com
On 08.03.2012 04:57, Thad Guidry wrote:
>
> So by that reasoning, i propose to use key formats of the form
> [namespace]:[id], like:
>
> mailto:us...@example.com <mailto:us...@example.com>

> facebook:123456789
> tel:+1-123456789
> skype:alice123
> twitter:@unhosted
>
>
> Your absolutely on the right track. And exactly what you should be
> doing with namespace and id.

Hm. namespces with trademarks. Might become a problem sometime i n the
future. What happens when facebook renames itself to facealbum in the
future?

Or what about identi.ca, which is just one *service* running on the
status.net *protocol*?

I think it needs some careful thought wrt namespace definitions and updates.

Jan

Melvin Carvalho

unread,
Mar 8, 2012, 5:20:50 AM3/8/12
to unho...@googlegroups.com

Uniqueness is one good property to have.  The second good property to have is linkability.  That's why we try and use HTTP(S) identifiers whenever possible.  Your system is only as strong as it's identifiers.

http://inkdroid.org/journal/2010/06/04/the-5-stars-of-open-linked-data/

You can rate yourself on the scale above.  Getting that 5th star is the hardest, but that's where we need to go to be playing in the same park as the likes of facebook etc.
 

Michiel de Jong

unread,
Mar 8, 2012, 6:02:21 AM3/8/12
to unho...@googlegroups.com


On Thu, Mar 8, 2012 at 10:19 AM, Jan Wildeboer <j...@wildeboer.net> wrote:
Hm. namespces with trademarks.

the namespace in front of the identifier defines "who decides what this identifier means?".
 
Might become a problem sometime i n the future. What happens when facebook renames itself to facealbum in the future?

then ideally we should update that name. that probably won't happen though. openssl was never renamed to opentls. window.navigator was never renamed to window.browser. But i think your point is not so much about name changes, but about the face that we're recognizing facebook as a commercial company to define what it means for a person "to be on facebook". I think that's just calling things by there name. 
 
Or what about identi.ca, which is just one *service* running on the status.net *protocol*?

ah, so that's a good example. So there, my identifier '@michiel...@identi.ca' doesn't relate to "what it means to be on identi.ca", but what it means "to be on an instance of a StatusNet-compatible service", or even, "to be on an instance of an OStatus-compatible service".

The question is who gets to change the meaning of these identifiers in the future, and what name would best represent the continuity of that changed meaning. it's also about how a service presents its api to the outside.

Gmail says: interact with us using smtp.
Facebook currently still says: interact with us in a facebook-specific way.

it would be nice if they would, in their graph api, display 'services: smtp, xmpp, ...'. it would be even nicer if they would use webfinger to announce this. if next year they do, then importing your friends from facebook can be just like importing the VCARDs you get out of services like LinkedIn and Google, or importing the webfinger records you get out of StatusNet and Diaspora.

as long as facebook says 'this identifier is whatever facebook defines it to be' instead of 'we will announce the available services for this identifier via webfinger', we'll have to write them into our addressbook as such.

the contacts list just writes down in the most descriptive and usable way possible which contacts you have imported into it. if you choose not to import any facebook contacts, then you will not see them. but if you do, then presumably your expectation is that they are compatible with whatever facebook dictates about those contacts.
 
I think it needs some careful thought wrt namespace definitions and updates.

yes! and it's fun as well, i think :)


Cheers,
Michiel

Michiel de Jong

unread,
Mar 8, 2012, 6:15:04 AM3/8/12
to unho...@googlegroups.com
On Thu, Mar 8, 2012 at 10:20 AM, Melvin Carvalho <melvinc...@gmail.com> wrote:
Uniqueness is one good property to have.  The second good property to have is linkability.

i agree
 
That's why we try and use HTTP(S) identifiers whenever possible.

i don't agree. where's the cause-and-effect there? as i explained, using some URL from facebook's api, which points to a /document/ about the identifier we are really talking about, and on top of that, one of possibly multiple documents about that identifier, and even one of possibly multiple URLs that lead to that document, is throwing out the baby with the bath water. it kills our chances of maintaining the uniqueness we had in the identifier, and it kills our chances of linkability.

Your system is only as strong as it's identifiers.

http://inkdroid.org/journal/2010/06/04/the-5-stars-of-open-linked-data/

You can rate yourself on the scale above.  Getting that 5th star is the hardest, but that's where we need to go to be playing in the same park as the likes of facebook etc.

we've got the 5 of them as soon as we transfer this thread to the wiki. except arguably the first one; we're not making people's user data available on the web in general, but it's available on the web /to them/.

it's JSON (point 2), inside the data object that our apps will store on people's remoteStorage, we'll put a link to the page describing their data format (point 4). we'll wave any rights to ever make that format proprietary (point 3; probably putting it on our W3C CG wiki is enough for that). and on there, we'll do the same as we do in the remoteStorage spec, we link the short names to URLs. so we'll specify 'facebook' means 'https://graph.facebook.com/docs/whatever'.

Why put it on the wiki and not hard-code it into the data? because if facebook changes their naming strategies and decides to deprecate graph.facebook.com for timeline.facebook.com, we'll have only one place where we'll have to change that. inside everybody's data, we don't want to hardcode any http(s) URLs if we can avoid it.

Melvin Carvalho

unread,
Mar 8, 2012, 6:38:36 AM3/8/12
to unho...@googlegroups.com
On 8 March 2012 12:15, Michiel de Jong <mic...@unhosted.org> wrote:


On Thu, Mar 8, 2012 at 10:20 AM, Melvin Carvalho <melvinc...@gmail.com> wrote:
Uniqueness is one good property to have.  The second good property to have is linkability.

i agree
 
That's why we try and use HTTP(S) identifiers whenever possible.

i don't agree. where's the cause-and-effect there? as i explained, using some URL from facebook's api, which points to a /document/ about the identifier we are really talking about, and on top of that, one of possibly multiple documents about that identifier, and even one of possibly multiple URLs that lead to that document, is throwing out the baby with the bath water. it kills our chances of maintaining the uniqueness we had in the identifier, and it kills our chances of linkability.

Your system is only as strong as it's identifiers.

http://inkdroid.org/journal/2010/06/04/the-5-stars-of-open-linked-data/

You can rate yourself on the scale above.  Getting that 5th star is the hardest, but that's where we need to go to be playing in the same park as the likes of facebook etc.

we've got the 5 of them as soon as we transfer this thread to the wiki. except arguably the first one; we're not making people's user data available on the web in general, but it's available on the web /to them/.

I guess the first star is the starting point, from there the others follow.

Why do you say the data is not available on the web? 
 

N Nil

unread,
Mar 10, 2012, 5:59:22 AM3/10/12
to unho...@googlegroups.com

So by that reasoning, i propose to use key formats of the form [namespace]:[id], like:

    mailto:us...@example.com
    facebook:123456789
    tel:+1-123456789
    skype:alice123
    twitter:@unhosted


How about giving those questionable keys (those based on platform names / trademarks, not protocols), a prefix, like it's done with non-standard HTTP and Mail headers? e.g. x-twitter:@unhosted. Additionally, if those were required to be postfixed with the actual service hostname as well (e.g. x-twitter:@unhosted@twitter.com), people could choose to implement a "clone" of the twitter api (no idea if this is legal or even a good idea. It's just an example), and end up with something like "x-twitter:@unhosted@my-twitter.clone".
To summarize:
* the "x-" prefix would identify a protocol, which has been defined by some party, but not through an open process.
* the hostname part of the id makes the id globally unique (within the x-something namespace).
* in cases such as twitter, the hostname could be ommitted, which makes it fall back to a protocol-default (such as <id>@twitter.com)

What do you think?

Michiel de Jong

unread,
Mar 10, 2012, 7:27:09 AM3/10/12
to unho...@googlegroups.com
i like it! point 3 could be done in the user interface, doesn't have to be done in the data format. we just start storing our twitter contacts as 'x-twitter:'+handle+'@twitter.com' and then we have every opportunity to extend that later.

also, i think we should always store multiple contact items wherever multiple contact methods exist. just with a sameAs to link them all together. that way, providers who follow all the standards will produce contacts like mailto:, xmpp:, sip:, and maybe also an x-provider: one, but that would then become much less important, and almost informational. it all depends how often you need access to provider-specific features. if it's just retrieving an atom: feed or sending an xmpp: message, and the provider's api happens to adhere to the standard for that, then you can use the generic contact item, and never even have to worry much about the prorietary one.

Manuel Strehl

unread,
Mar 10, 2012, 8:36:23 AM3/10/12
to unho...@googlegroups.com
Sorry to jump into the middle of a discussion, but the "x-" prefix suggestion triggered my response.

Currently such kinds of prefixes are combatted against on all fronts. From HTTP and SMTP,
http://tools.ietf.org/html/draft-ietf-appsawg-xdash-02
where the IETF tries to get rid of X-prefixed headers, to CSS,
http://hsivonen.iki.fi/vendor-prefixes/
and the discussion in the W3C WG and around.

The baseline is, that prefixing stuff this way hampers compatibility and extensibility more than aiding it. It boils down to the "x-" suggesting, that talking and specifying are unnecessary, which comes back later when there are more than one successful applications in that realm.

Just my 2c and only remotely connected to the actual topic.

Cheers,
Manuel


Am 10.03.2012 13:27, schrieb Michiel de Jong:
On Sat, Mar 10, 2012 at 10:59 AM, N Nil <nil.n...@gmail.com> wrote:

So by that reasoning, i propose to use key formats of the form [namespace]:[id], like:

    mailto:us...@example.com
    facebook:123456789
    tel:+1-123456789
    skype:alice123
    twitter:@unhosted


How about giving those questionable keys (those based on platform names / trademarks, not protocols), a prefix, like it's done with non-standard HTTP and Mail headers? e.g. x-twitter:@unhosted. Additionally, if those were required to be postfixed with the actual service hostname as well (e.g. x-twitter:@unhosted@twitter.com), people could choose to implement a "clone" of the twitter api (no idea if this is legal or even a good idea. It's just an example), and end up with something like "x-twitter:@unho...@my-twitter.clone".
To summarize:
* the "x-" prefix would identify a protocol, which has been defined by some party, but not through an open process.
* the hostname part of the id makes the id globally unique (within the x-something namespace).
* in cases such as twitter, the hostname could be ommitted, which makes it fall back to a protocol-default (such as <id>@twitter.com)

What do you think?

Michiel de Jong

unread,
Mar 10, 2012, 8:50:35 AM3/10/12
to unho...@googlegroups.com
On Sat, Mar 10, 2012 at 1:36 PM, Manuel Strehl <bold...@googlemail.com> wrote:
Just my 2c and only remotely connected to the actual topic.

it's a really good point, actually! we can first explore how far we get using only the open standards - which might be further than one might think at first glance.

the particular application i'm looking at right now is sending Opentabs.net IOUs to facebook-contacts. given that facebook chat is addressable as xmpp, and facebook messages is addressable as smtp, i might not even need to import facebook contacts as any thing else than an email address + a jabber id. if i start with that, then we can delay this question until a later point, when maybe we have a better view of what we need and how and why, and whether or not there should be an 'x-' in front of it etcetera.

thanks!
Michiel

Thad Guidry

unread,
Mar 10, 2012, 9:44:49 AM3/10/12
to unho...@googlegroups.com
Michiel,

Is the plan to support all the vCard properties ?  I didn't hear mention of "org".  What if I have 3 "rel" of type "WORK" ?

Let's say hypothetically, that I work for 3 companies or "org".  Mine company and 2 others.  With all 3 of them, I have at least 2 methods of "contacting" me, a tel. phone number and a unique email address.

You only know me through my WORK involving the org "Thad's BIG Company Ltd." and not the other 2 companies.  The domain of the email address is there, but perhaps for "Thad's BIG Company Ltd.", I only have a phone #.

Michiel de Jong

unread,
Mar 10, 2012, 12:49:06 PM3/10/12
to unho...@googlegroups.com
org is an attribute, not a contact item. it will be displayed so that you know you have the right "David", just like the avatar, full name, birthday, etcetera. But it's not a contact method.

nil

unread,
Jun 19, 2012, 4:18:39 AM6/19/12
to unho...@googlegroups.com
As far as we have discussed this now (mostly in the channel and in
RL), we have settled on using JSON representations of hCards/vCards,
called jCards, pretty much like http://microformats.org/wiki/jcard.
Those can (for example) be generated with the vCardJS[1] library.

Now as there's been some talk about using JSON-LD at various points,
we should probably think about using that in the contacts category as
well. There seems to be a @context for people[2]. We could just use
that. I have only scanned through that briefly, and am not sure yet,
whether all info from vCards can be mapped to person.jsonld (and/or
vice versa). But to me JSON-LD seems more sophisticated than jcards
(which are only very loosely defined).

Anyone else any thoughts?

[1]: https://github.com/nilclass/vcardjs
[2]: http://json-ld.org/contexts/person.jsonld

Michiel de Jong

unread,
Jun 19, 2012, 6:10:42 AM6/19/12
to unho...@googlegroups.com
with the new 'modules' concept for remoteStorage.js, the data format
has to be understood by the javascript module. so it makes sense to
use the module version as the context.

i'm playing around with this, here:

https://github.com/unhosted/remoteStorage.js/tree/v0.7/src/modules/tasks/0.1

so the idea would be to define a 'contacts' module, that gets loaded
with remoteStorage.loadModule('contacts', '0.1', 'rw'); and after that
you can call remoteStorage.contacts.add(...)
remoteStorage.contacts.search(...), etcetera.

to me, using json-ld means adding @context, @type and @id into
objects. this does not clash with using the proposal of using the
vcardjs format to serialize vcards.

but since the code module and the data format can go together, as long
as you make sure to always set the @context field correctly and
specifically to the exact version of data format expected, and provide
a remoteStorage.contacts.importVCard(..) function in the contacts
module, you can use any on-storage format you like.

Thanks to the modules, apps can be agnostic of the on-storage format.

nil

unread,
Jun 19, 2012, 6:34:53 AM6/19/12
to unho...@googlegroups.com
On Tue, Jun 19, 2012 at 12:10 PM, Michiel de Jong <mic...@unhosted.org> wrote:
> with the new 'modules' concept for remoteStorage.js, the data format
> has to be understood by the javascript module. so it makes sense to
> use the module version as the context.

I see, so we're defining new "@context"s anyway. Good to know.

>
> i'm playing around with this, here:
>
> https://github.com/unhosted/remoteStorage.js/tree/v0.7/src/modules/tasks/0.1
>
> so the idea would be to define a 'contacts' module, that gets loaded
> with remoteStorage.loadModule('contacts', '0.1', 'rw'); and after that
> you can call remoteStorage.contacts.add(...)
> remoteStorage.contacts.search(...), etcetera.
>
> to me, using json-ld means adding @context, @type and @id into
> objects. this does not clash with using the proposal of using the
> vcardjs format to serialize vcards.
>
> but since the code module and the data format can go together, as long
> as you make sure to always set the @context field correctly and
> specifically to the exact version of data format expected, and provide
> a remoteStorage.contacts.importVCard(..) function in the contacts
> module, you can use any on-storage format you like.
>
> Thanks to the modules, apps can be agnostic of the on-storage format.

Right. But they won't be agnostic of the format that
contacts.search(...) etc. return. So the question here is, whether
that would be vCard based keys:
Example: { "fn": "Michiel de Jong", "n": { "given-name": "Michiel",
"family-name": "de Jong" } }
or person.jsonld based keys,
Example: { "name": "Michiel de Jong", "givenName": "Michiel",
"familyName": "de Jong" }
or something else. I don't know what most people are comfortable with.
vCard attributes are shorter in general, but less obvious (e.g. fn is
neither first nor full name, but "formatted name").
But right now I would vote for vCard attributes still, as they seem
more complete (at least in vcard 4.0).

Michiel de Jong

unread,
Jun 19, 2012, 6:46:35 AM6/19/12
to unho...@googlegroups.com
what goes on the wire and what reaches the app does not need to be the
same. the library module could do conversions between wire formats and
expose getAsVCard() and getAs...() but also more specific methods like
getFirstName() etcetera

Markus Lanthaler

unread,
Jun 20, 2012, 6:31:52 AM6/20/12
to elf Pavlik, public-linked-json, nil, unho...@googlegroups.com
Hi Elf,

There exists a vCard mapping to RDF [1] which would make it very easy to write a JSON-LD context. So, your jCard could easily be transformed to valid JSON-LD:

{
"@context": {
"v": "http://www.w3.org/2006/vcard/ns#",
"VCard": "v:VCard",
"fn": "v:fn",
"nickname": "v:nickname",
"email": { "@id": "v:email", "@type": "@id" },
"tel": "v:tel",
"Home": "v:Home",
"Voice": "v:Voice",
"value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#value",
"address": "v:adr",
"street": "v:street-address",
"postcode": "v:postal-code",
"locality": "v:locality",
"country": "v:country-name"
},
"@id": "http://example.com/me/corky",
"@type": "vCard:VCard",
"fn": "Corky Crystal",
"nickname": "Corks",
"email": "mailto:co...@example.com",
"tel": {
"@type": ["Home", "Voice"],
"value": "+61 7 5555 5555"
},
"address": {
"@type": "Home",
"street": "111 Lake Drive",
"postcode": "5555",
"locality": "WonderCity",
"country": "Australia"
}
}

Please note that you are free to define how your fields are named in the context. I simplified some here, e.g., "street-address" to just "street" and made sure you don't have to use prefixes. If you would be fine with using prefixes such in v:address in your JSON-LD documents the context could be simplified to something like:

{
"@context": {
"v": "http://www.w3.org/2006/vcard/ns#",
"v:email": { "@type": "@id" },
"r:value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#value"
}
}

The document would then look as follows: http://bit.ly/Mw0weD


The advantage of using JSON-LD in this instance is that you could easily integrate data coming from RDF/XML, Turtle, RDFa (embedded in Websites) into your system.


[1] http://www.w3.org/TR/vcard-rdf/


Hope this helps,
Markus


--
Markus Lanthaler
@markuslanthaler



> -----Original Message-----
> From: elf Pavlik [mailto:perpetua...@wwelves.org]
> Sent: Wednesday, June 20, 2012 11:20 AM
> To: public-linked-json
> Cc: nil
> Subject: Fwd: Re: [unhosted] getting social: defining the 'contacts'
> category
>
> hi, would someone like to share suggestions about using JSON-LD
> with/insteadOf jCards? thank you! :)
> you can find replies to original message below here:
> https://groups.google.com/group/unhosted/browse_thread/thread/afc876f98
> dddd050#anchor_47c625e430b3a9ad
>
> --- Begin forwarded message from nil ---
> From: nil <nil.n...@googlemail.com>
> To: unhosted <unho...@googlegroups.com>
> Date: Tue, 19 Jun 2012 08:18:39 +0000
> Subject: Re: [unhosted] Re: getting social: defining the 'contacts'
> category
>
> As far as we have discussed this now (mostly in the channel and in
> RL), we have settled on using JSON representations of hCards/vCards,
> called jCards, pretty much like http://microformats.org/wiki/jcard.
> Those can (for example) be generated with the vCardJS[1] library.
>
> Now as there's been some talk about using JSON-LD at various points,
> we should probably think about using that in the contacts category as
> well. There seems to be a @context for people[2]. We could just use
> that. I have only scanned through that briefly, and am not sure yet,
> whether all info from vCards can be mapped to person.jsonld (and/or
> vice versa). But to me JSON-LD seems more sophisticated than jcards
> (which are only very loosely defined).
>
> Anyone else any thoughts?
>
> [1]: https://github.com/nilclass/vcardjs
> [2]: http://json-ld.org/contexts/person.jsonld
> --- End forwarded message ---

Markus Lanthaler

unread,
Jun 20, 2012, 10:00:26 AM6/20/12
to elf Pavlik, public-linked-json, unho...@googlegroups.com
elf Pavlik wrote on Wednesday, June 20, 2012 3:18 PM:

> WOW! thanks a lot Markus, looks to me like enough of advice to sort it
> out :) let's see what nil and other folks on unhosted list think about
> it... thank you once more!!!

Let me (us) know if you have further questions. I'm more than happy to answer them.



--
Markus Lanthaler
@markuslanthaler


Markus Lanthaler

unread,
Jun 20, 2012, 10:00:40 AM6/20/12
to nil, elf Pavlik, public-linked-json, unho...@googlegroups.com
> I'm not sure about whether to use prefixes. What are the pros/cons in
> terms of JSON-LD?

Pros: Smaller context
Cons: When accessing data you have to use data["v:email"] vs. data.email


> But as Michiel said earlier in this thread, in the end it doesn't
> really matter what format we use for storage, as at least on the
> JavaScript front we provide the library to access the data. That can
> still convert to "pure" jCards or whatever.

The advantage of JSON-LD in this case is that you can use it for other stuff
as well, it isn't limited to jCards. This could simplify your library and
drastically reduce the amount of custom code you have to write. We also have
an API for JSON-LD [1] and especially framing [2] is quite powerful (it is
currently in a separate document because it's not yet stable enough to hand
it over to W3C).


[1] http://www.json-ld.org/spec/latest/json-ld-api/
[2] http://www.json-ld.org/spec/latest/json-ld-framing/



--
Markus Lanthaler
@markuslanthaler


Michiel de Jong

unread,
Jun 22, 2012, 12:23:59 PM6/22/12
to unho...@googlegroups.com, elf Pavlik, nil
one question is what the information looks like on the wire, but also
interesting is how our future client-side "remoteStorage.contacts"
module will expose the information to the app. the following two links
are also relevant for that:

http://w3c-test.org/dap/contacts/
https://wiki.mozilla.org/WebAPI/ContactsAPI

Niklas, what do you think?


Cheers,
Michiel

nil

unread,
Jun 25, 2012, 7:52:52 AM6/25/12
to Michiel de Jong, unho...@googlegroups.com, elf Pavlik
I agree we can keep it as cryptic as we want on the wire. Maybe for
remoteStorage.contacts the default shouldn't be augmented with
meta-information (such as json-ld's @context), but that should be
available optionally (as "contacts.getRaw()" or something).

"Pick Contacts Intent" -> awesome! was adding extra widgets to
remoteStorage.contacts in my head, but I guess I can remove that :)
"ContactsAPI" -> Oh my! put this in a plugin: forEach(categories,
function(category) { navigator[category] = remoteStorage[category] })
->
Reply all
Reply to author
Forward
0 new messages