ニフクラ ブログ

ニフクラやクラウドの技術について、エンジニアが語るブログです。

ニフクラスクリプトが Ruby に対応しました! (利用可能ライブラリのご紹介)

こんにちは、ニフクラエンジニアの d:id:tily です。
ニフクラスクリプトは、サーバーの構築・運用を一切せずに、サーバーサイドのスクリプトが実行できる機能です。 いわゆるサーバーレスサービスと呼ばれているものです。
本日 4/18(水) より、このニフクラスクリプトでプログラミング言語 Ruby が利用可能となりました。

概要や基本的な使い方については上記ヘルプをご参照いただくとして、この記事ではニフクラスクリプトの Ruby で利用可能な gem ライブラリについて、いくつかピックアップしてご紹介したいと思います。

スクリプトの基本形

ヘルプにも記載がありますが、ニフクラスクリプトの Ruby は Rack 互換の call メソッドを実装することになります。
下記のように env を受け取って適切に処理し、ステータスコード・HTTP ヘッダ・ボディを返却します。

require "cgi"

def call(env)
  params = CGI.parse(env["QUERY_STRING"])
  name = params["name"][0]
  [200, {"Content-Type": "text/plain"}, ["hello, #{name}\n"]]
end

コントロールパネル(以降コンパネ)からスクリプトを登録し、Query に {"name": "tily"} を指定して実行すると、このように表示されます。

f:id:tily:20180412171808p:plain

rack gem でリクエスト・レスポンスを抽象化

「基本形」のままでは env に保存された GET クエリ情報を取得したり、自分で Rack 互換なレスポンスを返却しなければならなく、少し不便です。
rack gem に含まれる Rack::Request / Rack::Response クラスを利用して、よりスマートにリクエスト・レスポンス情報を扱ってみましょう

require "rack"

def call(env)
  req = Rack::Request.new(env)
  res = Rack::Response.new
  res["Content-Type"] = "text/plain"
  res.write("hello, #{req.params["name"]}\n")
  res.finish
end

このように node.js + express.js での req / res オブジェクトのような感覚でプログラムを書くことができます。

httparty gem で HTTP リクエストを送る

httparty gem を利用することで、簡単に HTTP リクエストを送ることができます。
ここではチャットツール Slack の API をたたいて、チャンネルにメッセージを送信する例をご紹介します。

require "rack"
require "httparty"

SLACK_ENDPOINT = "https://slack.com/api/chat.postMessage"
SLACK_TOKEN = "<SLACK の API トークン>"
SLACK_CHANNEL = "<メッセージ送信先の Slack チャンネル>"
SLACK_USERNAME = "<Slack ボット名>"

def call(env)
  req = Rack::Request.new(env)
  res = Rack::Response.new

  text = "hello, #{req.params["name"]}"
  slack_res = send_slack_message(text)

  res["Content-Type"] = "application/json"
  res.write(slack_res.body)
  res.finish
end

def send_slack_message(text)
  HTTParty.post(
    SLACK_ENDPOINT,
    query: {
      text: text,
      channel: SLACK_CHANNEL,
      token: SLACK_TOKEN,
      username: SLACK_USERNAME
    }
  )
end

コンパネから実行すると下記のように表示され、 f:id:tily:20180412172107p:plain

Slack 上にもメッセージが送信されていることが分かります。

f:id:tily:20180412172118p:plain

前にサーバー不要! タイマー+スクリプトで定期処理を自動化の記事でもご紹介しましたが、タイマーと組み合わせて利用すると、なんらかの情報を定期的にチャンネルにつぶやくボットが簡単に作れます。

nokogiri gem でスクレイピング

ニフクラスクリプトの Ruby では XML/HTML データを簡単に扱うことができる nokogori gem も利用可能です。
上記で紹介した httparty gem と組み合わせれば、

  • HTTP リクエストで任意のページを取得
  • 取得したページをパースして必要な情報を取得

といった処理を行うことができます。

下記では、httparty でニフクラスクリプトの技術仕様ページを取得したあと、nokogiri で利用可能なモジュールの一覧を取得し、
さらに httparty で Slack チャンネルにつぶやくような処理を実現しています。

require "rack"
require "httparty"
require "nokogiri"

SLACK_ENDPOINT = "https://slack.com/api/chat.postMessage"
SLACK_TOKEN = "<SLACK の API トークン>"
SLACK_CHANNEL = "<メッセージ送信先の Slack チャンネル>"
SLACK_USERNAME = "<Slack ボット名>"
SCRIPT_SPEC_URL = "https://cloud.nifty.com/spec/script/"

def call(env)
  res = Rack::Response.new

  text = "Node modules available at NIFCLOUD Script:\n"
  node_modules = get_node_modules
  node_modules.each do |m|
    text << "* #{m}\n"
  end

  slack_res = send_slack_message(text)

  res["Content-Type"] = "application/json"
  res.write(slack_res.body)
  res.finish
end

def send_slack_message(text)
  HTTParty.post(
    SLACK_ENDPOINT,
    query: {
      text: text,
      channel: SLACK_CHANNEL,
      token: SLACK_TOKEN,
      username: SLACK_USERNAME
    }
  )
end

def get_node_modules()
  body = HTTParty.get(SCRIPT_SPEC_URL).body
  doc = Nokogiri::HTML(body.force_encoding("utf-8"))
  tds = doc.search("table.tbl-01 tr td[1]")
  tds.map {|td| td.text }
end

実行するとこのような感じで Slack にメッセージが送信されます。
これで、ニフクラスクリプトで利用可能なライブラリが増えたときに、すぐに気づくことができますね。

f:id:tily:20180412172208p:plain

なお、スクレイピングはサイト管理者に迷惑をかけないように注意して行うようにしましょう。

まとめ

以上、ニフクラスクリプトの Ruby で利用可能なライブラリについて、いくつかピックアップしてご紹介しました。
その他の利用可能ライブラリについては技術仕様のページをご参照ください。
興味を持たれた方は、ぜひRuby 対応のサーバーレスサービス、ニフクラスクリプトをお試しください! フィードバックもお待ちしております。