HubotからGithubのissueを扱う

HubotからGithubのissueを扱う

http://shokai.org/blog/archives/9560

こちらコードに少し手を加えて、HubotからGtihub issueを扱えるようにしてみた。

create, list up, close github issues via hubot

使い方

Githubのトークンが必要:

$ curl -i https://api.github.com/authorizations -d '{"scopes":["repo"]}' -u "username"
$ heroku config:set HUBOT_GITHUB_TOKEN=token_value

TODO listとかブログ記事のネタとかのために使う。

  • hubot issue list

  • hubot issue create タイトル body コンテンツ

  • hubot close issueのナンバー(#)

Processing のエディタとして Atom を使う

Processing のコーディングを快適にするために、Atom を使ってみる。

Processing とは

ビジュアルアートを学ぶためのオープンソースのプログラミング言語であり、開発環境。Java でビルドされており、その構文は Java をシンプルにしたもの。

エディタも備わっているが、より快適にコーディングするために、Atom に Processing 用のパッケージを導入してみる。

インストールするパッケージ一覧

これらのパッケージをインストールする。

$ apm install processing processing-autocomplete processing-language

Processing の導入

まずは、こちらから Processing の開発環境をダウンロード。

Processingを立ち上げて、Toolsメニューからprocessing-java をインストールする。

which コマンドでパスを確認し、

$ which processing-java
/usr/local/bin/processing-java

processing の実行パスに設定する

実際に使ってみる

.pde ファイルを作成し、コーディングする。

ctrl-alt-b コマンドでビルドされれば、成功。

Atomのマークダウンプレビュー内で数式を扱う

Atomのマークダウンプレビュー内で数式を扱う

まずは必要な以下のパッケージをインストール

$ apm install markdown-preview-plus mathjax-wrapper

必要なパッケージ

マークダウン

文章を記述するための軽量マークアップ言語

Mathjax

さまざまな数式用のマークアップ言語を表示するJavaScriptエンジン

ドキュメント

マークダウンプレビュー内で数式を扱う

準備が完了したら、適当なマークダウンファイル(.md)を作成し、編集する:

<h3>The Quadratic Formula</h3>

\[ x = {-b \pm \sqrt{b^2-4ac} \over 2a} \]

<h3>The Cauchy-Schwarz Inequality</h3>

\[ \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \]

<h3>A Cross Product Formula</h3>

\[\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix}
\mathbf{i} & \mathbf{j} & \mathbf{k} \\
\frac{\partial X}{\partial u} &  \frac{\partial Y}{\partial u} & 0 \\
\frac{\partial X}{\partial v} &  \frac{\partial Y}{\partial v} & 0
\end{vmatrix}  \]

<h3>The probability of getting \(k\) heads when flipping \(n\) coins is</h3>

\[P(E)   = {n \choose k} p^k (1-p)^{ n-k} \]

<h3>An Identity of Ramanujan</h3>

\[ \frac{1}{\Bigl(\sqrt{\phi \sqrt{5}}-\phi\Bigr) e^{\frac25 \pi}} =
1+\frac{e^{-2\pi}} {1+\frac{e^{-4\pi}} {1+\frac{e^{-6\pi}}
{1+\frac{e^{-8\pi}} {1+\ldots} } } } \]

<h3>Maxwell’s Equations</h3>

\[  \begin{aligned}
\nabla \times \vec{\mathbf{B}} -\, \frac1c\, \frac{\partial\vec{\mathbf{E}}}{\partial t} & = \frac{4\pi}{c}\vec{\mathbf{j}} \\   \nabla \cdot \vec{\mathbf{E}} & = 4 \pi \rho \\
\nabla \times \vec{\mathbf{E}}\, +\, \frac1c\, \frac{\partial\vec{\mathbf{B}}}{\partial t} & = \vec{\mathbf{0}} \\
\nabla \cdot \vec{\mathbf{B}} & = 0 \end{aligned}
\]

Ctr+Shift+Mでマークダウンプレビューを、Ctr+Shift+Xで数式のレンダリングを起動する:

(そろそろ大きいディスプレイが必要)

終わり。

おまけ

いろいろググっていると、こんなサイトを見つけた。数学の質問を聞くことができるようだ。文系にはありがたい。英語が出来ればの話だが。

http://math.stackexchange.com/

webpack, React Hot Loader + Browsersync でクロスブラウジング+ホットリロード開発

React Hot Loader + Browsersync

React Hot Loader を使えば、エディタを保存した時点で、React コンポーネントの変更が検知され、ブラウザの更新が自動で行われます。さらに、React Hot Loader はHotModuleReplacementPlugin(HMR) を使用しているため、更新時にページの全読み込みが発生せず、state が保持されたまま React コンポーネントの変更した箇所のみが部分更新されるため、いちいち手動でブラウザをリロードする手間が省けることに加え、チェック毎に state を変える必要がなくなります。

通常はデベロップメントサーバーに webpack-dev-server を使うことで、このホットリローディング機能を使うことができるのですが、今回は Browsersync を使って、クロスブラウジングとさらなるホットリローディングの強化を目指します。Browsersync は、ファイル群の変更を監視して、ブラウザを自動で全読み込みしてくれます。また、他のデバイスからもブラウジングができる、クロスブラウジングを可能にしてくれます。これと、React Hot Loader を使えば、快適に React フロントエンドが開発できるようになります。

まとめると、次のようになります。

  • React Hot Loader : React コンポーネントの変更を監視し、変更があれば最小限のページ更新を行う。

  • Browsersync : js ファイル以外のファイルの変更を監視し、変更があればページの全読み込みを行う。クロスブラウジングを可能にする。

導入

まずは必要な物をインストールします。package.json は次のようになります。

"dependencies": {
  "react": "^0.13.3",
  "react-dom": "^0.14.7"
},
"devDependencies": {
  "babel-core": "^5.8.38",
  "babel-loader": "^5.4.0",
  "browser-sync": "^2.11.2",
  "react-hot-loader": "^1.3.0",
  "webpack": "^1.12.14",
  "webpack-dev-middleware": "^1.5.1",
  "webpack-hot-middleware": "^2.10.0"
}

通常の React Hot Loader に必要なライブラリに加えて Browsersyncwebpack-hot-middlewarewebpack-dev-middleware の ふたつのミドルウェアをインストールしておきます。webpack のホットリローディングは webpack-dev-middleware がファイル変更イベントを検知して webpack-dev-server に送信することで可能になりますが、 webpack-hot-middleware を合わせて使うことで、その他のデベロップメントサーバーにイベントを送信して、自動でブラウザをリロードさせることができます。

webpack config

プロジェクトファイルの構成:

|___app/
|     |___main.jsx
|___dist/
|     |___css/
|     |___index.html
|___server.js
|___webpack.config.js

まずは webpack.config.js を編集します。

下記は React Hot Loader での webpack.config.js です。

// React Hot Loader
var webpack = require('webpack');
var path = require('path');

module.exports = {
  debug: true,
  devtool: '#eval-source-map',

  entry: [
    'webpack-dev-server/client?http://localhost:3000',
    'webpack/hot/only-dev-server',
    './app/main.jsx'
  ],

  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: 'bundle.js'
  },

  plugins: [
    new webpack.HotModuleReplacementPlugin(),
  ],

  module: {
    loaders: [
      { test: /\.jsx?$/, exclude: /node_modules/, loaders: ['react-hot', 'babel'] }
    ]
  }
};

ここに、プラグインを2つ加えます。

plugins: [
    // Webpack 1.0
    new webpack.optimize.OccurenceOrderPlugin(),
    // Webpack 2.0 fixed this mispelling
    // new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
]

また、webpack-hot-middleware/client をエントリーポイントに設定します。

したがって、webpack.config.js ファイルは次のようになります。

var webpack = require('webpack');
var path = require('path');

module.exports = {
  debug: true,
  devtool: '#eval-source-map',

  entry: [
    'webpack/hot/dev-server',
    'webpack-hot-middleware/client',
    './app/main.jsx'
  ],

  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/',
    filename: 'bundle.js'
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NoErrorsPlugin()
  ],

  module: {
    loaders: [
      { test: /\.jsx?$/, exclude: /node_modules/, loaders: ['react-hot', 'babel'] }
    ]
  }
};

Browsersync

サーバーに、ミドルウェアを加えます。Browsersync を実行する server.js ファイルは次のようになります。

/**
 * Require Browsersync along with webpack and middleware for it
 */
var browserSync = require('browser-sync');
var webpack = require('webpack');
var webpackDevMiddleware = require('webpack-dev-middleware');
var webpackHotMiddleware = require('webpack-hot-middleware');

var webpackConfig = require('./webpack.config');
var bundler = webpack(webpackConfig);

browserSync({
    server: {
      baseDir: 'dist',

      middleware: [
        webpackDevMiddleware(bundler, {
          publicPath: webpackConfig.output.publicPath,
          stats: { colors: true }
          // http://webpack.github.io/docs/webpack-dev-middleware.html
        }),

        webpackHotMiddleware(bundler)
      ]
    },

    files: [
      'dist/css/*.css',
      'dist/*.html'
    ]
});
  • baseDir: サーバーのベースとなるディレクトリ。
  • middleware: 使用するミドルウェア。devMiddlewareではpublicPathの指定が必須となります。
  • files: Browsersync が変更を監視するファイル群。変更がなされると、ページ全体をリロードします。js ファイル群の監視は webpack に任せるので、ここに記述する必要はありません。

クロスブラウジング

次のコマンドで、サーバーが立ち上がります。

node server.js

同時に、次のような URL が表示されます。

[BS] Access URLs:
 ------------------------------------
       Local: http://localhost:3000
    External: http://{PCのIPアドレス}:3000
 ------------------------------------
          UI: http://localhost:3001
 UI External: http://{PCのIPアドレス}:3001
 ------------------------------------

この URL に繋げば、同じネットワークに接続している他のデバイスからも、ブラウジングすることができます。
モバイルデバイスからの UI や UX のチェックに便利です。

ソースコード

npmのバージョン管理まとめ

たまにしか活用しないから忘れるのでメモ

参考: semver | npm Documentation

バージョン管理

npmでは、「セマンティックバージョニング」と呼ばれるバージョン管理法によって、依存パッケージやリリース物のバージョンを定義している。

npmにあるプロジェクトは少し異なるものもあるが、他の人と共有するようなプロジェクトは、普通 1.0.0 から始めるべきだ。

このルールに加えて、プロジェクトに変更を行った時のバージョンは次のように扱われる。

  • バグの修正やその他のマイナーチェンジ: パッチリリースでは最後の数字をインクリメントする (e.g. 1.0.1)
  • 既存の機能を壊さないような新しい機能: マイナーリリースでは、真ん中の数字をインクリメントする (e.g. 1.1.0)
  • 後方互換性のない変更: メジャーリリースでは、最初の数字をインクリメントする (e.g. 2.0.0)

npm では依存パッケージを package.json ファイルで管理する。そこでは、パッケージのバージョンを範囲指定することもできる。

もし、あるパッケージ 1.0.4 を範囲指定する時、次のようになる。

  • パッチリリースの範囲指定: 1.0 / 1.0.x / ~1.0.4
  • マイナーリリースの範囲指定: 1 / 1.x / ^1.0.4
  • メジャーリリースの範囲指定: * / x

詳しくは、このエントリの最後の後半で説明する。

演算子を用いて、更に細かく範囲指定することができる。これを、comparatorと呼ぶ。

  • < 未満
  • <= 以下
  • > より大きい
  • >= 以上
  • = イコール(演算子の指定がなければ適応される)

例えば、>=1.2.71.2.7 / 1.2.8 / 2.5.3 / 1.3.9 に一致するが、1.2.6 / 1.1.0 には一致しない。

また、comparator はホワイトスペースで結合できる(comparator set)。範囲指定は、さらにこの comparator set を || で結合して示されることがある。

例えば、 >=1.2.7 <1.3.01.2.7 / 1.2.8 / 1.2.99 に一致するが、1.2.6 / 1.3.0 / 1.1.0 には一致しない。

1.2.7 || >=1.2.9 <2.0.01.2.7 / 1.2.9 / 1.4.6 には一致するが、 1.2.8 / 2.0.0には一致しない。

プレリリースタグ (Prerelease Tags)

もし、バージョンがプレリリースタグ(e.g. 1.2.3-alpha.3)を持っていれば、同じ [major, minor, patch] で、プレリリースタグを持つ comparator しか、指定できない。

例えば、 >1.2.3-alpha.31.2.3-alpha.7 に一致するが、 3.4.5-alpha.9 には、一致しない。この場合、バージョンの範囲指定は、1.2.3のプレリリースタグにのみ適応される。3.4.5はプレリリースタグを持たず、1.2.3-alpha.3 より大きいので、これは条件を満たす。

こうした振る舞いには2つの理由があり、ひとつはプレリリースバージョンは頻繁に更新され、多くの前衛的変更を含む。従って、デフォルトでは範囲指定から外されている。

また、プレリリースバージョンを使用することを選んだユーザーは、特定の alpha/beta/rc バージョンを使用する意思をはっきりと示すことができる。範囲指定にプレリリースタグを含めることで、ユーザーはそれを使用することのリスクを自覚していることを示している。

更に詳しく

Hyphen Rangees X.Y.Z - A.B.C

以上/以下の範囲指定:

  • 1.2.3 - 2.3.4 := >=1.2.3 <=2.3.4

最初と最後を含めて範囲指定する。欠けているものがあれば、0が代わりに使われる。

  • 1.2 - 2.3.4 := >=1.2.0 <=2.3.4
  • 1.2.3 - 2 := >=1.2.3 <3.0.0

X-Ranges 1.2.x / 1.x / 1.2.* /*

X / x / * はあらゆる数字の代わりになる。

  • * := >=0.0.0 (すべてのバージョン)
  • 1.x := >=1.0.0 <2.0.0 (メジャーバージョンの範囲指定)
  • 1.2.x := >=1.2.0 <1.3.0 (メジャーバージョン、マイナーバージョンの範囲指定)

Tilde Ranges ~1.2.3 / ~1.2 / ~1

Tilde rangesでは、comparator 上でマイナーバージョンを指定していれば、パッチレベルの変更は許容される。

  • ~1.2.3 := >=1.2.3 <1.(2+1).0 := >=1.2.3 <1.3.0
  • ~1.2 := >=1.2.0 <1.(2+1).0 := >=1.2.0 <1.3.0 (Same as 1.2.x)
  • ~1 := >=1.0.0 <(1+1).0.0 := >=1.0.0 <2.0.0 (Same as 1.x)
  • ~0.2.3 := >=0.2.3 <0.(2+1).0 := >=0.2.3 <0.3.0
  • ~0.2 := >=0.2.0 <0.(2+1).0 := >=0.2.0 <0.3.0 (Same as 0.2.x)
  • ~0 := >=0.0.0 <(0+1).0.0 := >=0.0.0 <1.0.0 (Same as 0.x)
  • ~1.2.3-beta.2 := >=1.2.3-beta.2 <1.3.0 (プレリリースタグの範囲指定は 1.2.3 上でのみ適応される)

Caret Ranges ^1.2.3 / ^0.2.5 / ^0.0.4

Caret ranges ではパッチとマイナーチェンジは許容される。

Caret ranges は 0.2.43.0.0 の間にブレイキングチェンジ(既存の機能の削除など後方互換性のない変更)があることを想定している。しかし、 0.2.40.2.5 の間にブレイキングチェンジが絶対にないと想定していることに注意する。

  • ^1.2.3 := >=1.2.3 <2.0.0
  • ^0.2.3 := >=0.2.3 <0.3.0
  • ^0.0.3 := >=0.0.3 <0.0.4
  • ^1.2.3-beta.2 := >=1.2.3-beta.2 <2.0.0
  • ^0.0.3-beta := >=0.0.3-beta <0.0.4

欠けている patchminor の値は 0 とみなし、それ以上のバージョンのパッチやマイナーの変更を許容する。

  • ^1.2.x := >=1.2.0 <2.0.0
  • ^0.0.x := >=0.0.0 <0.1.0
  • ^0.0 := >=0.0.0 <0.1.0
  • ^1.x := >=1.0.0 <2.0.0
  • ^0.x := >=0.0.0 <1.0.0

ブラウザでマルコフ連鎖を用いた文章を要約できる要約器を作った

ブラウザでマルコフ連鎖を用いた文章を要約できる要約器を作った

作ったもの

ブラウザでマルコフ連鎖(Website)

hubotでマルコフ連鎖(Twitter)

hubotはこんな感じのことを10分毎にツイートしている。

使用したもの

今回、要約器や要約スクリプトを作成するにあたって、markov-chain-kuromojiを作成した。

kuromoji.jsは、mecabと違ってJavaScriptのみで記述されているので、hubotへの組み込みが容易。

ソースコード

hubotのスクリプトは次の通り

cronJob = require('cron').CronJob
MarkovChain = require('markov-chain-kuromoji')

Twit = require 'twit'
client = new Twit({
  consumer_key: process.env.HUBOT_TWITTER_KEY
  consumer_secret: process.env.HUBOT_TWITTER_SECRET
  access_token: process.env.HUBOT_TWITTER_TOKEN
  access_token_secret: process.env.HUBOT_TWITTER_TOKEN_SECRET
})

module.exports = (robot) ->
  cronjob = new cronJob(
    cronTime: "00 00,10,20,30,40,50 * * * *"
    start:    true
    timeZone: "Asia/Tokyo"
    onTick: ->
      client.get 'statuses/home_timeline', {count: 200}, (err, tweets, response) =>
        if !err
          input = null
          for i in tweets
            input += "#{i.text}。"
          input = input.replace /。。/g, '。'
          input = input.replace /(https?:\/\/[\x21-\x7e]+)/g, ''
          input = input.replace /(@[\x21-\x7e]+)/g, ''
          input = input.replace /\s*/g, ''
          markov = new MarkovChain(input)
          markov.start(1, (output) =>
            robot.send {room:'Twitter'}, "#{output}"
          )
        else
          console.log err

  )

hubotの作成手順はこちら

uraway.hatenablog.com

  • node-cron : 10分ごとにツイートし、同時にホームライムラインのツイートの取得。15分に15回程度だったと思うが、TwitterAPIの制限[rate limit exceeded]に引っかかるかもしれないので適度に取得回数を調節する。
  • twit : ホームタイムラインのツイートを最大200件取得できる。

あとは適当に要らない記号等を正規表現で取り除いて、マルコフ連鎖モジュールで要約している。

タイムラインから取得したツイートやマルコフ連鎖モジュール内の要約用の辞書をデータベースに保存すれば、もっといろいろな文章ができそう。

Hubotでビットコインbotを作る

参考: http://qiita.com/hkusu/items/36ce56f3df4e7a0937cb

今回作ったもの

自然言語処理 bot (@hubot_uraway) | Twitter

必要なもの

  • Herokuのアカウントと基礎知識
  • TwitterのBot用アカウント
  • NPM

基本方針

  • Herokuにデプロイ(無料枠だと24時間のうち6時間スリープしてしまう)
  • リフォローする
  • 定期的にツイートする
  • リプライに返信する

こんな感じのbotを作ります。

Hubotジェネレーター

npmでインストールします。

$ npm install -g generator-hubot

Hubotの雛形を作成。

$ yo hubot
? Owner:
? Bot name:
? Description:
? Bot adapter: twitter-userstream

一旦Hubotを起動して、動作を確認しよう

$ ./bin/hubot
hubot> hubot ping
hubot> PONG

Twitterアプリケーションの登録

Bot用のアカウントを取得後、ログインしたまま https://apps.twitter.com/ にアクセスして、アプリケーションを登録し、次の情報を控えておきます。

  • Consumer Key (API Key)
  • Consumer Secret (API Secret)
  • Access Token
  • Access Token Secret

ローカルで動作させる

Hubot起動スクリプトを作成します。

local_run.sh

#!/bin/sh

export HUBOT_TWITTER_KEY="key"
export HUBOT_TWITTER_SECRET="key_secret"
export HUBOT_TWITTER_TOKEN="token"
export HUBOT_TWITTER_TOKEN_SECRET="token_secret"
export HUBOT_NAME = "hubotのスクリーンネーム"

bin/hubot -a twitter-userstream

起動スクリプトに実行権限を付与して、実行します。

$ chmod +x local_run.sh
$ ./local_run.sh

実行中はTwitter Hubotが常に起動しています。botスクリプトに変更を加えた時の確認に便利です。

Herokuにデプロイ

先ほどのlocal_run.shと同じ立ち上げ方をHeroku上で出来るようにしましょう。

Procfile

web: bin/hubot -a twitter-userstream

gitでコミットします。トークン等を記載しているので、local_run.shをコミットしないように注意しましょう。

$ git init
$ git add .
$ git commit -m "firs comment"

Herokuへプッシュします。

$ heroku create
$ git push heroku master

アプリケーションのページを確認します。エラーが出ているはずです。

$ heroku open

環境変数を追加してから、もう一度$ heroku openして、エラーが出ていなければ、Twitterで動作を確認しましょう。

$ heroku config:add HUBOT_TWITTER_KEY="key"
$ heroku config:add HUBOT_TWITTER_SECRET="secret"
$ heroku config:add HUBOT_TWITTER_TOKEN="token"
$ heroku config:add HUBOT_TWITTER_TOKEN_SECRET="token_secret"
$ heroku config:add HUBOT_NAME="hubotのスクリーンネーム"

このような表記であれば、Hubotは動作しています。

Botを作成する

scriptsディレクトリにスクリプトを記述したファイルを作成すれば、自動で読み取ってくれます。

次のことを実行するスクリプトを記述します。

  • リフォローする
  • 定期的にツイートする
  • リプライに返信する

リフォローする

Botをフォローしたユーザーをフォローし返すには、twitter-userstream が提供する followed イベントを使用します。

module.exports = (robot) ->
  robot.on 'followed', (event) ->
    robot.logger.info "followed #{event.user.name}!"
    robot.adapter.join event.user

定期的にツイートする

定期的にツイートするには node-cron を利用します。今回は node-zaif を使って取得したビットコインのlast_price(終値)をツイートするスクリプトを記述します。

cronJob = require('cron').CronJob
zaif = require('zaif.jp')
publicApi = zaif.PublicApi

module.exports = (robot) ->
  cronjob = new cronJob(
    # 実行する時間。今回は10分毎
    cronTime: "00 00,10,20,30,40,50 * * * *"
    # 自動発火するかどうか
    start:    true
    # タイムゾーン
    timeZone: "Asia/Tokyo"
    # cronが実行する関数
    onTick: ->
      publicApi.lastPrice('btc_jpy')
        .then (res) ->
          robot.send {room: 'Twitter'}, "1 BTC = #{res.last_price} JPY"
        .catch (e) ->
          robot.send {room: 'Twitter'}, "ERROR: #{e}"
  )

詳しくはそれぞれのドキュメントで。

リプライに返信する

便利なAPIが用意されているので、一度目を通す。正規表現でリプライの内容を取得できる。

module.exports = (robot) ->
  # 「おみくじ」リプライを受け取ると、結果をランダムにツイートする
  robot.respond /おみくじ/i, (msg) ->
    msg.send msg.random ["大吉", "中吉", "小吉", "凶"]
  # タイムラインに「疲れた」が流れると、「頑張って」とツイートする
  robot.hear /疲れた/i, (msg) ->
    msg.send "頑張って!"
  # 「x BTC」リプライを受けると、JPYを計算して結果を対象ユーザーに返信する
  robot.respond /(.*) BTC/i, (res) ->
    btc = res.match[1]
    publicApi.lastPrice('btc_jpy')
      .then (response) ->
        jpy = btc*response.last_price
        res.reply "#{btc} BTC = #{jpy} JPY"
      .catch (e) ->
        res.reply "ERROR: #{e}"
  「x JPY」リプライを受けると、BTCを計算して対象ユーザーに返信する
  robot.respond /(.*) JPY/i, (res) ->
    jpy = res.match[1]
    publicApi.lastPrice('btc_jpy')
      .then (response) ->
        btc = jpy/response.last_price
        res.reply "#{jpy} JPY = #{btc} BTC"
      .catch (e) ->
        res.reply "ERROR: #{e}"

最後に

このBot、Herokuの無料枠だと問題がある。

説明にある通り無料枠だと、

  • 30分間のアクセスがないとスリープ状態に
  • 24時間のうち、必ず6時間はスリープ

ひとつ目の、アクセスに関してはcronやこれを使えば問題なさそうだが、ふたつ目の問題は有料版を使う以外に解決策がない。うーん...

ソースコード

自然言語処理 bot (@hubot_uraway) | Twitter

ソースコード

MITライセンス。終値や計算結果、このbotを利用したことによる損害の責任を保証しない。