Cloudwatch Alarmをchatworkで受け取りたい

# Alarmをメールで受けるのイヤなんじゃ・・・
slack だと、Lambdaで便利なブループリントが提供されてるんですけどね・・・
chatwork使わざるをえない環境なんで・・・


:thinking::thinking::thinking:
Cloudwatch Alarm:arrow_heading_down:
SNS:arrow_heading_down:
Lambda:arrow_heading_down:
Chatwork :bulb:
:smile::smile::smile::smile:

って良くあるパータンの。


# 手順
## 1. Lambda Function作成
python3で。

```python
import boto3
import json
import logging
import os
import pprint

from base64 import b64decode
from urllib.request import Request, urlopen
from urllib.error import URLError, HTTPError
from urllib.parse import urlencode

APIKEY = os.environ['APIToken']
ROOMID = os.environ['RoomID']
ENDPOINT = 'https://api.chatwork.com/v2/'
post_message_url = '{}/rooms/{}/messages'.format(ENDPOINT, ROOMID)

logger = logging.getLogger()
logger.setLevel(logging.INFO)
logger.info("post_message_url: " + str(post_message_url))

def lambda_handler(event, context):
    logger.info("Event: " + str(event))
    message = json.loads(event['Records'][0]['Sns']['Message'])
    logger.info("Message: " + str(message))

    alarm_name = message['AlarmName']
    #old_state = message['OldStateValue']
    new_state = message['NewStateValue']
    reason = message['NewStateReason']

    chatwork_message = {
        'body': "[info][title]{0} state is now {1}[/title][code]{2}[/code][/info]" .format(alarm_name, new_state, reason)
    }
    chatwork_message = urlencode(chatwork_message).encode("utf-8")

    try:
        headers = {"X-ChatWorkToken": APIKEY}
        request = Request(post_message_url, data=chatwork_message, method="POST", headers=headers)
        
        with urlopen(request) as response:
            result = json.loads(response.read().decode("utf-8"))
            logger.info("TEST %s", result)
            info = dict(response.info())
            logger.info("TEST2 %s", info)

        logger.info("Message posted to %s", ROOMID)
        #logger.info("Message: %s", resp.content)
    except HTTPError as e:
        logger.error("Request failed: %d %s", e.code, e.reason)
    except URLError as e:

```

### テストケース
どこぞで拾ったテストケース、使わせて頂きました。
他にも探したけど、良さそうなの見つからなかった。

```json
{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:EXAMPLE",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "1970-01-01T00:00:00.000Z",
        "Signature": "EXAMPLE",
        "SigningCertUrl": "EXAMPLE",
        "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
        "Message": "{\"AlarmName\":\"awsrds-app-High-DB-Connections\",\"AlarmDescription\":\"Alarm when CPU exceeds 50 percent\",\"AWSAccountId\":\"123456789123\",\"NewStateValue\":\"ALARM\",\"NewStateReason\":\"Threshold Crossed: 1 datapoint (10.0) was greater than or equal to the threshold (10.0).\",\"StateChangeTime\":\"2016-07-24T22:05:19.737+0000\",\"Region\":\"US West - Oregon\",\"OldStateValue\":\"OK\",\"Trigger\":{\"MetricName\":\"DatabaseConnections\",\"Namespace\":\"AWS/RDS\",\"Statistic\":\"AVERAGE\",\"Unit\":null,\"Dimensions\":[{\"name\":\"DBInstanceIdentifier\",\"value\":\"app\"}],\"Period\":300,\"EvaluationPeriods\":1,\"ComparisonOperator\":\"GreaterThanOrEqualToThreshold\",\"Threshold\":10.0}}",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "EXAMPLE",
        "TopicArn": "arn:aws:sns:EXAMPLE",
        "Subject": "TestInvoke"
      }
    }
  ]
}
```


# この後の手順
SNSトピックを作って、サブスクリプションを定義して
Cloudwatch Alarmのアクションで指定して、
って感じになると思うけど、探せば色々資料出てくるので割愛。


# 課題
- RDSのAlarmとか、多分適宜捕まえてもうちょっと見やすく改変する必要がある。
- 厳密にテストしてない。alarm頻発してる場合とか。