Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
33
Help us understand the problem. What is going on with this article?
@ie4

EC2(CentOS)にSkype用のボットを作る

More than 5 years have passed since last update.

Skypeにボットを飼おう

ものすごく今更ですが、Skypeにボットを招待する事にしてみました。
その際の作業メモです。

chatbot.gif
※ただし、ボットの反応がにぶい場合があります

EC2の構成

ボット小屋は、EC2(CentOS6)です。

skype4py-bot-house.gif

item value
region ap-northeast-1
AMI CentOS 6 (ami-25436924)

インストール

skype4py-install.gif

以下すべて、root権限でログインしている前提での、コマンド一覧です。

事前準備

事前に、必要なものを yum install しておきます。

ec2# yum install -y http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
ec2# yum install -y qtwebkit.i686 webkitgtk.i686 alsa-lib.i686 libXv.i686 libXScrnSaver.i686 gtk2-engines.i686 PackageKit-gtk-module.i686 libcanberra.i686 libcanberra-gtk2.i686 pulseaudio-libs.i686 alsa-plugins-pulseaudio.i686
ec2# yum install -y x11vnc ipa-gothic-fonts xauth Xvfb dbus-x11 wget

Skypeのインストール

インストール

ec2# cd /usr/src
ec2# wget http://www.skype.com/go/getskype-linux-beta-dynamic -O skype-4.3.0.37.tar.bz2
ec2# tar xjvf /usr/src/skype-4.3.0.37.tar.bz2 -C /usr/local
ec2# dbus-uuidgen > /var/lib/dbus/machine-id
ec2# ln -s /usr/local/skype-4.3.0.37 /usr/local/skype
ec2# ln -s /usr/local/skype /usr/share/skype
ec2# ln -s /usr/local/skype/skype /usr/local/bin/skype
ec2# useradd skype
ec2# mkdir /var/db/skype /var/run/skype/ /var/log/skype/
ec2# chown skype:skype /var/db/skype /var/run/skype/ /var/log/skype/

起動スクリプトの作成

以下のような起動スクリプトを作成します。

/etc/init.d/skype
#!/bin/bash
#
# Init file for daemonized Skype service
#
### BEGIN INIT INFO
# Provides:          skype
# Required-Start:    $local_fs $remote_fs $network
# Required-Stop:     $local_fs $remote_fs $network
# Default-Start:     3 4 5
# Default-Stop:      0 1 2 6
# X-Interactive:     false
# Short-Description: Start/stop daemonized Skype service
### END INIT INFO
#
# chkconfig: 345 80 10
#
# processname: skype
#
# pidfile: /var/run/skype.pid
#

if [ -r /etc/rc.d/init.d/functions ]; then
    . /etc/rc.d/init.d/functions
    log_daemon_msg() {
        msg=$1
        prog=$2
        echo -n $"$msg $prog: "
    }
    log_end_msg() {
        if [ "$1" = "0" ]; then
            success
        elif [ "$1" = "1" ]; then
            failure
        fi
        echo
    }
elif [ -r /lib/lsb/init-functions ]; then
    . /lib/lsb/init-functions
else
    echo "Could not find a helper script needed to run this script."
    exit 1
fi

DAEMON_USER=skype
PROGNAME=`basename $0`
PIDFILE=/var/run/skype.pid
XSERVERNUM=20
XAUTHFILE=/home/skype/.Xauthority
LOGFILE=/var/log/skype/error.log
DBPATH=/var/log/skype/
XAUTHPROTO=.
SKYPE=/usr/local/skype-4.3.0.37/skype
USERNAME= # ボット用のskypeカウントを記載してください
PASSWORD= # ボット用のskypeカウントのパスワードを記載してください

[ -f /etc/sysconfig/skype ] && . /etc/sysconfig/skype

prog="skype"
RETVAL=0

dircheck() {
    if [ ! -d `dirname "$1"` ]; then
        echo "`dirname \"$1\"` does not exist"
        return 1
    else
        return 0
    fi
}

start() {
    log_daemon_msg "Starting" "skype"
    if ! dircheck "$LOGFILE" || ! dircheck "$XAUTHFILE"; then
        log_end_msg 1
        echo
        RETVAL=1
        return 
    fi 
    MCOOKIE=`mcookie` && \
    sudo -u "$DAEMON_USER" env XAUTHORITY=$XAUTHFILE sh -c "xauth add \":$XSERVERNUM\" \"$XAUTHPROTO\" \"$MCOOKIE\" >> \"$LOGFILE\" 2>&1" && \
    sudo -u "$DAEMON_USER" env XAUTHORITY=$XAUTHFILE sh -c "Xvfb :$XSERVERNUM -screen 0 800x600x8 -nolisten tcp >> \"$LOGFILE\" 2>&1 & echo \$!" >"$PIDFILE" &&
    sleep 3 && \
    ( sudo -u "$DAEMON_USER" env LD_LIBRARY_PATH=/usr/local/skype-4.3.0.37/:$LD_LIBRARY_PATH DISPLAY=:$XSERVERNUM XAUTHORITY=$XAUTHFILE SKYPE="$SKYPE" sh -c "echo \"$USERNAME $PASSWORD\" | nohup \"$SKYPE\" --dbpath=\"$DBPATH\" --pipelogin &") >> "$LOGFILE" 2>&1 && \
    (log_end_msg 0 && [ -d /var/lock/subsys ] && touch /var/lock/subsys/skype || true) \
        || (RETVAL=$?; kill -TERM `cat $PIDFILE`; log_end_msg 1)
}

stop() {
    log_daemon_msg "Stopping" "skype"
    if [ -e "$PIDFILE" ]; then
        kill -TERM `cat $PIDFILE` && \
        rm -f $PIDFILE && \
        if [ -d /var/lock/subsys ]; then rm -f /var/lock/subsys/skype; fi && \
        log_end_msg 0 || log_end_msg 1
    else
        log_end_msg 1
        RETVAL=1
    fi
}

usage() {
    echo "Usage: $PROGNAME {start|stop|restart}"
}

case $1 in
    start)
        start
        ;;
    stop)
        stop
        ;;
    restart)
        stop
        start
        ;;
    *)
        usage
        RETVAL=255
        ;;
esac

exit $RETVAL

実行権限を付与しておきます。

ec2# chmod +x /etc/init.d/skype

Skypeの起動

ec2# /etc/init.d/skype start

VNCでアクセスする

iptables の設定

VNCで利用する 5900番ポート を解放しましょう。
※よく分からない場合は、22番ポートの行をコピペして、5900番ポートの行を追加

ec2# vi /etc/sysconfig/iptables
ec2# service iptables restart

VNCを起動

ec2# x11vnc -display :20

起動したVNCに、VNC Viewerでアクセス

TigerVNC プロジェクト日本語トップページ - SourceForge.JP から、クライアントソフトをダウンロードし、インストールします。

現在ログインしているEC2インスタンスのグローバルIPアドレスは、下記のコマンドで確認できます。

ec2# curl http://169.254.169.254/latest/meta-data/public-ipv4;echo

TigerVNC Viewer を立ち上げて、(EC2のIPアドレス):5900 に接続
VNC-Viewer-Access.gif

接続出来たら、言語を選んで「同意する」をクリック
VNC-Skype-01.gif

サインイン画面が出ますが、そのままにしておくと
起動スクリプトに記載したUSERNAME/PASSWORDで、
勝手にログインします。
VNC-Skype-02.gif

ログイン後の画面が出たら、VNC Viewerはしばらくそのままで
サーバー側の作業に戻ります。

ボットとの会話

Skype4Pyのインストール

ec2# wget https://pypi.python.org/packages/source/d/distribute/distribute-0.6.49.tar.gz
ec2# tar xpvf distribute-0.6.49.tar.gz
ec2# python distribute-0.6.49/setup.py install
ec2# easy_install Skype4Py

ボットスクリプトを書く

サンプルとして、
「ボット」と呼びかけると
「|ΦωΦ) ...」と返すスクリプトを書きます。

bot.py
# encoding: utf-8

import Skype4Py
import time

def handler(msg, event):
    if event == u"RECEIVED":
        if msg.Body == u"ボット":
            msg.Chat.SendMessage(u"|ΦωΦ) ...")

def main():
    skype = Skype4Py.Skype(Transport='x11')
    skype.OnMessageStatus = handler
    skype.Attach()
    while True:
        time.sleep(1) 

if __name__ == "__main__":
    main()

ボットを起動する

ec2# export DISPLAY=:20;
ec2# python bot.py

そのままにしておいた VNC Viewer 側に、
下記のようなメッセージが表示されるので、
“この選択を記憶する”にチェックを入れ、「はい」をクリック。
VNC-Skype-03.gif

他のスカイプから、ボットに話しかけてみる

unnamed.png

よくできました☆

後片づけ

VNCサーバーは、終了させておきましょう。
(Skypeは起動したままなので、問題ありません)

ボットを育成する

ボットに色々な反応をインストールしてみましょう。

# encoding: utf-8

import Skype4Py
import time
import re # ←追加

def handler(msg, event):

    if event == u"RECEIVED":

        #---- 完全一致
        if msg.Body == u"おれが":
            msg.Chat.SendMessage(u"お前で")
            return

        #---- 検索
        if re.search(u"お前が", msg.Body, re.S):
            msg.Chat.SendMessage(u"おれで")

        #---- 複数行
        if re.search(u"起きろ", msg.Body, re.S):
            gataMsg = u"""     オハヨー!!
    ∧∧ ∩
    (`・ω・)/
   ⊂  ノ
    (つノ
     (ノ
 ___/(___
/  (___/
 ̄ ̄ ̄ ̄ ̄ ̄
"""
            msg.Chat.SendMessage(gataMsg)

        #---- 一覧抽出
        if re.search(u'おれ', msg.Body, re.S):
            list = re.findall(u'おれ', msg.Body, re.S)
            cnt = len(list)
            msg.Chat.SendMessage(u"【自意識過剰警報】 おれ: "+str(cnt))

        #---- 文字列置換
        # note: python 2.6系だと re.sub で flags が使えない...
        #       http://docs.python.jp/2/library/re.html#re.sub
        if re.search(u'おれ', msg.Body):
            lines = msg.Body.splitlines()
            msg.Chat.SendMessage(u'理解した。')
            for line in lines :
                you = re.sub(u'お前', u'-お前-', line)
                you = re.sub(u'おれ', u'お前', you)
                you = re.sub(u'-お前-', u'おれ', you)
                msg.Chat.SendMessage(you)
            msg.Chat.SendMessage(u'だな。')

def main():
    skype = Skype4Py.Skype(Transport='x11')
    skype.OnMessageStatus = handler
    skype.Attach()
    while True:
        time.sleep(1) 

if __name__ == "__main__":
    main()

skype-bot-chat-05.gif

ボットをグループに招待する

Skypeチャットには、「クラウドベース」と「P2Pベース」のモノがあり
最近作られたグループは、「クラウドベース」のチャットになるようです。

『チャットのコマンドと役割を教えてください。- Skype Support FAQ』
https://support.skype.com/ja/faq/FA10042/

・・・で、
SkypeApiの仕様なのか、Skype4Pyの仕様なのか、はたまた自分の書き方の問題か
「クラウドベース」のグループだと、ボットがグループを上手く認識してくれませんでした。

そこで、
“グループにボットを招待”したり
“ボットがグループにメッセージを通知”したりしたい場合は
「P2Pベース」を利用する事にします。

現在開いているグループが
「クラウドベース」なのか「P2Pベース」なのかを確認するには
メッセージ入力欄から、下記のコマンドを投げます。

/get name

上記Skype-FAQページの説明から、下記の通り判別できるようです。

グループ名の応答の先頭が「19:...」である場合はクラウドベースのチャットを使用しています。グループ名の応答の先頭が「#skypename...」である場合はP2Pベースのチャットを使用しています。

「P2Pベース」のグループを作成するためには、
メッセージ入力欄(どこのチャットでもOK)から、下記のコマンドを投げます。

/createmoderatedchat

可能であれば、ボット自身がこのコマンドを投げるのが望ましいです。
(常駐しているボットが、管理者になれる為)

VNC Viewer からやるのも面倒ですので、お使いのPCでボットアカウントにログインして
そこで作業するのが良いかと思います。

新しく作成された「P2Pベース」のグループに、メンバーを追加していきましょう。

メッセージを通知する

せっかくなので、受動的に反応させるだけじゃなく、
能動的にボットの方から、通知なんてのもさせてみたいですよね。

ユーザーへ

通知先のユーザー名のところは適宜変更してください。
スケジューラー等に、下記のコマンドを登録しておくことで、
任意のタイミング(定刻、イベント発生等)に
メッセージを通知させることが可能で、
リマインダーやアラート通知として利用できます。

※事前に、ボットとユーザーで連絡先リストの登録をしておく必要があるかも(未確認)

通知スクリプト

send_message_for_user.py
# -*- coding: utf-8 -*-
import Skype4Py
import sys

user = 'username' # 要書き換え

argvs = sys.argv
acnt = len(argvs)

skype = Skype4Py.Skype(Transport='x11')
skype.Attach()

msg = argvs[1] if acnt > 1 and argvs[1] else '元気?'

chat = skype.CreateChatWith(user)
chat.SendMessage(msg)

通知コマンド

ec2# export DISPLAY=:20;
ec2# python send_message_for_group.py 'あと30分でアニメが始まります'

グループへ

グループへの通知は、やや特殊で
所属しているチャットの一覧から対象のグループを探し出し
該当のグループである場合にのみ、メッセージ通知するようにしています。

通知スクリプト

send_message_for_group.py
# -*- coding: utf-8 -*-
import Skype4Py
import sys

argvs = sys.argv
acnt = len(argvs)

skype = Skype4Py.Skype(Transport='x11')
skype.Attach()

msg = argvs[1] if acnt > 1 and argvs[1] else '元気?'

for chat in skype.Chats :
    if chat.Name == '#skype_group_name/$1234567890abcdef': # 要書き換え
        chat.SendMessage(msg)

通知コマンド

ec2# export DISPLAY=:20;
ec2# python send_message_for_group.py 'みなさん、お昼の時間です。'

最後に

業務に使用する場合などは、くれぐれもセキュリティ面に気を付けてください。

参考にしたサイト

■ aws marketplace : CentOS 6 (x86_64) - with Updates
https://aws.amazon.com/marketplace/ordering?productId=adc4348e-1dc3-41df-b833-e86ba57a33d6
※CentOS6のAMIは、コチラから

■ CentOS6.3にSkypeBot(Skype4Py)を構築 [2013/03/09]
https://mistymagich.wordpress.com/2013/03/09/centos6-3%E3%81%ABskypebot%E3%82%92%E6%A7%8B%E7%AF%89/
※Skype起動スクリプトは、コチラを流用させて頂きました

■ Linux上で動くSkype用のbotを作る方法 [2010/09/26]
http://d.hatena.ne.jp/moriyoshi/20100926/1285517353
※Skype4Pyを使ったサンプルBotスクリプトは、コチラのスクリプトを流用させて頂きました

33
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ie4
IoTっぽい記事多めです。
iotlt
IoT縛りの勉強会です。 毎月イベントを実施しているので是非遊びに来てください! 登壇者を中心にQiitaでも情報発信していきます。 https://iotlt.connpass.com

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
33
Help us understand the problem. What is going on with this article?