diff options
-rw-r--r-- | facebook/facebook-api.c | 127 | ||||
-rw-r--r-- | facebook/facebook.c | 12 |
2 files changed, 132 insertions, 7 deletions
diff --git a/facebook/facebook-api.c b/facebook/facebook-api.c index 3d73caa..36f29c2 100644 --- a/facebook/facebook-api.c +++ b/facebook/facebook-api.c @@ -1435,6 +1435,9 @@ fb_api_message_parse_attach(FbApi *api, const gchar *mid, FbApiMessage *msg, static GSList * fb_api_cb_publish_ms_new_message(FbApi *api, JsonNode *root, GSList *msgs, GError **error); +static GSList * +fb_api_cb_publish_ms_event(FbApi *api, JsonNode *root, GSList *events, FbApiEventType type, GError **error); + static void fb_api_cb_publish_ms(FbApi *api, GByteArray *pload) { @@ -1446,11 +1449,23 @@ fb_api_cb_publish_ms(FbApi *api, GByteArray *pload) GError *err = NULL; GList *elms, *l; GSList *msgs = NULL; + GSList *events = NULL; guint size; JsonNode *root; JsonNode *node; JsonArray *arr; + static const struct { + const gchar *member; + FbApiEventType type; + gboolean is_message; + } event_types[] = { + {"deltaNewMessage", 0, 1}, + {"deltaThreadName", FB_API_EVENT_TYPE_THREAD_TOPIC, 0}, + {"deltaParticipantsAddedToGroupThread", FB_API_EVENT_TYPE_THREAD_USER_ADDED, 0}, + {"deltaParticipantLeftGroupThread", FB_API_EVENT_TYPE_THREAD_USER_REMOVED, 0}, + }; + /* Read identifier string (for Facebook employees) */ thft = fb_thrift_new(pload, 0); fb_thrift_read_str(thft, NULL); @@ -1492,10 +1507,23 @@ fb_api_cb_publish_ms(FbApi *api, GByteArray *pload) elms = json_array_get_elements(arr); for (l = elms; l != NULL; l = l->next) { + guint i = 0; JsonObject *o = json_node_get_object(l->data); - if ((node = json_object_get_member(o, "deltaNewMessage"))) { - msgs = fb_api_cb_publish_ms_new_message(api, node, msgs, &err); + + for (i = 0; i < G_N_ELEMENTS(event_types); i++) { + if ((node = json_object_get_member(o, event_types[i].member))) { + if (event_types[i].is_message) { + msgs = fb_api_cb_publish_ms_new_message( + api, node, msgs, &err + ); + } else { + events = fb_api_cb_publish_ms_event( + api, node, events, event_types[i].type, &err + ); + } + } } + if (G_UNLIKELY(err != NULL)) { break; } @@ -1505,13 +1533,21 @@ fb_api_cb_publish_ms(FbApi *api, GByteArray *pload) json_array_unref(arr); if (G_LIKELY(err == NULL)) { - msgs = g_slist_reverse(msgs); - g_signal_emit_by_name(api, "messages", msgs); + if (msgs) { + msgs = g_slist_reverse(msgs); + g_signal_emit_by_name(api, "messages", msgs); + } + + if (events) { + events = g_slist_reverse(events); + g_signal_emit_by_name(api, "events", events); + } } else { fb_api_error_emit(api, err); } g_slist_free_full(msgs, (GDestroyNotify) fb_api_message_free); + g_slist_free_full(events, (GDestroyNotify) fb_api_event_free); json_node_free(root); } @@ -1615,6 +1651,89 @@ beach: return msgs; } +static GSList * +fb_api_cb_publish_ms_event(FbApi *api, JsonNode *root, GSList *events, FbApiEventType type, GError **error) +{ + FbApiEvent *event; + FbJsonValues *values = NULL; + FbJsonValues *values_inner = NULL; + GError *err = NULL; + + values = fb_json_values_new(root); + fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, + "$.messageMetadata.threadKey.threadFbId"); + fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, + "$.messageMetadata.actorFbId"); + + switch (type) { + case FB_API_EVENT_TYPE_THREAD_TOPIC: + fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, + "$.name"); + break; + + case FB_API_EVENT_TYPE_THREAD_USER_ADDED: + values_inner = fb_json_values_new(root); + + fb_json_values_add(values_inner, FB_JSON_TYPE_INT, FALSE, + "$.userFbId"); + + /* use the text field for the full name */ + fb_json_values_add(values_inner, FB_JSON_TYPE_STR, FALSE, + "$.fullName"); + + fb_json_values_set_array(values_inner, FALSE, + "$.addedParticipants"); + break; + + case FB_API_EVENT_TYPE_THREAD_USER_REMOVED: + fb_json_values_add(values, FB_JSON_TYPE_INT, FALSE, + "$.leftParticipantFbId"); + + /* use the text field for the kick message */ + fb_json_values_add(values, FB_JSON_TYPE_STR, FALSE, + "$.messageMetadata.adminText"); + break; + } + + fb_json_values_update(values, &err); + + event = fb_api_event_dup(NULL, FALSE); + event->type = type; + event->tid = fb_json_values_next_int(values, 0); + event->uid = fb_json_values_next_int(values, 0); + + if (type == FB_API_EVENT_TYPE_THREAD_TOPIC) { + event->text = fb_json_values_next_str_dup(values, NULL); + } else if (type == FB_API_EVENT_TYPE_THREAD_USER_REMOVED) { + /* overwrite actor with subject */ + event->uid = fb_json_values_next_int(values, 0); + event->text = fb_json_values_next_str_dup(values, NULL); + } else if (type == FB_API_EVENT_TYPE_THREAD_USER_ADDED) { + + while (fb_json_values_update(values_inner, &err)) { + FbApiEvent *devent = fb_api_event_dup(event, FALSE); + + devent->uid = fb_json_values_next_int(values_inner, 0); + devent->text = fb_json_values_next_str_dup(values_inner, NULL); + + events = g_slist_prepend(events, devent); + } + fb_api_event_free(event); + event = NULL; + g_object_unref(values_inner); + } + + g_object_unref(values); + + if (G_UNLIKELY(err != NULL)) { + g_propagate_error(error, err); + } else if (event) { + events = g_slist_prepend(events, event); + } + + return events; +} + static void fb_api_cb_publish_pt(FbThrift *thft, GSList **press, GError **error) { diff --git a/facebook/facebook.c b/facebook/facebook.c index 29a67e9..995ad59 100644 --- a/facebook/facebook.c +++ b/facebook/facebook.c @@ -353,15 +353,21 @@ fb_cb_api_events(FbApi *api, GSList *events, gpointer data) case FB_API_EVENT_TYPE_THREAD_USER_ADDED: if (bee_user_by_handle(ic->bee, ic, uid) == NULL) { - g_hash_table_insert(fetch, &event->tid, event); - break; + if (event->text) { + bee_user_new(ic->bee, ic, uid, BEE_USER_LOCAL); + imcb_buddy_nick_hint(ic, uid, event->text); + imcb_rename_buddy(ic, uid, event->text); + } else { + g_hash_table_insert(fetch, &event->tid, event); + break; + } } imcb_chat_add_buddy(gc, uid); break; case FB_API_EVENT_TYPE_THREAD_USER_REMOVED: - imcb_chat_remove_buddy(gc, uid, NULL); + imcb_chat_remove_buddy(gc, uid, event->text); break; } } |