Skip to content

Instantly share code, notes, and snippets.

@19h
Created December 25, 2013 11:17
Show Gist options
  • Save 19h/8122309 to your computer and use it in GitHub Desktop.
Save 19h/8122309 to your computer and use it in GitHub Desktop.
Facebook Messenger (iOS) initialization graph query over an inofficial API.
viewer() {
messenger_contacts {
deltas.after(Nzg1NDY3Nzk1OjEzODc5Njc0NTE=).contact_profile_type(user) {
page_info {
end_cursor
}, nodes {
added_edge {
time, node {
id, graph_api_write_id, phone_entries {
is_verified, primary_field {
label, phone {
display_number, universal_number
}
}
}, phonetic_name {
parts {
offset, length, part
}, text
}, profile_picture.size(88, 88) as small_profile_picture {
uri
}, profile_picture.size(160, 160) as large_profile_picture {
uri
}, represented_profile {
id, is_mobile_pushable, is_messenger_user, is_viewer_friend, messenger_version_max, name_search_tokens, viewer_affinity.method(communication) as rank
}, structured_name {
parts {
offset, length, part
}, text
}
}
}, removed
}
}
}
}
@19h
Copy link
Author

19h commented Dec 25, 2013

Analysis

  • the first wrap seems to specify the perspective of the query ("viewer")
  • the second wrap seems to specify the target graph table ("messenger_contacts") which might have been specifically implemented as a bridge between the chat, messaging platform of Facebook and the messenger API platform.
  • the third wrap seems to be a ECMAScript-inspired query sequence mimicking a function call sequence.
    • the first statement is a selector of "deltas" which seems to be a segment selector. (everything before X, after X)
    • the assumption is proven by having a selector called "after" with a base64-encoded parameter consisting of the user-id and the selector timestamp in seconds (not ms).
    • the following query statement might indicate a selection of contact_profile_type from every result the previous selector yielded. For now, I assume this could translate to SQL like this: SELECT * FROM deltas.after:* WHERE contact_profile_type = "user"
  • inside the next wrap there are two seperated statements: page_info and nodes. page_info might be a control-statement and is puzzling. Considering the response to the query, the statement end_cursor points to the last or if no result yielded, local user of the query. This is very likely a timestamp influencing the next requests. (we already have a similar value inside our deltas.after call, thus this might be the key used for the next request in order to receive all appropiate deltas)
    • nodes obviously is a selector of the fields resulted from the query.

Conclusion

There seems to be only three key statements influecing the query itself: viewer (as perspective?), messenger_contacts (as table selector?) and the deltas.after call. Everything inside the deltas.after wrap indicates that it is formatting the results and queried fields in a form desired by the api client.

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