昔は413 Payload Too Large
が返されていたが、今は受け付けてくれる。
413
が返されるのは去年の夏くらいに確認したが、その後いつ変更されたんだろうか。
自動分割された場合はレスポンスにis_auto_split
フィールドが増える。
is_auto_split
フィールドは、自動分割されなかった場合は存在しない(false
になるわけではない)ので注意が必要である。
また、自動分割された場合のレスポンスのmessage.text
フィールドは、分割された一連メッセージのうち、最後のメッセージのテキストとなり、全文は含まれない。
{
"ok": true,
"ts": "1521494094.000437",
"message": {
"text": "分割された一連のメッセージのうち、最後のメッセージのテキスト",
"username": "Slack API Tester",
"is_auto_split": true,
"type": "message",
"subtype": "bot_message",
"ts": "1521494094.000437"
},
"warning": "missing_charset",
"response_metadata": {
"warnings": [
"missing_charset"
]
}
}
何文字で分割されるのかは仕様が見当たらなかった。
実測によると4042文字である。
# coding: utf_8
import bisect
import json
import time
import requests
TOKEN = ''
def json_post(char, length):
time.sleep(3)
h = {
'Content-type': 'application/json',
'Authorization': 'Bearer ' + TOKEN,
}
d = json.dumps({
'channel': 'general',
'text': ''.join([char] * length),
})
r = requests.post('https://slack.com/api/chat.postMessage', headers=h, data=d)
if not r.json()['ok']:
raise Exception()
return 1 if r.json().get('message', {}).get('is_auto_split') else 0
def form_post(char, length):
time.sleep(3)
d = {
'token': TOKEN,
'channel': 'general',
'text': ''.join([char] * length),
}
r = requests.post('https://slack.com/api/chat.postMessage', data=d)
if not r.json()['ok']:
raise Exception()
return 1 if r.json().get('message', {}).get('is_auto_split') else 0
class Resolver(object):
def __init__(self, char, post):
self.char = char
self.post = post
def __len__(self):
return 100000
def __getitem__(self, key):
return self.post(self.char, key)
print(bisect.bisect(Resolver('a', json_post), 0))
print(bisect.bisect(Resolver('あ', json_post), 0))
print(bisect.bisect(Resolver('a', form_post), 0))
print(bisect.bisect(Resolver('あ', form_post), 0))
$ pipenv run python _.py
4041
4041
4041
4041
a
とあ
を個別にチェックしているのは昔の名残である。
以前のSlackはパーセントエンコード後のバイト数で文字数をカウントしていたため、あ
は9文字扱いだった(utf8で3バイト、パーセントエンコード後9バイト)のだ。
今はそういうことはないようだ。