글쓰기 메뉴

페이스북 임베드 URL,
소셜 플러그인 (XFBML) 파싱

임베드 대상 페이스북 콘텐츠는 "포스트", "비디오", "사진" 이렇게 종류별로, 웹과 모바일에서 각각 URL 형식이 조금씩 달라 프로그램으로 이를 처리하기 위해 동일한 형태의 주소가 필요하다.


SDK를 사용해 페북 컨텐츠를 임베드하는 경우 기준이 되는 URL 은 웹용 URL 이다.


# photos
[Web] https://www.facebook.com/misfitskr/photos/a.1491490727759208.1073741829.1484819065093041/1676373025937643/?type=3
[Mobile] https://m.facebook.com/misfitskr/photos/a.1491490727759208.1073741829.1484819065093041/1676373025937643/?type=3&refid=17&_ft_=top_level_post_id.1676373025937643%3Atl_objid.1676373025937643

# post
[Web] https://www.facebook.com/miriya.lee/posts/10207578137913624
[Mobile] https://m.facebook.com/story.php?story_fbid=10207578137913624&id=1295580583&refid=17&_ft_=top_level_post_id.10207578137913624%3Atl_objid.10207578137913624%3Athid.1295580583%3A306061129499414%3A2%3A0%3A1448956799%3A-1465209181969975201

# video
https://www.facebook.com/feedbac/videos/10152616268967035/


뭐, URL은 딱보면 알겠지만 fbid 라는 고유ID만 빼오면 된다. 


모바일에서 포스트에 대한 주소만 URL 파라미터로 처리되어 있고 나머지는 전부 URL Path에 포함되어 있으니 아래와 같은 정규식으로 fbid부터 발라내자


/(?<=\/|fbid=)([0-9]+)(?=\/|&|$)/


정규식은 Ruby 2.x 버전에서만 동작을 확인했지만 look-behind 와 look-ahead 외에 정규식 엔진을 타는 내용이 없기 때문에 동작이 안된다면 그 부분만 수정하자.

사실 효율을 생각한다면 저딴 정규식으로 한방에 fbid 를 뽑는 것 보다 fbid 가 파라미터로 존재하는 케이스를 분리시키고 나머지 정규식도 2회로 나눠 돌리는게 더 좋지만... 귀찮으니 한 줄로 하자.


상식적으로 fbid 만 뽑아내면 될 것 같으나 페북 임베드에 사용되는 URL은 사용자 아이디가 버킷 이름처럼 포함되어 있다. 문제는 모바일 URL에 사용자 아이디-문자-가 없다는 점.


이 문제는 페이스북의 짧은 주소 fb.com 을 사용해 해결할 수 있다. http://fb.com/<fbid>의 형식으로 리퀘스트를 보내면 해당하는 완성된 주소로 리디렉션 시켜준다. - 임베드 코드 생성 시 fb.com 을 그냥 쓸 수 있으면 좋을텐데 안되더라.


curl 로 리디렉션된 최종 URL을 뽑는 코드는 아래와 같다.

curl -Ls -o /dev/null -w %{url_effective} http://fb.com/10207578137913624


내가 쓰는 Typhoeus 에선 아래처럼 최종 URL을 받으면 된다. 

res = Typhoeus.get("http://fb.com/10207578137913624", followlocation: true)
facebook_url = res.effective_url


이렇게 얻은 URL 로 

<div class="fb-post" data-href="{fb-post-url}"></div>


위와 같은 XFBML을 사용해 임베드가 가능하다. 다양한 옵션은 페북 문서 확인.


Javascript SDK 를 사용하는 경우 SDK 가 로드된 후 FB 객체를 initialize 하면서 페이지에 있는 모든 XFBML 을 파싱할 수 있고, 이와 다른 타이밍에 추가적으로 XFBML 을 파싱해야하는 경우는 아래의 코드로 가능하다.

FB.XFBML.parse();


특정 엘레먼트만 파싱하려면

FB.XFBML.parse(document.getElementById('foo'));


jQuery 로 돔을 잡아 파싱하려면

FB.XFBML.parse($("#foo")[0]);


이렇게 파싱하면 컨텐츠가 임베드된다.



어디서 왔지?
[["synd.kr", 14], ["adguard.com", 3], ["www.google.co.kr", 84], ["search.naver.com", 1], ["www.google.com.kh", 1], ["www.google.co.jp", 1], ["www.google.com.au", 1], ["unknown", 1041], ["mail.keywordbridge.com", 1], ["www.google.com", 7]]
다른 글들