1. daxanya1

    Posted

    daxanya1
Changes in title
+HubotからDigitalOceanAPIを叩いてみる
Changes in tags
Changes in body
Source | HTML | Preview

Hubot-scriptは、hubot経由で外部APIを叩く機能も多いですね。(本来それが目的のような気もします)

さて、最近1時間1円で話題のクラウドホスティングのDigitalOceanは、APIもシンプルでhubotから管理しやすそうなので、ちょっと試してみました。

準備

1.DigitalOceanのアカウントを取得します。参考URL
2.DigitalOceanにログインして、APIのページからClient IDとAPI Keyを取得します。
3.とりあえず1つサーバを立ち上げてみます。(DigitalOcean上のサーバ1つの単位をdropletと呼んでいるようです)

今回叩くAPI

DigitalOceanのAPIページを参考にします。

DigitaiOceanのAPIだけで、dropletを作って、電源OFFして、スナップショット取って、破棄するのができてしまうので、気づくとお金をちゃりんちゃりん払う事にもなります。

といっても最低構成のdropletだと、1時間1セント(最低金額が0.007$なのですが請求時に1セント未満は繰り上げられて0.01$になります)なので、そうそうたいしたことにはならないと思います。

でも最初ですので、プログラムがバグってて悪影響が出ても大丈夫なように、閲覧系のAPIだけ叩いてみましょう。

/droplets - Show All Active Droplets
/images - All Images
の2つのAPIを叩きます。

ちなみに、「APIを叩く」という表現は単純にDigitalOceanのAPIにアクセスするというだけのことです。

サンプルプログラム

モジュールを2つ使います。
APIを叩くのに、scoped-http-clientを利用しています。
また、APIを連続で叩く際に、ネストが深くならないように、async.jsを利用しています。
coffeescriptだと、インデントでcallback配列の制御ができるので楽でいいですね。

digitalocean.coffee
HttpClient     = require 'scoped-http-client'
async = require 'async'

CLIENT_ID = '__YOUR_CLIENT_ID__'
API_KEY = '__YOUR_API__KEY__'

class DigitalOcean
  constructor: (debug = false) ->

  get : (path, params, callback) ->
    params.client_id=CLIENT_ID
    params.api_key=API_KEY
    url = "https://api.digitalocean.com/#{path}/?"+("#{k}=#{v}" for k,v of params).join('&')
    console.log(url) if debug
    HttpClient.create(url)
      .header("User-Agent", "Hubot/#{@version}")
        .get() (err,res,body) =>
          try
            callback(JSON.parse(body))
          catch e
            console.log(e)
            console.log("can't load")

  check_api_status : (json) ->
    json.status == 'OK'

  show_droplets : (droplets) ->
    ("#{droplet.name}(#{droplet.id})" for droplet in droplets).join('\n')

  show_images : (images) ->
    ("#{image.name}(#{image.id})" for image in images).join('\n')

module.exports = (robot) ->
  api = new DigitalOcean(debug=false)

  robot.respond /digitalocean\s*(リスト|list)/i, (msg) ->
    async.waterfall [
      (callback)->
        api.get("droplets", {}, (json) ->
          if api.check_api_status(json)
            if (json.droplets.length > 0)
              msg.reply '今動いているdropletはこれだけありますー。\n' + api.show_droplets(json.droplets)
            else
              msg.reply '今はdropletは一つも立ち上がってないですー。'
            callback null
          else
            msg.reply "digitaloceanのdroplets_apiが正常に動いていないようですー。"
        )
      (callback)->
        api.get("images", {filter:"my_images"}, (json)->
          if api.check_api_status(json)
            if (json.images.length > 0)
              msg.reply '今動いている自前管理のimageはこれだけありますー。\n' + api.show_images(json.images)
            else
              msg.reply '今は自前管理のimageは一つもないですー。'
            callback null
          else
            msg.reply "digitaloceanのimages_apiが正常に動いていないようですー。"
        )
    ], (err) ->

package.jsonのdependenciesにも忘れず追加してください。

package.json
        :
        :  
  "dependencies": {
        :
    "scoped-http-client": "0.9.8",
    "async": "0.2.9",
        :
  },

動かし方

hubotの名前が、@hubotだとして、
@hubot digitalocean リスト」と話しかけましょう。

hubotがAPIを叩いて調べにいってくれます。名前とIDでdropletとsnapshotイメージについて教えてくれます。

こんな人にどうぞ

いちいちDigitalOceanのWEBページにログインして、リンククリックして…というのが面倒な人はぜひどうぞ。