Rapsberry piとSQSでtweetスイッチを作る

日々生活をしていると、ストレスというものが貯まるらしい。
twitterについ心の闇を吐き出してしまうこともあるでしょう。

ただ、twitterは怖い所。
一時の感情でとんでもないつぶやきをしてしまって全世界へ公開されてしまう。
30分も経てば大体の怒りは収まり、ネガティブな発言をしてしまった事を後悔してしまう事もあるかもしれません。
恐ろしいですね。

ということで、そういったつぶやきは一旦キューに入れて保留しておきましょう。


# つぶやき保留装置概要
## 用意するもの
* AWSアカウント
上記アカウントのSQS操作が可能なアクセスキー+シークレットアクセスキー

* twitter APIキー
 参考 http://hello-apis.blogspot.jp/2013/03/twitterapi.html

【メッセージ受信＋tweet側】
* Raspberry pi（モデルは何でも）
* ブレッドボード、ジャンパワイヤー、スイッチ、抵抗、LED
　Raspberry Pi 電子工作入門キット（これでなくてもいいがひと通り揃っているので）
　http://www.amazon.co.jp/exec/obidos/ASIN/B00G86DOP8/hatena-blog-22/


## アーキテクチャ
【メッセージ送信】
SQSにメッセージを送るpythonスクリプトを実行

【メッセージ受信 & tweeet】
下記処理を行うpythonスクリプトを常に起動させておく
1. Raspberry pi側でスイッチ（物理）を押す
2. SQSからキューを取得
3. tweet

![raspberry_tweet_arc.png](https://qiita-image-store.s3.amazonaws.com/0/38286/7207d29a-019a-ce08-c350-67c517df2ae6.png "raspberry_tweet_arc.png")

#メッセージ送信
## 必要な環境
* Python2.6以上
* botoモジュールをインストール
  ``` pip install boto ```

## 送信用スクリプト
```sqs_send_queue.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import boto
import boto.sqs
from boto.sqs.message import Message

import sys
from sys import argv


def sqs_send_queue(aws_access_key, aws_secret_access_key, region, queue_name, queue_message):
    # boto.sqsへの認証
    conn = boto.sqs.connect_to_region(region,
                                      aws_access_key_id=aws_access_key,
                                      aws_secret_access_key=aws_secret_access_key)

    # Create or Get queue info
    queue = conn.create_queue(queue_name)

    # send
    queue.write(Message(body=queue_message))
    print "%s へ %s をいれました" % (queue_name, queue_message)


'''
[main function]
'''
if __name__ == '__main__':
    argvs = sys.argv
    argc = len(argvs)

    if not argc == 2:
        print u'Usage: python %s message' % argv[0]
        quit()

    # queueに入れるメッセージ
    queue_message = argvs[1]

    # 作成するqueueの名前
    queue_name = "evil_tweet"

    # アカウント情報
    aws_access_key = "access_key"
    aws_secret_access_key = "secret_access_key"
    region = "ap-northeast-1"

    # queue_nameへqueue_messageを送信
    sqs_send_queue(aws_access_key, aws_secret_access_key, region, queue_name, queue_message)
```

## 実行
```
$ python sqs_send_queue.py "馬鹿もーんっ・・・・！ 通るかっ・・・・！ こんなもん・・！"
evil_tweet へ 馬鹿もーんっ・・・・！ 通るかっ・・・・！ こんなもん・・！ をいれました
```

これで自分のAWSアカウントのSQSに"evil_tweet"キューが作成され、
キュー内に"馬鹿もーんっ・・・・！ 通るかっ・・・・！ こんなもん・・！"というメッセージを入れる事ができた。

![SQS_info.png](https://qiita-image-store.s3.amazonaws.com/0/38286/e313b731-f7ee-a9aa-fec7-3dfdbb787132.png "SQS_info.png")

# メッセージ受信

受信は **Raspberry pi** で行う

## Raspberry pi GPIO設定
GPIO:7(IN),11(OUT)に加え、6(GROUND)を-列に接続しておくことを忘れずに。
（IN/OUTのピン指してるのにうまく出来ない…となったので）
こんなかんじの配線
![IMG_0253.JPG](https://qiita-image-store.s3.amazonaws.com/0/38286/23f7bd56-933c-5edb-6320-53a7d648ce61.jpeg "IMG_0253.JPG")

## 必要な環境
* Python2.6以上
* 必要なパッケージ（ライブラリ）をインストール

|パッケージ|version|何に必要|
|:-----------|:-----------|:-----------|
|boto|2.32.1|sqs操作|
|RPi.GPIO|0.5.3a|Raspberry piのGPIO操作|
|requests|2.3.0|HTTPリクエスト操作|
|requests_oauthlib|0.4.1|requestsのOAuth認証サポート|
 
``` 
$ pip install boto
$ pip install RPi.GPIO
$ pip install requests requests_oauthlib
```

## 受信用スクリプト
``` tweet_switch.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import boto
import boto.sqs
from RPi import GPIO
import time
from requests_oauthlib import OAuth1Session

# raspberry pi switch
pi_switch = "False"


# evil_tweetからキューを取得
def sqs_get_queue():

    # AWS accesskey
    aws_access_key = "access_key"
    aws_secret_access_key = "secret_access_key"
    region = "ap-northeast-1"

    # SQS queue_name
    queue_name = "evil_tweet"

    try:
        # boto.ec2への認証
        conn = boto.sqs.connect_to_region(region,
                                          aws_access_key_id=aws_access_key,
                                          aws_secret_access_key=aws_secret_access_key)

        # Create or Get queue
        queue = conn.create_queue(queue_name)
        # Long Polling Setting
        queue.set_attribute('ReceiveMessageWaitTimeSeconds', 1)

        # fetch message
        msgs = queue.get_messages(1)
        for msg in msgs:
            tweet_message = msg.get_body()
            # delete message
            queue.delete_message(msg)

        return tweet_message

    except:
        GPIO.cleanup()


# tweetする
def tweet(message):
    CK = ''   # Consumer Key
    CS = ''   # Consumer Secret
    AT = ''   # Access Token
    AS = ''   # Accesss Token Secert

    # ツイート投稿用のURL
    url = "https://api.twitter.com/1.1/statuses/update.json"

    # 日本語ツイートできるように
    tweet = message.encode('utf-8')
    # ツイート本文
    params = {"status": tweet}

    # OAuth認証で POST method で投稿
    twitter = OAuth1Session(CK, CS, AT, AS)
    req = twitter.post(url, params=params)

    # レスポンスを確認
    if req.status_code == 200:
        print ("%s をtweetしました" % tweet)
    else:
        print ("Error: %d" % req.status_code)


if __name__ == '__main__':

    try:
        while True:
            # raspberry pi GPIO init
            GPIO.setmode(GPIO.BOARD)
            GPIO.setup(7, GPIO.OUT)
            GPIO.setup(11, GPIO.IN, pull_up_down=GPIO.PUD_UP)
            GPIO.output(7, False)
            input = GPIO.input(11)
            GPIO.output(7, not input)
            time.sleep(0.01)

            if input == 0 and pi_switch == "False":
                # 物理スイッチのフラグ(ON)
                pi_switch = "True"

                # メッセージを取得
                queue_message = sqs_get_queue()

                # typeがNoneでなければtweet
                if isinstance(queue_message, type(None)):
                    print "ないでキュー"
                else:
                    tweet(queue_message)

            elif input == 1:
                pi_switch = "False"

    except KeyboardInterrupt:
        GPIO.cleanup()
```

## 実行
```
$ sudo python tweet_switch.py
```

スイッチを押す

```
馬鹿もーんっ・・・・！ 通るかっ・・・・！ こんなもん・・！ をtweetしました
```

tweetされた
![tweet_bakamon.png](https://qiita-image-store.s3.amazonaws.com/0/38286/3741723a-1741-5871-9cd6-fc288c220d4c.png "tweet_bakamon.png")



もう一回押す

```
ないでキュー
```
キューがない場合は上記メッセージを出す。

以上をループしている。
supervisorで管理しておくと家帰ってスイッチ押すだけでツイートが可能になる。


# まとめ
スイッチをカチカチと押してアクションがあるという体験だけで結構ストレス発散にはなる。
もともとストレスなんて全くないですけどね！！\\(@o@)/

長くなった割に具体的にかけていないという残念感。
・tweetをする／しないの選択処理
・tweet失敗時の再送処理
ができていないので、最低限やっておきたい。


# 参考
sqs,tweet部分は下記ページをかなり参考にさせていただきました。
ありがとうございます。

Amazon SQSを効率よく処理するための簡単なサンプルコード
http://d.hatena.ne.jp/toritori0318/20130423/1366732268

Python で Twitter API にアクセス
http://qiita.com/yubais/items/dd143fe608ccad8e9f85