네이버 신디케이션 — Rails

티엘엑스(TLX) / 이성관

블로그에 새 글이 올라올 때, naver에 사이트 등록을 한다. 네이버 신디케이션 API를 이용하면 자동으로 등록된다.

Wordpress에는 네이버 신디케이션 plugin이 존재한다. Rails gem을 찾아보니 애석하게도 없었다. 직접 만들면서 알게 되었다. 딱히 gem을 만들 만한 일도 아니더라.

네이버 신디케이션을 이용하려면 우선 네이버 웹마스터 도구를 이용해야 한다. 해당 url이 자기 것이라는 인증과정만 거치면 바로 사용할 수 있다.

작동방법은 대강 이렇다.

  1. 네이버 신디케이션 API를 이용해서, 새로운 글이 생성되었음을 알린다. (혹은 글이 지워졌음을)
  2. 네이버 크롤링 봇, Yeti가 와서 크롤링 해간다.

API를 이용할 때 미리 약속된 format으로 만들어야 되는데, ATOM feed와 구조가 거의 같다. 다만 네이버가 정한 룰 때문에 (꼭 이름/저자/업데이트날짜 이런 순서를 지켜야 한다.)
Rails에서 제공하는 atom_feed helper를 그대로 이용할 수 없다. 그러나 format만 살짝 바꾸면 되기 때문에 atom_feed helper를 이용해서, feed를 만드는 방법을 알려주는 Railscast가 늘 그렇듯 엄청 도움이 된다.
(요즘 새로운 episode가 안올라오고 있는데… 힘내시라는 의미에서 예전에 유료결제 해드렸다)

atom_feed helper의 코드를 그대로 가져와서 formating만 바꾼 naver_atom_feed helper를 만들었다. 별다른 건 없고, feed option 초기화 부분과 제일 마지막에 나와야 되는 link 부분을 주석처리한게 전부다.

module NaverSyndicationHelper
def naver_atom_feed(options = {}, █)
...
feed_opts = {}
//feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'}
...
xml.feed(feed_opts) do
xml.id...
// xml.link...
// xml.link...
yield ActionView::Helpers::AtomFeedHelper::AtomFeedBuilder.new(xml, self, options)
end
end
end

새로만든 naver_atom_feed helper를 이용해서, feed부분만 완성한 code이다.

naver_atom_feed({xmlns: "http://webmastertool.naver.com", id: 'http://ikeaapart.com'}) do |feed|
feed.title "이케아아파트"
feed.author do |autor|
autor.name("이케아아파트")
end
feed.updated Link.maximum(:updated_at)
feed.link(:rel => 'site', :href => (request.protocol + request.host_with_port), :title => '이케아아파트')

이제 entry쪽을 만들어야 되는데, 네이버가 지정한 순서에 맞아야지만 신디케이션 서버에 전달할 수 있다. 정말 이상한 형식이다. 아무튼 그래서 Rails에서 제공하는 entry method를 사용하지 못한다. 이번엔 AtomFeedBuilder class에 naver_entry method를 만들었다.

#config/initializers/feed_entry_extentions.rb
module ActionView
module Helpers
module AtomFeedHelper
class AtomFeedBuilder
def naver_entry(record, options = {})
@xml.entry do
@xml.id...
# if options[:published]...
# @xml.published(...)
# end
# if options[:updated]...
# @xml.updated(...)
# end
# @xml.link(..)
...

이번에도 순서 때문에 주석처리 한 것 밖에 없다. naver_entry method를 이용해서 완성된 코드가 아래 코드이다.

# views/links/show.atom.builder
naver_atom_feed({xmlns: "http://webmastertool.naver.com", id: 'http://ikeaapart.com'}) do |feed|
feed.title "이케아아파트"
feed.author do |autor|
autor.name("이케아아파트")
end
feed.updated Link.maximum(:updated_at)
feed.link(:rel => 'site', ...)

feed.naver_entry(@link, {id: link_url(@link)}) do |entry|
entry.title(@link.title)
entry.author do |author|
author.name("이케아아파트")
end
entry.updated(@link.updated_at.xmlschema)
entry.published(@link.created_at.xmlschema)
entry.link(:rel => 'via', :href => (request.protocol + request.host_with_port))
entry.content(@link.contents)
end
end

이제 새 글이 만들어 질 때, 이 atom 파일 주소를 네이버 신디케이션 API로 보내주면 된다. 참고로 Rails에서는 어떤 view파일을 사용할지 알아서 해주니, controller에 따로 ‘response_to’ 를 이용해서 format을 나눠줄 필요는 없고, 이름만 잘 맞춰주면 된다. (위 파일명은 show.atom.builder 이다)

네이버 신디케이션 API에 핑을 보내는 code이다. 네이버가 지정해 놓은 header를 설정해 줘야 되고, 신디케이션 인증 토큰을 받아서 header에 넣어줘야 된다. 신디케이션 토큰은 네이버 웹마스터 페이지에서 볼 수 있다.

require 'net/http'
...
header = {"User-Agent"=>"request",
"Host"=>"apis.naver.com",
"Progma"=>"no-cache",
"Content-type"=>"application/x-www-form-urlencoded",
"Accept"=>"*/*",
"Authorization"=>"Bearer " + ENV["NAVER_SYNDICATION_TOKEN"]}
 uri = URI.parse('https://apis.naver.com/crawl/nsyndi/v2')
 http = Net::HTTP.new(uri.host, uri.port) 
http.use_ssl = true
 args = {ping_url: link_url(link_id, format: "atom")}
uri.query = URI.encode_www_form(args)
request = Net::HTTP::Post.new(uri.request_uri, header)
http.request(request)

네이버 신디케이션 페이지에서 핑이 제대로 도달하는지 바로 확인해 볼 수 있다.

#티엘엑스 #TLX #BA #BusinessAnalyst #비즈니스애널리스트 #꿀팁 #인사이트 #조언


관련 스택

티엘엑스(TLX) 팀의 팀터뷰 보기

TLX의 스튜디오 사업부를 만나다, 이종현 개발자

기업문화 엿볼 때, 더팀스

로그인

/