Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Facebook threads api #3

Closed
wants to merge 3 commits into from

2 participants

@martosoler

All,

I would like to add an initial implementation for the facebook thread api.

Let me know your feedback on this

Thanks

@habuma
Owner

Thanks for the contribution. Just a few things to address:

  1. Your threads.json and thread.json test data files don't look right. It has the "tags" field as an array of Strings, when in fact, the actual data coming back from Facebook is an object with a "data" field containing records of tags. Something like this:

        "tags":
        {
            "data":
            [
                {
                    "name":"inbox"
                },
                {
                    "name":"read"
                },
                {
                    "name":"sent"
                },
                {
                    "name":"source:web"
                }
            ]
        },
    

    So although your test passes, it fails to deserialize when I use it to fetch real data.

  2. I might rename FacebookThread to Thread (yeah...it's the same name as java.util.Thread, but the package is different)

  3. Whenever I call getThread(), passing in a known thread ID, there's a deserialization error. That's because https://graph.facebook.com/{thread ID} seems to always return "false". It seems odd to me that FB would return "false" there, but it does (I get the same thing requesting it directly through my web browser). Have you actually seen it return any real thread data?

  4. Real thread data also includes the actual messages, participants, and a few other items. I know this is your first pass, but do you anticipate adding the ability to fetch a thread's messages (which seems like the most valuable thing about a thread). FWIW, I tried fetch a thread's messages with "https://graph.facebook.com/{thread ID}/messages" and got an empty data list back. It kinda makes me wonder if this part of the Graph API isn't fully baked yet (as hinted in the note at the top of http://developers.facebook.com/docs/reference/api/thread/). Have you had any better luck?

@martosoler

Hi Craig !
First of all, let me say that I really appreciate this kind of feedback. As
you may notice, this is the FIRST time that I will commit something on an open
source community and your kindness is very helpful.
I will take in account each point and commit the code once is finished.
Thanks

@martosoler

Folks,

I won't be able to conitnue working on this.

My apologizes for the inconveniences...

@martosoler martosoler closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
84 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/FacebookThread.java
@@ -0,0 +1,84 @@
+package org.springframework.social.facebook.api;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * Model class representing a thread that contain messages
+ *
+ * @author leandro.soler
+ *
+ */
+public class FacebookThread {
+ private String id;
+
+ private String snippet;
+
+ private Date updatedTime;
+
+ private int messageCount;
+
+ private int unreadCount;
+
+ private List<String> tags;
+
+ public FacebookThread(String id,
+ String snippet, Date updatedTime,
+ int messageCount, int unreadCount, List<String> tags) {
+ this.id = id;
+ this.snippet = snippet;
+ this.updatedTime = updatedTime;
+ this.messageCount = messageCount;
+ this.unreadCount = unreadCount;
+ this.tags = tags;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getSnippet() {
+ return snippet;
+ }
+
+ public void setSnippet(String snippet) {
+ this.snippet = snippet;
+ }
+
+ public Date getUpdatedTime() {
+ return updatedTime;
+ }
+
+ public void setUpdatedTime(Date updatedTime) {
+ this.updatedTime = updatedTime;
+ }
+
+ public int getMessageCount() {
+ return messageCount;
+ }
+
+ public void setMessageCount(int messageCount) {
+ this.messageCount = messageCount;
+ }
+
+ public int getUnreadCount() {
+ return unreadCount;
+ }
+
+ public void setUnreadCount(int unreadCount) {
+ this.unreadCount = unreadCount;
+ }
+
+ public List<String> getTags() {
+ return tags;
+ }
+
+ public void setTags(List<String> tags) {
+ this.tags = tags;
+ }
+
+}
View
9 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/ThreadOperations.java
@@ -0,0 +1,9 @@
+package org.springframework.social.facebook.api;
+
+import java.util.List;
+
+public interface ThreadOperations {
+ List<FacebookThread> getAllThreads(String userId);
+
+ FacebookThread getThread(String threadId);
+}
View
8 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/FacebookTemplate.java
@@ -39,6 +39,7 @@
import org.springframework.social.facebook.api.MediaOperations;
import org.springframework.social.facebook.api.PageOperations;
import org.springframework.social.facebook.api.PlacesOperations;
+import org.springframework.social.facebook.api.ThreadOperations;
import org.springframework.social.facebook.api.UserOperations;
import org.springframework.social.facebook.api.impl.json.FacebookModule;
import org.springframework.social.oauth2.AbstractOAuth2ApiTemplate;
@@ -77,6 +78,8 @@
private MediaOperations mediaOperations;
+ private ThreadOperations threadOperations;
+
private PageOperations pageOperations;
/**
@@ -111,6 +114,7 @@ private void initSubApis() {
eventOperations = new EventTemplate(this);
mediaOperations = new MediaTemplate(this, getRestTemplate());
groupOperations = new GroupTemplate(this);
+ threadOperations = new ThreadTemplate(this);
pageOperations = new PageTemplate(this);
}
@@ -161,6 +165,10 @@ public MediaOperations mediaOperations() {
return mediaOperations;
}
+ public ThreadOperations threadOperations() {
+ return threadOperations;
+ }
+
public PageOperations pageOperations() {
return pageOperations;
}
View
45 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/ThreadList.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.social.facebook.api.impl;
+
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import org.springframework.social.facebook.api.FacebookThread;
+
+/**
+ * Holder class to hold a typed list of Threads, pulled from the "data" field of the JSON object structure.
+ * This helps Jackson know what type to deserialize list data into.
+ * @author leandro.soler
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+public class ThreadList {
+
+ private final List<FacebookThread> list;
+
+ @JsonCreator
+ public ThreadList(@JsonProperty("data") List<FacebookThread> list) {
+ this.list = list;
+ }
+
+ public List<FacebookThread> getList() {
+ return list;
+ }
+
+}
View
24 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/ThreadTemplate.java
@@ -0,0 +1,24 @@
+package org.springframework.social.facebook.api.impl;
+
+import java.util.List;
+
+import org.springframework.social.facebook.api.GraphApi;
+import org.springframework.social.facebook.api.FacebookThread;
+import org.springframework.social.facebook.api.ThreadOperations;
+
+public class ThreadTemplate implements ThreadOperations {
+ private final GraphApi graphApi;
+
+ public ThreadTemplate(GraphApi graphApi) {
+ this.graphApi = graphApi;
+ }
+
+ public List<FacebookThread> getAllThreads(String userId) {
+ return graphApi.fetchConnections(userId, "threads", ThreadList.class).getList();
+ }
+
+ public FacebookThread getThread(String threadId) {
+ return graphApi.fetchObject(threadId, FacebookThread.class);
+ }
+
+}
View
2  spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/FacebookModule.java
@@ -43,6 +43,7 @@
import org.springframework.social.facebook.api.Video;
import org.springframework.social.facebook.api.VideoPost;
import org.springframework.social.facebook.api.WorkEntry;
+import org.springframework.social.facebook.api.FacebookThread;
import org.springframework.social.facebook.api.impl.json.PhotoMixin.ImageMixin;
/**
@@ -84,5 +85,6 @@ public void setupModule(SetupContext context) {
context.setMixInAnnotations(PhotoPost.class, PhotoPostMixin.class);
context.setMixInAnnotations(StatusPost.class, StatusPostMixin.class);
context.setMixInAnnotations(VideoPost.class, VideoPostMixin.class);
+ context.setMixInAnnotations(FacebookThread.class, ThreadMixin.class);
}
}
View
43 spring-social-facebook/src/main/java/org/springframework/social/facebook/api/impl/json/ThreadMixin.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2011 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.social.facebook.api.impl.json;
+
+import java.util.Date;
+import java.util.List;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * Annotated mixin to add Jackson annotations to Thread.
+ * @author leandro.soler
+ *
+ */
+@JsonIgnoreProperties(ignoreUnknown = true)
+abstract class ThreadMixin {
+
+ @JsonCreator
+ ThreadMixin(
+ @JsonProperty("id") String id,
+ @JsonProperty("snippet") String snippet,
+ @JsonProperty("updated_time") Date updatedTime,
+ @JsonProperty("message_count") int messageCount,
+ @JsonProperty("unread_count") int unreadCount,
+ @JsonProperty("tags") List<String> tags
+ )
+ {}
+}
View
52 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/ThreadTemplateTest.java
@@ -0,0 +1,52 @@
+/**
+ *
+ */
+package org.springframework.social.facebook.api;
+
+import static org.springframework.http.HttpMethod.GET;
+import static org.springframework.social.test.client.RequestMatchers.header;
+import static org.springframework.social.test.client.RequestMatchers.method;
+import static org.springframework.social.test.client.RequestMatchers.requestTo;
+import static org.springframework.social.test.client.ResponseCreators.withResponse;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.core.io.ClassPathResource;
+
+
+/**
+ * @author leandro.soler
+ *
+ */
+public class ThreadTemplateTest extends AbstractFacebookApiTest {
+
+ @Test
+ public void getAllThreads() {
+ mockServer.expect(requestTo("https://graph.facebook.com/123456/threads"))
+ .andExpect(method(GET))
+ .andExpect(header("Authorization", "OAuth someAccessToken"))
+ .andRespond(withResponse(new ClassPathResource("testdata/threads.json", getClass()), responseHeaders));
+
+ List<FacebookThread> threads = facebook.threadOperations().getAllThreads("123456");
+ assertNotNull(threads);
+ assertTrue(threads.size() > 0);
+ }
+
+ @Test
+ public void getThread() {
+ mockServer.expect(requestTo("https://graph.facebook.com/12345678912323"))
+ .andExpect(method(GET))
+ .andExpect(header("Authorization", "OAuth someAccessToken"))
+ .andRespond(withResponse(new ClassPathResource("testdata/thread.json", getClass()), responseHeaders));
+
+ FacebookThread thread = facebook.threadOperations().getThread("12345678912323");
+ assertNotNull(thread);
+ assertTrue(thread.getId().equalsIgnoreCase("1122334455"));
+ assertTrue(thread.getMessageCount() == 3);
+ assertTrue(thread.getUnreadCount() == 1);
+ assertTrue(thread.getSnippet().equalsIgnoreCase("Snippet 1"));
+ }
+}
View
8 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/thread.json
@@ -0,0 +1,8 @@
+{
+ "id":"1122334455",
+ "snippet":"Snippet 1",
+ "updated_time":"2011-03-26T14:00:00",
+ "message_count":3,
+ "unread_count":1,
+ "tags":["Maven", "Test"]
+}
View
29 spring-social-facebook/src/test/java/org/springframework/social/facebook/api/testdata/threads.json
@@ -0,0 +1,29 @@
+{
+ "data":
+ [
+ {
+ "id":"1122334455",
+ "snippet":"Snippet 1",
+ "updated_time":"2011-03-26T14:00:00",
+ "message_count":3,
+ "unread_count":1,
+ "tags":["Maven", "Test"]
+ },
+ {
+ "id":"1122334457",
+ "snippet":"Snippet 2",
+ "updated_time":"2011-04-26T14:00:00",
+ "message_count":3,
+ "unread_count":1,
+ "tags":["Maven", "Test"]
+ },
+ {
+ "id":"1122334467",
+ "snippet":"Snippet 3",
+ "updated_time":"2011-05-26T14:00:00",
+ "message_count":3,
+ "unread_count":1,
+ "tags":[]
+ }
+ ]
+}
Something went wrong with that request. Please try again.