3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python初心者がチャットワークのRESTful APIで遊んでみた

Last updated at Posted at 2018-08-16

たぶん何番煎じかわからないけど、最小構成Red Hat系OSの上でREST APIを叩く機会があり、手持ちの言語だと追加ライブラリなしで実装できなくてcurlでゴリゴリ書いて凌いだことがあったけど、Pythonだと標準ライブラリでできるらしいので試してみた。

想定している読者

  • Pythonは初心者
  • 制御構文とか関数とかプログラミングの基本的なことは完全にマスター()
  • Pythonの配列とか辞書(連想配列)は何となく知っている
  • RESTful APIが何かは知っている

2019.05.29追記: ビジネスプランの場合のAPI利用申請について追記

TL;DR

  • Python2.7 (OSインストール後の標準環境はまだ2.7系の模様)
  • 追加ライブラリなし
  • API Tokenはチャットワークの設定メニューから取得
  • HTTPアクセスには標準のurllib2ライブラリを使用
  • レスポンスのJSON解析は標準のjsonライブラリを使用
  • 今回実行したAPIは以下の2つ
    • ルーム一覧の取得(GET)
    • 「マイチャット」にメッセージ投稿(POST)

API Tokenの取得

小難しいOAuthなどは不要。
Webのチャットワークにログインし、設定メニューから「API設定」を選択。

2018-08-16_07h25_38.png

画面にチャットワークのログインパスワードを入力すればTokenの文字列が表示される。

2018-08-16_06h41_47.png


2019.05.29 追記

上記はフリープラン(おそらくパーソナルプランも)の場合。
ビジネスプランの場合は、APIトークンの取得には「管理者」の許諾が必要。

2019-05-14_21h55_32.png

利用申請画面で[API利用申請]ボタン押下すれば、設定されている組織の管理者へ利用申請の通知が届く。
そして管理者が許諾の手続きを行えば、APIトークンが作成可能になる。
(フリープランのときに作っていたAPIトークンがあっても、すべて破棄される)

Pythonのソースコードを書く

大枠

Python2系だとこんな感じ。
ソースコードはutf-8で書く。
変数の頭に$とかつかないし、行末の;もないし、ブレース{...}はなくてブロックの始まりに:を書く模様。
mainの書き方が独特ですね。

  • def myfunction(arg):でmyfunction関数(引数はarg)を定義
  • if __name__ == '__main__':でメイン関数を定義

#!/usr/bin/python
# -*- coding: utf-8 -*-

def myfunction(arg):
    return arg + 1

if __name__ == '__main__':
    result = myfunction(arg)

設定ファイル読み込み

API Tokenをソースファイル内にハードコーディングしてもいいけど、せっかくなので外部ファイルに保存し、それをスクリプトから読み込むようにする。
Pythonの標準ライブラリにConfigParserというものがあり、Windowsのiniファイルに近い形式の設定ファイルを簡単に読み込める。

config.ini
[chatwork]
token = ********
import ConfigParser

ini = ConfigParser.SafeConfigParser()
ini.read('./config.ini')
token = ini.get('chatwork', 'token')

これでtokenにはconfig.iniに記述しているtokenの値がセットされる。

「マイチャット」のID取得(GETリクエスト)

解説は見当たらなかったけど「マイチャット」であるかどうかは、チャットのtypemyになっているので、その項目を探す。

チャット一覧を取得するにはhttps://api.chatwork.com/v2/roomsに対してGETリクエストを投げればOK。
標準ライブラリでHTTPアクセスを行うには、urllib2を使用する。

基本的な構文はurllib2.urlopen("http://www.example.org")となるが、今回はAPI Tokenをヘッダに付加するため、Requestオブジェクトを作成(urllib2.Request())し、それにヘッダ設定を追加(request.add_header())している。
エラーの場合は例外が発生するのでハンドリングしておく。

レスポンスはJSON形式なので、これもPythonのjsonライブラリを使って対象を探す。
json.loads()することで、Pythonの配列・辞書形式のオブジェクトに変換してくれる。(PowerShellのConvertFrom-Jsonと同じ!)
チャット一覧は配列形式なのでforで地道に探す。

18.2. json --- JSON エンコーダおよびデコーダ — Python 2.7.15 ドキュメント

def get_mychat_id(token):
    url = 'https://api.chatwork.com/v2/rooms'
    request = urllib2.Request(url)
    request.add_header('X-ChatWorkToken', token)
    try:
        resp = urllib2.urlopen(request)
    except urllib2.HTTPError, e:
        print e.code
        print e.reason
        print e.read()
        return ""
    j = json.loads(resp.read())
    for item in j:
        if item['type'] == 'my':
            room_id = item['room_id']
    return room_id

マイチャットへメッセージ送信(POSTリクエスト)

チャットのID取得と同様にurllib2を使用する。
今回はメッセージの送信のため、HTTPリクエストボディも追加する(request.add_data())。
リクエストボディを追加すると、メソッドは勝手にPOSTになる。

リクエストボディはURLエンコードをしておく必要があるため、(urllib2とは別の)urllibを使用する(urllib.urlencode())。

20.5. urllib --- URL による任意のリソースへのアクセス — Python 2.7.15 ドキュメント

def post_message(token, room_id, message):
    url = "https://api.chatwork.com/v2/rooms/" + str(room_id) + "/messages"
    request = urllib2.Request(url)
    request.add_header('X-ChatWorkToken', token)
    body = {
        'body' : message
    }
    request.add_data(urllib.urlencode(body))
    try:
        resp = urllib2.urlopen(request)
    except urllib2.HTTPError, e:
        print e.code
        print e.reason
        print e.read()
        return ""
    print resp.read()

あと、他言語やってたせいで引っかかったのが、intの値(room_idは文字列でなく数値)は+で文字列連結しようとしても型エラーになるので、明示的にstr()で文字列にしてやる必要がある。

ソース全体

チャットワークはGoogle APIと違って日本語がそのまま送れました。。𩸽も問題なし。
(念のためPowerShellでも書いてみたけどShift_JISのソースコードなら問題なかった。𩸽は?になったけど)

chatwork.py
#!/usr/bin/python
# -*- coding: utf-8 -*-

import ConfigParser
import urllib
import urllib2
import json

def read_token():
    ini = ConfigParser.SafeConfigParser()
    ini.read('./config.ini')
    return ini.get('chatwork', 'token')

def get_mychat_id(token):
    url = 'https://api.chatwork.com/v2/rooms'
    request = urllib2.Request(url)
    request.add_header('X-ChatWorkToken', token)
    try:
        resp = urllib2.urlopen(request)
    except urllib2.HTTPError, e:
        print e.code
        print e.reason
        print e.read()
        return ""
    j = json.loads(resp.read())
    for item in j:
        if item['type'] == 'my':
            room_id = item['room_id']
    return room_id

def post_message(token, room_id, message):
    url = "https://api.chatwork.com/v2/rooms/" + str(room_id) + "/messages"
    request = urllib2.Request(url)
    request.add_header('X-ChatWorkToken', token)
    body = {
        'body' : message
    }
    request.add_data(urllib.urlencode(body))
    try:
        resp = urllib2.urlopen(request)
    except urllib2.HTTPError, e:
        print e.code
        print e.reason
        print e.read()
        return ""
    print resp.read()

if __name__ == '__main__':
    token = read_token()
    #print token
    id = get_mychat_id(token)
    print id
    post_message(token, id, "hello chatwork api!\n日本語\n改行も多バイトコードもそのまま書ける…?\nほっけ / 𩸽 / ホッケ")

※ urlopen()の例外はハンドリングしてるけど、そのあとは素通りしているので注意

3
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?