使用Ruby访问Ivona Speech Cloud

时间:2016-08-29 08:43:09

标签: ruby text-to-speech ivona

我正在尝试使用Ruby访问Ivona Speech Cloud。

我已将我找到的一个代码示例移植到Ruby,但我在验证请求时可能做错了,因为我收到了错误。

这是我的实施:

require 'http' # the gem
require 'openssl'
require 'pp'

def sign key, date, region, service, text
  k_date    = OpenSSL::HMAC.digest('sha256', "AWS4" + key, date)
  k_region  = OpenSSL::HMAC.digest('sha256', k_date, region)
  k_service = OpenSSL::HMAC.digest('sha256', k_region, service)
  k_signing = OpenSSL::HMAC.digest('sha256', k_service, "aws4_request")
  signature = OpenSSL::HMAC.digest('sha256', k_signing, text)
  signature
end

def run
  access_key = "GDxxxxxxxxxxxxxxxxRA"
  secret_key = "QtxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxlE"

  region    = 'eu-west-1'
  date      = '20160808'
  service   = 'tts'
  body      = {"Input" => {"Data" => "Hello world"}}
  endpoint  = "https://#{service}.#{region}.ivonacloud.com/CreateSpeech"
  signature = sign secret_key, date, region, service, 'Hello World'

  headers = {
    "Content-Type" =>"application/json",
    "Authorization" => "AWS4-HMAC-SHA256",
    "Credential" => "#{access_key}/#{date}/#{region}/#{service}/aws4_request",
    "SignedHeaders" => "content-type;host;x-amz-content-sha256;x-amz-date",
    "Signature" => "#{signature}",
  }

  res = HTTP.headers(headers).post(endpoint, json: body)
  p res
end

run

这是我得到的错误(为了易读性而断行):

#<HTTP::Response/1.1 403 Forbidden 
 {"X-Amzn-Requestid"=>"18a44dd8-6dc3-11e6-808f-975692d1ee55", 
  "X-Amzn-Errortype"=>"IncompleteSignatureException:http://internal.amazon.com/coral/com.amazon.coral.service/", 
  "Content-Type"=>"application/json", 
  "Content-Length"=>"293", 
  "Date"=>"Mon, 29 Aug 2016 08:32:18 GMT"}>

感谢任何帮助

1 个答案:

答案 0 :(得分:1)

我建议使用AWS4 gem来帮助解决这个问题。我使用以下格式进行了类似的调用:

signer = ::AWS4::Signer.new(
  access_key: "YOUR_ACCESS_KEY",
  secret_key: "YOUR_SECRET_KEY",
  region: "us-east-1"
)

aws_headers = {
  "Content-Type" => "application/json; charset=utf8",
  "Date" => Time.now.iso8601.to_s,
  "Host" => "tts.us-east-1.ivonacloud.com"
}

uri = URI(endpoint)
body_params = {"Input":{"Data":"Hello world"}}.to_json

headers = signer.sign("POST", uri, aws_headers, body_params)
res = HTTP.headers(headers).post(endpoint, body: body_params)