package com.robonobo.midas.controller;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import com.restfb.*;
import com.restfb.types.User;
import com.robonobo.midas.FacebookService;
import com.robonobo.midas.model.MidasUser;
import com.robonobo.midas.model.MidasUserConfig;
import com.robonobo.remote.service.MidasService;
@Controller
@RequestMapping(value = "/fb-callback")
public class FacebookController extends BaseController {
@Autowired
FacebookService facebook;
@Autowired
MidasService midas;
ObjectMapper jsonMapper = new ObjectMapper();
@RequestMapping(method=RequestMethod.GET)
public void facebookVerifyUrl(@RequestParam(value = "hub.challenge", required = false) String challenge,
@RequestParam("hub.verify_token") String verifyToken, HttpServletRequest req, HttpServletResponse resp) throws IOException {
if (!verifyToken.equals(facebook.getFacebookVerifyTok())) {
// Someone is playing silly buggers, maybe?
log.error("Facebook called back with invalid verify token " + verifyToken + " (was expecting "
+ facebook.getFacebookVerifyTok() + ")");
resp.setStatus(HttpServletResponse.SC_FORBIDDEN);
return;
}
resp.getWriter().print(challenge);
}
@SuppressWarnings("unchecked")
@RequestMapping(method=RequestMethod.POST)
public void facebookDataChanged(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
// Parse our json using the wonderful jackson library
Map<String, Object> json;
try {
json = jsonMapper.readValue(req.getInputStream(), Map.class);
} catch (Exception e) {
throw new IOException(e);
}
if (!"user".equals(json.get("object")))
throw new IOException("Invalid object in facebook callback: " + json.get("object"));
List<Object> changedObjs = (List<Object>) json.get("entry");
log.info("Facebook callback received with " + changedObjs.size() + " changed objects");
for (Object obj : changedObjs) {
Map<String, Object> changedObj = (Map<String, Object>) obj;
String fbId = (String) changedObj.get("uid");
MidasUserConfig muc = facebook.getUserConfigByFacebookId(fbId);
if (muc == null)
continue;
List<Object> changedFields = (List<Object>) changedObj.get("changed_fields");
for (Object field : changedFields) {
if ("name".equals(field)) {
FacebookClient fbCli = facebook.getFacebookClient(muc.getItem("facebookAccessToken"));
User fbUser;
try {
fbUser = fbCli.fetchObject("me", User.class, Parameter.with("fields", "name"));
} catch (FacebookException e) {
throw new IOException(e);
}
facebook.updateFacebookName(fbId, fbUser.getName());
} else if ("friends".equals(field)) {
MidasUser user = midas.getUserById(muc.getUserId());
facebook.updateFriends(user, muc);
}
}
}
}
}