Rhapsodist
2020.04.24
Created By Rhapsodist
Rhapsodist
Rails에서 Line Message api를 이용해 대화리스트에서 올라온 이미지를 다운 받아보자.
uri= URI.parse("https://api-data.line.me/v2/bot/message/#{content_id}/content")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
head = {
'Content-type' => 'application/json; charset=UTF-8',
'Authorization' => "Bearer #{ENV['LINE_CHANNEL_TOKEN']}"
}
request = Net::HTTP::Get.new(uri.path, head)
response = http.request(request)
File.open(Rails.root.join('public', 'upload', "#{content_id}.jpg"), 'wb') do |file|
file.write(response.body)
end
라인에서 메세지에는 각각 고유의 아이디가 존재하는데, 이 메세지를 content라고 정의한다.
사진을 받기 위해서는 사진의 content 아이디를 알고 있어야 한다.
또 필요한 것은 line의 channel token이다.
uri= URI.parse("https://api-data.line.me/v2/bot/message/#{content_id}/content")
우선 라인에서 context의 정보를 받기위한 uri를 입력한다.
#{}
안에는 이미지의 content id를 넣는다.
head = {
'Content-type' => 'application/json; charset=UTF-8',
'Authorization' => "Bearer #{ENV['LINE_CHANNEL_TOKEN']}"
}
그 다음으로는 request의 header을 설정해 준다.
Content-type
은 딱히 설정을 안해줘도 괜찮은나, Authorization
은 반드시 설정해야한다.
#{}
안에 line channel token을 입력해주면 된다.
Bearer은 잊지말고 넣어주자!
File.open(Rails.root.join('public', 'upload', "#{content_id}.jpg"), 'wb') do |file|
file.write(response.body)
end
response를 받고 body
부분을 확인해 보면 binary code의 형태로 돌아온다.
원래는 send_file
로 바로 front 쪽으로 보내는 방법을 생각했었지만,
line에서 돌아온 binary 코드를 직접 저장하거나, send_file
처럼 바로 file로 사용하려고 하면 다음과 같은 에러가 발생한다.
Encoding::UndefinedConversionError ("\xFF" from ASCII-8BIT to UTF-8):
binary code가 깨져있다는 것인데, 인코딩 과정에서 뭔가 문제가 있는듯 하다.
nodejs에서는
const options = {
url: `https://api.line.me/v2/bot/message/${content_id}/content`,
method: 'get',
headers: {
'Authorization': 'Bearer ' + accessToken,
},
encoding: null
}
처럼 간단히 request options에 encoding: null
만 해주면 encode 에러 없이 사용할 수 있지만,
루비에서 저 방식을 어떻게 해야하는지 나는 모르겠다. 한참을 조사해봤지만 방법을 알아낼 수 없었다.
현재 진행중인 프로젝트에서 bot server에 직접 image를 저장하지 않고 line의 server에 저장되어있는 image를 불러와서 쓰고, 그 이미지 파일은 보관하지 않는 계획이었기 때문에, 방법을 찾을 수가 없어서 참 화가나는 상황이었다.
결국, 나는 파일로 우선 저장했다가 사용후 다 지워버리는 방법을 택했다.
위의 코드에서 중요한 점은 response되어 오는 코드가 binary이기 때문에 저장 방식을 wb로 해주어야 한다는 점이다. 그 이외에는 그저 파일을 저장하는 코드이다.
참고로 폴더안의 모든 데이터를 삭제하는 ruby 코드는 다음과 같다.
FileUtils.rm_rf(Dir.glob(Rails.root.join('public', 'upload', '*')))
© 2020, made by Rhapsodist