Skip to content

Instantly share code, notes, and snippets.

@udzura

udzura/slide.md Secret

Last active August 29, 2015 14:01
Show Gist options
  • Save udzura/970e2d2ff79d20a963bf to your computer and use it in GitHub Desktop.
Save udzura/970e2d2ff79d20a963bf to your computer and use it in GitHub Desktop.
Hubotによるやわらかプログラミング

Hubotによるやわらかプログラミング

始めに、地図を描く

Joel on Software - 5つの世界

  • パッケージ
  • インターナル
  • 組み込み
  • ゲーム
  • 使い捨て

パッケージ && Webサービスの世界の地図

  • Windows と UN*X
  • クライアントとサーバー
  • アプリとバッチ
  • ブラウザとネイティブ

演習

  • プログラミング言語を地図の上に置く
    • Ruby
    • JavaScript
    • Perl
    • Python
    • PHP
    • Java
    • Haskell
    • C
    • C++
    • Lua
    • Objective-C
    • C#
    • VisualBasic

教訓

  • プログラミングでできることは果てしなく広い
  • 何のためにプログラミングをするかが重要、目的がはっきりしていればそれに向いた言語を学べ、学習が効率的になる

CoffeeScriptとHubot

今日の仮の目的

  • どのプログラミング言語でも使えるような基本中の基本を学ぶ
  • なるべく短い時間でSUGEEE経験をする
  • なるべく身近な役立つツールを作る

CoffeeScriptとは

  • 「スクリプト言語」
  • JavaScriptに変換できる言語
  • JavaScriptなので、サーバ(node.js)、クライアント(ブラウザやTitanium)、バッチ(Grunt)に使えて便利

言語的に難解すぎない割にモダンな特徴を持っている

  • たとえば
    • オブジェクト指向
    • 無名関数
    • 非同期
    • 動的型付け
  • JavaScript、Ruby、Pythonにステップアップできる(と思う

Hubotとは

  • 「Bot」のための「フレームワーク」
  • 「フレームワーク」は雑な言い方をすれば、ソフトウェアを作るためのソフトウェア
  • 皆さんが今後毎日使うIRCのBotを簡単に作る
  • IRC以外にも、HipchatなどAPIの公開されたチャットサービスの多くで使えるようになっている(skypeはもうすぐ使えなくなる、残念!)

セットアップとHello, world

CoffeeScriptのインストール

  • まず、JavaScriptを入れる
    • 同じ言語でも、いろいろな実装があることを覚えておく。今回はnode.js
  • 次にnpmをインストール

そしたら

  • やっとhubotをインストール
$ npm install -g coffee-script hubot

Windowsの方...

エディタのインストール

  • ファイルの編集
  • Vim, Emacs, 別にいいけど...今日教えること何もありません
  • 秀丸、TeraPad、さくらエディタ、たぶんJavaScriptなんで使えるけど...
  • それっぽいのなら Sublime Text 評価版だが、永遠に使える...

Hubotのプロジェクトを作る

  • コマンドライン操作
  • PATHを通す必要があるかも
$ hubot -c yawaraka-hubot

Hello, hubot

  • shellアダプター
  • デフォルトの機能(pingとかyoutubeとか)
$ cd yawaraka-hubot
$ npm install
$ echo "[]" > hubot-scripts.json
["redis-brain.coffee", "shipit.coffee"] -> []
$ ./bin/hubot
Hubot> 
Hubot> hubot, ping
Hubot> PONG

IRC に接続する

$ npm install --save hubot-irc

スクリプトをいじる

#!/bin/sh

export PATH="node_modules/.bin:node_modules/hubot/node_modules/.bin:$PATH"

npm install

export HUBOT_IRC_SERVER="irc.paperboy.co.jp" # サーバ名
export HUBOT_IRC_PORT=6668 # ポート
export HUBOT_IRC_ROOMS="#bot_test" # channel
export HUBOT_IRC_NICK="hubot-udzura" # ニックネーム
export HUBOT_IRC_PASSWORD="paperb0y" # パスワード
export HUBOT_IRC_USESSL="true" # SSLを使う
export HUBOT_IRC_SERVER_FAKE_SSL="true" # SSLが社内独自なので
export HUBOT_IRC_SEND_NOTICE_MODE="true" # 全発言をNotice
export HUBOT_IRC_DEBUG="true" # デバッグ

exec node_modules/.bin/hubot "$@"

Windowsの

@echo off

SET HUBOT_IRC_SERVER=irc.paperboy.co.jp
SET HUBOT_IRC_PORT=6668
SET HUBOT_IRC_ROOMS=#bot_test
SET HUBOT_IRC_NICK=hubot-udzura
SET HUBOT_IRC_PASSWORD=paperb0y
SET HUBOT_IRC_USESSL=true
SET HUBOT_IRC_SERVER_FAKE_SSL=true
SET HUBOT_IRC_SEND_NOTICE_MODE=true
SET HUBOT_IRC_DEBUG=true

npm install && node_modules\.bin\hubot.cmd %*

起動?どう?

./bin/hubot-irc

Bot完成!おめでとう!

Hubot script を書く

CoffeeScript入門

$ coffee
coffee> 1 + 2
coffee> 3 * 9
coffee> Math.power 3, 2

coffee> process.exit()

言語の基本

  • 制御構造
  • データ構造

関数

power2 = (num) ->
  num * num

分岐(if)

is_odd_even = (num) ->
  if num % 2 == 0
    'even'
  else
    'odd'

繰り返し

for i in [1 .. 10]
  console.log "Hello! #{i}"

1, 2, 3 #=> 整数
1.2, 3.45 #=> 小数
"Coffee" #=> 文字列

(val) -> console.log(val)
#=> 関数、手続き

配列

fib = [1, 1, 2, 3, 5, 8]
branches = ["Tokyo", "Fukuoka", "Kyoto"]

連想配列

{
  "lolipop": "Fukuoka",
  "minne": ["Fukuoka", "Tokyo", "Kyoto"],
  "suzuri": "Tokyo"
}
  • オブジェクト、ハッシュテーブル、辞書、などとも

Hubotスクリプトを書く

$ open scripts/yawaraka.coffee

なかみ

# Description:
#   説明を書く
#
# Commands:
#   コマンドの説明を書く
#   hubot hello, I am <名前> - <名前> に挨拶をする
#
module.exports = (robot) ->
  robot.respond /hello, I am (.*)/i, (msg) ->
    # この中で処理を書く
    name = msg.match[1] # () の中が取れる
    msg.send "Test" # 発言をする
    msg.send "ちょりーっす、 #{name}"
    
  robot.respond /goodbye (.*)/i, (msg) ->
    # いくつでもコマンドを追加できる

試し方

$ ./bin/hubot
Hubot> hubot, hello ...
# ローカルで試してからIRCでも試す!

ほらちゃんにだけツンデレbot

module.exports = (robot) ->
  robot.respond /hello, I am (.*)/i, (msg) ->
    name = msg.match[1]
    if name == "horaotoko"
      msg.send "べ、別にあんたに挨拶なんかしたくないんだからねっ!"
    else
      msg.send "ちょりーっす、 #{name}"

局長にだけテンションが高いbot

module.exports = (robot) ->
  robot.respond /hello, I am (.*)/i, (msg) ->
    name = msg.match[1]
    if name == "kyokutyo"
      for i in [1 .. 3]
        msg.send "ちょりーっす、 #{name}"
    else
      msg.send "ちょりーっす、 #{name}"

うらないボット

random = (n) -> Math.floor(Math.random() * n)

module.exports = (robot) ->
  robot.respond /今日の運勢/i, (msg) ->
    fortunes = [
      '大吉',
      '末吉',
      '大凶'
    ]
    result = fortunes[random(3)]
    msg.send "今日の運勢: #{result}"

他己紹介ボット

module.exports = (robot) ->
  robot.respond /about (.*)/i, (msg) ->
    name = msg.match[1]
    profiles = {
      'udzura' : '基盤ティーム',
      'horaotoko' : '3.5期生',
      'kyokutyo' : '隠れ変態'
    }
    result = profiles[name]
    if result
      msg.send "#{name}さんのプロフィール: #{result}"
    else
      msg.send "#{name}さんのことなんて知りません"

課題

  • (1) 電卓ボット(記号を見て四則計算する)
  • (2) 現在時刻を教えてくれるボット
now = new Date
now.toString()
now.getFullYear(), now.getFullYear(), now.getDay() #...
  • (3) クイズを出すボット

応用編

tiqav 画像検索ボット

Web API

  • 外部サービスと連携する!!
  • あたらしいnpmモジュールを入れる
$ npm install --save request

実装の例

module.exports = (robot) ->
  robot.respond /tiqav (.*)/i, (msg) ->
    request = require('request');
    request.get("http://api.tiqav.com/search.json?q=#{msg.match[1]}", (error, response, body) ->
      if error or response.statusCode != 200
        return msg.send('画像検索に失敗しました...')
      data = JSON.parse(body)[0]
      # robot.logger.info data
      msg.send "画像の様子です: http://img.tiqav.com/#{data.id}.#{data.ext}" )

デプロイをする

  • デプロイ=配備
  • 準備OKにする

デーモン化する必要性

  • 皆さんの使うプログラムは、人間が立ち上げ、人間が終了させる(アプリケーション)
  • 今回は、ボットなので、ずっと立ち上がっていなければいけない
  • ずっと立ち上がっているプログラムをサーバとかデーモンと呼ぶ

社内ツール専用のPaaS - Dokku

セットアップ(簡易)

Host dokku001.tokyo.pb
    HostName dokku001.tokyo.pb
    User dokku
    IdentityFile ~/.ssh/id_dsa.pb
  • Procfile を編集
web: bin/hubot-irc -a irc

Gitでデプロイ

$ git init .
$ git add .
$ git commit
$ git remote add dokku dokku@dokku001.tokyo.pb:udzura-hubot
$ git push dokku master

デモ

終わりに

いい話

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment