0

Facebook メッセージ (FQL 用語では unified_message) を読み取るデスクトップ アプリケーションがあり、他のユーザーが Facebook ページに残しました。問題は、ユーザーがリンクを含むメッセージを書き込むと、Facebook が自動的にオブジェクトをメッセージに添付することです。そして、このアタッチメントは RestFb Lib で例外を引き起こします。残念ながら、私のページ アクセス トークンは役に立ちません。使用するには、Facebook で私としてログインする必要があるためです。しかし、シナリオは非常に単純です。「www.wheather.com - クールなサイト」のようなページにメッセージを残してみてください。RestFb 1.6.9 と 1.6.11 で試してみましたが、どちらも同じ結果でした。整形してごめんなさい。他の方法ではできませんでした:(

1.6.11 のスタックは次のとおりです。

com.restfb.exception.FacebookJsonMappingException: Unable to convert Facebook response JSON to a list of java.lang.String instances.  Offending JSON is {"38d79791ef0dac6f0b645a87f4d152d7":{"icon":"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif","fb_object_type":"","tagged_ids":[],"description":"The Weather Channel and weather.com provide a national and local weather forecast for cities, as well as weather radar, report and hurricane coverage.","name":"National and Local Weather Forecast, Hurricane, Radar and Report","fb_object_id":"","caption":"www.weather.com","properties":[],"media":[],"href":"http://www.weather.com/"}}
    at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:171)
    at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:653)
    at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:290)
    at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:181)
    at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:653)
    at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:290)
       at myprogram.MyDefaultFacebokClient.executeMultiquery(MyDefaultFacebokClient.java:62)
Caused by: com.restfb.json.JsonException: JsonObject["data"] not found.
    at com.restfb.json.JsonObject.get(JsonObject.java:525)
    at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:155)
    ... 17 more

1.6.9 のスタックは次のとおりです。

com.restfb.exception.FacebookJsonMappingException: Unable to convert Facebook response JSON to a list of java.lang.String instances.  Offending JSON is {"38d79791ef0dac6f0b645a87f4d152d7":{"icon":"https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif","fb_object_type":"","tagged_ids":[],"description":"The Weather Channel and weather.com provide a national and local weather forecast for cities, as well as weather radar, report and hurricane coverage.","name":"National and Local Weather Forecast, Hurricane, Radar and Report","fb_object_id":"","caption":"www.weather.com","properties":[],"media":[],"href":"http://www.weather.com/"}}
    at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:167)
    at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:602)
    at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:279)
    at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:177)
    at com.restfb.DefaultJsonMapper.toJavaType(DefaultJsonMapper.java:602)
    at com.restfb.DefaultJsonMapper.toJavaObject(DefaultJsonMapper.java:279)
       at myprogram.MyDefaultFacebokClient.executeMultiquery(MyDefaultFacebokClient.java:62)
    . . .
Caused by: com.restfb.json.JsonException: JsonObject["data"] not found.
    at com.restfb.json.JsonObject.get(JsonObject.java:525)
    at com.restfb.DefaultJsonMapper.toJavaList(DefaultJsonMapper.java:151)
    ... 17 more

FQL リクエストは次のとおりです。

{
"users":"SELECT uid,first_name,middle_name,last_name,name,pic_small,pic_big,profile_update_time,timezone,religion,birthday,birthday_date,sex,hometown_location,relationship_status,political,current_location,about_me,notes_count,wall_count,status,locale,profile_url,verified,profile_blurb,username,is_blocked,email,friend_count,languages FROM user WHERE uid IN (SELECT sender FROM #messages)"
,"msg":"SELECT message_id FROM unified_message WHERE thread_id='t_id.238275946308607' AND timestamp > '1360112817564' AND sender.user_id != '507447822604742' LIMIT 100"
,"messages":"SELECT message_id,thread_id,subject,body,unread,action_id,timestamp,tags,sender,recipients,object_sender,html_body,attachments,shares,share_map FROM unified_message WHERE message_id IN (SELECT message_id FROM #msg) AND timestamp > '1360112817564' AND timestamp <= '1360117314920' LIMIT 100"
}

上記のリクエストに対する Facebook Explorer からの返信は次のとおりです。

{
  "data": [
    {
      "name": "msg", 
      "fql_result_set": [
        {
          "message_id": "m_mid.1360112949050:d17ca4ed7fc6236a75"
        }
      ]
    }, 
    {
      "name": "messages", 
      "fql_result_set": [
        {
          "message_id": "m_mid.1360112949050:d17ca4ed7fc6236a75", 
          "thread_id": "t_id.238275946308607", 
          "subject": null, 
          "body": "Have a look on http://www.weather.com 1", 
          "unread": true, 
          "action_id": "1360112949128000000", 
          "timestamp": "1360112949058", 
          "tags": [
            "inbox", 
            "source:web"
          ], 
          "sender": {
            "name": "Adam Client", 
            "email": "100004967623158@facebook.com", 
            "user_id": "100004967623158"
          }, 
          "recipients": [
            {
              "name": "MB Aerospace Corp.", 
              "email": "507447822604742@facebook.com", 
              "user_id": "507447822604742"
            }, 
            {
              "name": "Adam Client", 
              "email": "100004967623158@facebook.com", 
              "user_id": "100004967623158"
            }
          ], 
          "object_sender": null, 
          "html_body": "Have a look on http://www.weather.com 1", 
          "attachments": [
          ], 
          "shares": [
            "38d79791ef0dac6f0b645a87f4d152d7"
          ], 
          "share_map": {
            "38d79791ef0dac6f0b645a87f4d152d7": {
              "media": [
              ], 
              "name": "National and Local Weather Forecast, Hurricane, Radar and Report", 
              "href": "http://www.weather.com/", 
              "caption": "www.weather.com", 
              "description": "The Weather Channel and weather.com provide a national and local weather forecast for cities, as well as weather radar, report and hurricane coverage.", 
              "properties": [
              ], 
              "fb_object_type": "", 
              "fb_object_id": "", 
              "icon": "https://fbstatic-a.akamaihd.net/rsrc.php/v2/yD/r/aS8ecmYRys0.gif", 
              "tagged_ids": [
              ]
            }
          }
        }
      ]
    }, 
    {
      "name": "users", 
      "fql_result_set": [
        {
          "uid": 100004967623158, 
          "first_name": "Adam", 
          "middle_name": "", 
          "last_name": "Client", 
          "name": "Adam Client", 
          "pic_small": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/371585_100004967623158_2019810380_t.jpg", 
          "pic_big": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-ash4/371585_100004967623158_2019810380_n.jpg", 
          "profile_update_time": 1360108999, 
          "timezone": null, 
          "religion": null, 
          "birthday": null, 
          "birthday_date": null, 
          "sex": "male", 
          "hometown_location": null, 
          "relationship_status": null, 
          "political": null, 
          "current_location": null, 
          "about_me": null, 
          "notes_count": null, 
          "wall_count": null, 
          "status": null, 
          "locale": "en_US", 
          "profile_url": "https://www.facebook.com/adam.client.5", 
          "verified": null, 
          "profile_blurb": null, 
          "username": "adam.client.5", 
          "is_blocked": false, 
          "email": null, 
          "friend_count": 1, 
          "languages": [
          ]
        }
      ]
    }
  ]
}

そして最後。再定義された FacebookClient を使用します。ソースはここ、stackoverflow.com から取得されました。正確な理由は覚えていませんが、DefaultFacebookClient が Facebook からの結果 (メッセージへの添付ファイル) を正しくマップできなかったようなものでした。

public class MyDefaultFacebokClient extends DefaultFacebookClient {


@Override public <T> T executeMultiquery (Map<String, String> queries, Class<T> objectType, Parameter... parameters)
{
verifyParameterPresence("objectType", objectType);
for (Parameter parameter : parameters)
if (QUERY_PARAM_NAME.equals(parameter.name))
throw new IllegalArgumentException("You cannot specify the '" + QUERY_PARAM_NAME
+ "' URL parameter yourself - " + "RestFB will populate this for you with "
+ "the queries you passed to this method.");

try {
List<JsonObject> jsonObjects = jsonMapper.toJavaList(makeRequest("fql", false, false, null,
parametersWithAdditionalParameter(Parameter.with("q", queriesToJson(queries)), parameters)), JsonObject.class);

JsonObject normalizedJson = new JsonObject();

for (int i = 0; i < jsonObjects.size(); i++)
{
JsonObject jsonObject = jsonObjects.get(i);

// For empty result sets, Facebook will return an empty object instead of
// an empty list. Hack around that here.
JsonArray resultsArray =
jsonObject.get("fql_result_set") instanceof JsonArray ? jsonObject.getJsonArray("fql_result_set")
: new JsonArray();

normalizedJson.put(jsonObject.getString("name"), resultsArray);
}

return objectType.equals(JsonObject.class) ? (T) normalizedJson : jsonMapper.toJavaObject(normalizedJson.toString(), objectType);

} catch (JsonException e) {
throw new FacebookJsonMappingException("Unable to process fql.multiquery JSON response", e);
}
}
}

どんなアイデアでも大歓迎です。

4

1 に答える 1

0

私はRestFBの作者です。たぶん、Githubから最新のものをプルし、「antdist」を実行して1.6.12JARを作成し、FacebookClient.executeMultiquery()の代わりに新しいFacebookClient.executeFqlMultiqueryメソッドを呼び出してみてください。

新しいGraphAPIFQLエンドポイントは、古いものとは少し異なり、この新しいexecuteFqlMultiquery()メソッドで、発生している問題が修正されるはずです。そうでない場合、または結果タイプを正しくマッピングする際に問題が発生した場合は、お知らせください。

https://groups.google.com/forum/?fromgroups=#!topic/restfb/yjCxSQuiieEからコピーした新しいメソッドの使用方法の簡単な例を次に示します。

static void test() throws Exception {
  FacebookClient facebookClient = new DefaultFacebookClient("xxx");

  final String threadsFql =
      "SELECT action_id, archived, can_reply, folder, former_participants, has_attachments, "
          + "is_subscribed, last_visible_add_action_id, name, num_messages, num_unread, object_participants, "
          + "participants, senders, single_recipient, snippet, snippet_sender, snippet_message_has_attachment, "
          + "subject, tags, thread_id, thread_participants, timestamp, unread "
          + "FROM unified_thread WHERE folder='inbox' AND has_attachments='1'";

  final String messagesFql =
      "SELECT message_id, thread_id, subject, body, unread, action_id, timestamp, tags, sender, recipients, "
          + "object_sender, html_body, attachments, attachment_map, shares, share_map "
          + "FROM unified_message WHERE thread_id IN (SELECT thread_id FROM #threads) LIMIT 2";

  ComplexMappingResults results = facebookClient.executeFqlMultiquery(new HashMap<String, String>() {
    {
      put("threads", threadsFql);
      put("messages", messagesFql);
    }
  }, ComplexMappingResults.class);

  out.println(results);
}

public static class ComplexMappingResults {
  @Facebook
  private List<Thread> threads;

  @Facebook
  private List<Message> messages;

  @Override
  public String toString() {
    return ReflectionUtils.toString(this);
  }

  public List<Thread> getThreads() {
    return threads;
  }

  public List<Message> getMessages() {
    return messages;
  }
}
于 2013-02-06T21:57:58.563 に答える