LINE Official User API wrapper library for Python
Project description
LINELib
LINE公式アカウントのチャット操作を行う非公式Pythonラッパー
[!WARNING] 本ライブラリはLINEの非公式Webエンドポイントを利用します。 LINEの利用規約・仕様変更により動作しなくなる可能性があります。 自己責任のもとでご利用ください。
目次
- 概要
- 機能一覧
- インストール
- クイックスタート
- 認証・ログイン
- メッセージ送信
- イベント受信
- listen / stop
- 既読をつける
- レート制限
- チャット・Bot情報取得
- 非同期API
- クラスリファレンス
- 設定リファレンス
- エラーハンドリング
- テスト
- ライセンス
概要
LINELib は chat.line.biz / manager.line.biz のWeb APIをPythonから操作するためのライブラリです。
LINE Messaging API(公式SDK)とは独立しており、チャット画面上での手動操作を自動化することを目的としています。
LINELib
├── LineBot 高レベルBotクラス(推奨エントリーポイント)
├── LINELib セッション管理・送受信ラッパー
├── ChatService チャットAPIの生通信層
├── AuthService Cookieログイン / Seleniumログイン
├── ListenConfig SSE接続設定
├── RateLimitConfig レート制限設定
└── LINEOAError 例外クラス
機能一覧
| 機能 | 説明 |
|---|---|
| Cookie再利用 | 保存済みCookieでセッション復元 |
| Seleniumログイン | 初回のみブラウザ起動でログイン・Cookie保存 |
| テキスト送信 | チャットへテキストメッセージを送信 |
| ファイル送信 | 画像・ファイルをアップロード送信 |
| メンション送信 | ユーザーへのメンション送信 |
| Flex送信 | カードメッセージの動的作成・送信・削除 |
| 既読 | チャットを既読にする |
| イベント受信 | SSEによるリアルタイムイベント受信 |
| 自動再接続 | lastEventIdを引き継いだ再接続 |
| レート制限 | ローカルでの送信頻度制御 |
| 非同期送信 | aiohttp対応の async/await API |
| チャット情報取得 | Bot一覧・チャット一覧・メンバー取得 |
インストール
pip install lineoa
開発用(ソースから):
git clone https://github.com/yourname/LINELib.git
cd LINELib
pip install -e .
依存パッケージ:
requests
aiohttp
selenium
クイックスタート
from LINELib import LineBot
bot = LineBot(cookie_path="lineoa-storage.json")
bot.sendMessage(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
text="Hello from LINELib!",
)
初回実行時はSeleniumがブラウザを起動してログイン・Cookie保存を行います。
2回目以降は lineoa-storage.json が自動で読み込まれます。
認証・ログイン
Cookie自動復元
lineoa-storage.json が存在する場合、自動でCookieを読み込んでセッションを復元します。
bot = LineBot(cookie_path="lineoa-storage.json")
Seleniumによる初回ログイン
Cookieが存在しない・無効な場合は email / password を指定するとSeleniumで自動ログインします。
bot = LineBot(
cookie_path="lineoa-storage.json",
email="your@email.com",
password="yourpassword",
)
[!CAUTION]
lineoa-storage.jsonには認証Cookieが平文で保存されます。.gitignoreに追加してリポジトリに含めないようにしてください。
lineoa-storage.json
メッセージ送信
テキスト送信
bot.sendMessage(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
text="こんにちは",
)
引用返信(quoteToken 指定):
bot.sendMessage(
bot_id=bot_id,
chat_id=chat_id,
text="返信です",
quoteToken="xxxxxxxx",
)
ファイル送信
bot.sendFile(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
file_path="./image.png",
)
メンション送信
bot._lib.send_mention(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
mentionee_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)
Flexメッセージ送信
chat.line.biz の仕様上、Flex JSONを直接送信することはできません。
LINELibでは カードを動的作成 → 送信 → 削除 のフローで動的Flexを実現しています。
create_and_send_flex — 作成・送信・削除を一括実行
bot._lib._chat_service.create_and_send_flex(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # BotのUID
at_id="318ogzps", # Botの@ID(@なし)
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", # 送信先チャットID
title="商品名",
image_url="https://example.com/image.jpg",
tag_name="NEW", # タグテキスト(空文字で非表示)
tag_color="info", # info / success / warning / danger
description="説明文",
action_label="詳しく見る",
action_text="詳しく見る", # ボタン押下時に送信されるテキスト
delete_after_send=True, # 送信後にカードを自動削除(デフォルト: True)
session=bot._session,
xsrf_token=bot._xsrf_token,
)
個別API
カードの作成・削除を個別に制御したい場合:
# カード作成 → ID取得
card_id = bot._lib._chat_service.create_card_type_message(
at_id="318ogzps",
title="商品名",
image_url="https://example.com/image.jpg",
tag_name="SALE",
tag_color="danger",
description="期間限定セール中",
action_label="購入する",
action_text="購入する",
session=bot._session,
xsrf_token=bot._xsrf_token,
)
# 送信
bot._lib._chat_service.send_flex_message(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
card_type_message_id=card_id,
session=bot._session,
xsrf_token=bot._xsrf_token,
)
# 削除
bot._lib._chat_service.delete_card_type_message(
at_id="318ogzps",
card_id=card_id,
session=bot._session,
xsrf_token=bot._xsrf_token,
)
既存カードの一覧取得
OA Managerで作成済みのカードIDを取得する場合:
import requests, json
with open("lineoa-storage.json") as f:
data = json.load(f)
session = requests.Session()
for c in data["cookies"]:
session.cookies.set(c["name"], c["value"], domain=c.get("domain"))
resp = session.get(
f"https://chat.line.biz/api/v1/bots/{BOT_ID}/cardTypeMessages",
headers={"Accept": "application/json"},
)
cards = resp.json().get("list", [])
for card in cards:
print(card["id"], card["title"])
イベント受信
ハンドラ登録
@bot.event デコレータで関数名をイベント名として登録します。
@bot.event
def on_message(event):
payload = event.get("payload", {})
chat_payload = payload.get("payload", {})
message = chat_payload.get("message", {})
chat_id = chat_payload.get("chatId")
bot_id = chat_payload.get("botId")
text = message.get("text", "")
if text == "ping":
bot.sendMessage(bot_id=bot_id, chat_id=chat_id, text="pong")
未登録のイベントタイプを受け取りたい場合:
@bot.event
def on_unknown(event):
print("unknown event:", event)
イベント構造
受信するイベントの基本構造:
{
"id": "イベントID(lastEventId)",
"type": "イベントタイプ",
"payload": {
"subEvent": "message", # message / read / delivery など
"botId": "Uxxxxxxxx",
"chatId": "Uxxxxxxxx",
"payload": {
"type": "message",
"message": {
"id": "メッセージID",
"type": "text",
"text": "メッセージ本文",
"createdAt": 1710000000000, # ミリ秒タイムスタンプ
}
}
},
"time": "18:00:00.000"
}
listen / stop
同期リスニング(ブロッキング)
bot.listen(botid="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
# Ctrl+C で停止
非同期リスニング(ノンブロッキング)
thread = bot.listen(botid="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", block=False)
# メインスレッドで他の処理
time.sleep(60)
bot.stop()
thread.join()
自動再接続
SSEが切断・例外発生した場合、reconnect_interval 秒待機後に自動再接続します。
lastEventId を引き継ぐためイベントの取りこぼしを最小化します。
bot = LineBot(
cookie_path="lineoa-storage.json",
reconnect_interval=5, # 再接続待機秒数(デフォルト: 5)
max_reconnects=None, # 最大再接続回数(None=無制限)
)
既読をつける
bot._lib._chat_service.mark_as_read(
bot_id=bot_id,
chat_id=chat_id,
message_id="618399830900998145",
timestamp=1781426326503, # 省略時は現在時刻(ミリ秒)
session=bot._session,
xsrf_token=bot._xsrf_token,
)
イベントハンドラ内での典型的な使い方:
@bot.event
def on_message(event):
payload = event.get("payload", {})
chat_payload = payload.get("payload", {})
msg = chat_payload.get("message", {})
msg_id = msg.get("id")
msg_ts = msg.get("createdAt")
if msg_id:
bot._lib._chat_service.mark_as_read(
bot_id=chat_payload.get("botId"),
chat_id=chat_payload.get("chatId"),
message_id=msg_id,
timestamp=int(msg_ts) if msg_ts else None,
session=bot._session,
xsrf_token=bot._xsrf_token,
)
レート制限
ローカルで送信頻度を管理し、LINEサーバー側のレート制限に引っかかるのを防ぎます。
bot = LineBot(
cookie_path="lineoa-storage.json",
rate_limit=18, # ウィンドウ内の最大送信回数(デフォルト: 18)
rate_limit_window=60, # ウィンドウ秒数(デフォルト: 60)
rate_limit_enabled=True, # 有効/無効(デフォルト: True)
)
状態確認
status = bot.getRateLimitStatus()
print(status)
# {
# "limited": False,
# "count": 3,
# "limit": 18,
# "window": 60.0,
# "enabled": True,
# "ratelimit_after": 0,
# }
リセット
bot.resetRateLimit()
レート制限時のレスポンス
送信がブロックされた場合、送信関数は以下を返します(例外は発生しません):
{
"ratelimit": True,
"ratelimit_after": 1710000060.0, # 解除されるUNIXタイムスタンプ
}
[!NOTE] これはローカルの安全機能です。LINEサーバー側の制限とは独立しています。
チャット・Bot情報取得
Bot一覧
bots = bot.getBots()
print(bots)
# BotsInfo(6 bots)
# SB-moi : Uxxxxxxxx (@318ogzps)
# ...
# IDマップ取得
ids = bots.ids # {"@318ogzps": "Uxxxxxxxx", ...}
チャット一覧
chats = bot.getChats(bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
print(chats)
# ChatsInfo(10 chats)
# 田中太郎 : Uxxxxxxxx [USER]
# 営業チーム : Cxxxxxxxx [GROUP]
# ユーザーチャットIDのリスト
user_ids = chats.user.ids # ["Uxxxxxxxx", ...]
group_ids = chats.group.ids # ["Cxxxxxxxx", ...]
メッセージ履歴取得
messages = bot.getChatMessages(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
limit=50,
before=None, # このメッセージIDより前を取得
after=None, # このメッセージIDより後を取得
)
チャットメンバー取得
members = bot.getMembers(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Cxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
limit=100,
)
非同期API
async/await での送信に対応しています。
テキスト送信(非同期)
import asyncio
async def main():
await bot._lib.async_send_message(
user_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
context="hello async",
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)
asyncio.run(main())
ファイル送信(非同期)
async def main():
await bot._lib.async_send_file(
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
file_path="./image.png",
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)
クラスリファレンス
LineBot
高レベルBotクラス。通常はこれだけを使います。
| メソッド | 説明 |
|---|---|
sendMessage(bot_id, chat_id, text, quoteToken=None) |
テキスト送信 |
sendFile(bot_id, chat_id, file_path) |
ファイル送信 |
getChatMessages(bot_id, chat_id, limit, before, after) |
メッセージ履歴取得 |
getMembers(bot_id, chat_id, limit) |
チャットメンバー取得 |
getBots() |
Bot一覧取得 |
getChats(bot_id, limit) |
チャット一覧取得 |
getRateLimitStatus() |
レート制限状態確認 |
resetRateLimit() |
レート制限カウンターリセット |
listen(botid, block=True) |
SSEリスニング開始 |
stop() |
リスニング停止 |
event(func) |
イベントハンドラ登録デコレータ |
ChatService
低レベルAPI通信層。直接使う場合は bot._lib._chat_service 経由でアクセスします。
| メソッド | 説明 |
|---|---|
send_message(bot_id, chat_id, message, session, xsrf_token) |
メッセージ送信(raw) |
send_file(bot_id, chat_id, file_path, session, xsrf_token) |
ファイル送信 |
send_mention(bot_id, chat_id, mentionee_id, session, xsrf_token) |
メンション送信 |
send_flex_message(bot_id, chat_id, card_type_message_id, session, xsrf_token) |
Flex送信 |
create_card_type_message(at_id, title, image_url, ...) |
カード作成 |
delete_card_type_message(at_id, card_id, session, xsrf_token) |
カード削除 |
create_and_send_flex(bot_id, at_id, chat_id, title, image_url, ...) |
Flex一括送信 |
mark_as_read(bot_id, chat_id, message_id, timestamp, session, xsrf_token) |
既読 |
get_chat_messages(bot_id, chat_id, session, xsrf_token, limit, before, after) |
メッセージ履歴 |
get_chat_members(bot_id, chat_id, limit, session, xsrf_token) |
メンバー取得 |
get_bot_accounts(session, xsrf_token, limit, no_filter) |
Bot一覧 |
get_chats(bot_id, session, xsrf_token, limit) |
チャット一覧 |
get_streaming_api_token(bot_id, session, xsrf_token) |
SSEトークン取得 |
stream_events(streaming_api_token, ...) |
SSEイベントストリーム(Generator) |
set_typing(bot_id, chat_id) |
タイピング表示 |
LINELib
セッション管理・送受信ラッパー。bot._lib でアクセスできます。
| プロパティ / メソッド | 説明 |
|---|---|
bots |
BotsInfo オブジェクト |
chats |
ChatsInfo オブジェクト |
_session |
requests.Session |
_xsrf_token |
XSRFトークン |
send_message(user_id, context, bot_id, quoteToken) |
テキスト送信 |
send_file(chat_id, file_path, bot_id) |
ファイル送信 |
send_mention(bot_id, chat_id, mentionee_id) |
メンション送信 |
check_rate_limit() |
レート制限状態 |
reset_rate_limit() |
レート制限リセット |
get_bots() |
Bot一覧 |
get_chats(bot_id, limit) |
チャット一覧 |
LINEOAError
すべての例外の基底クラス。
from LINELib import LINEOAError
try:
bot.sendMessage(...)
except LINEOAError as e:
print(e) # メッセージ
print(e.code) # エラーコード(任意)
print(e.details) # 詳細(任意)
設定リファレンス
LineBot.__init__ パラメータ
| パラメータ | 型 | デフォルト | 説明 |
|---|---|---|---|
cookie_path |
str |
"lineoa-storage.json" |
Cookie保存パス |
email |
str | None |
None |
ログイン用メールアドレス |
password |
str | None |
None |
ログイン用パスワード |
ping_secs |
int |
60 |
SSE ping間隔(秒) |
device_type |
str |
"" |
デバイスタイプ |
client_type |
str |
"PC" |
クライアントタイプ |
rate_limit |
int |
18 |
ウィンドウ内最大送信回数 |
rate_limit_window |
float |
60 |
レート制限ウィンドウ(秒) |
rate_limit_enabled |
bool |
True |
レート制限の有効/無効 |
reconnect_interval |
float |
5 |
再接続待機秒数 |
max_reconnects |
int | None |
None |
最大再接続回数(None=無制限) |
エラーハンドリング
ハンドラ内で例外が発生しても他のイベント処理は継続します。
@bot.event
def on_message(event):
try:
# 処理
except LINEOAError as e:
print(f"LINE APIエラー: {e}")
except Exception as e:
print(f"予期しないエラー: {e}")
ハンドラのエラーはログに記録されます:
[2026-06-14 18:00:00] [ERROR] [ERROR] handler error (on_message): HTTP 400: {}
テスト
python -m unittest discover -s tests
テスト内容:
- レート制限ロジックの検証
- SSEパーサーの検証
LINEへの実際の接続は行いません。
ライセンス
本ライブラリはLINE社とは無関係の非公式プロジェクトです。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file lineoa-7.6.7.tar.gz.
File metadata
- Download URL: lineoa-7.6.7.tar.gz
- Upload date:
- Size: 27.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e39020bfdc6c8e00f3284f195c41eee00ce071faf1099de04389a84760c4fc1e
|
|
| MD5 |
5cf9971b022ccf20be4b6a2dbc71b746
|
|
| BLAKE2b-256 |
2da512d3f46e684122b9b0880fcb5ac0110f4e6e61db8c15bbd5fedb484a05fa
|
Provenance
The following attestation bundles were made for lineoa-7.6.7.tar.gz:
Publisher:
python-publish.yml on Madoa5561/LINELib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lineoa-7.6.7.tar.gz -
Subject digest:
e39020bfdc6c8e00f3284f195c41eee00ce071faf1099de04389a84760c4fc1e - Sigstore transparency entry: 1814400984
- Sigstore integration time:
-
Permalink:
Madoa5561/LINELib@e64f4a2aa9645c47efe76f07fe17f794151960ce -
Branch / Tag:
refs/tags/7.6.7 - Owner: https://github.com/Madoa5561
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e64f4a2aa9645c47efe76f07fe17f794151960ce -
Trigger Event:
release
-
Statement type:
File details
Details for the file lineoa-7.6.7-py3-none-any.whl.
File metadata
- Download URL: lineoa-7.6.7-py3-none-any.whl
- Upload date:
- Size: 29.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1f82f5a2ceab41ca03e255e104e77f2f75c932f96fb98f6f04cefe1ba012481b
|
|
| MD5 |
9ee35925d1ffb8f7ce7c0e78a32dc6c0
|
|
| BLAKE2b-256 |
035ce2ae927a6cd44b0bbfb63b3de4e37e89361825be5c90f6c0f940814c4e4e
|
Provenance
The following attestation bundles were made for lineoa-7.6.7-py3-none-any.whl:
Publisher:
python-publish.yml on Madoa5561/LINELib
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
lineoa-7.6.7-py3-none-any.whl -
Subject digest:
1f82f5a2ceab41ca03e255e104e77f2f75c932f96fb98f6f04cefe1ba012481b - Sigstore transparency entry: 1814401044
- Sigstore integration time:
-
Permalink:
Madoa5561/LINELib@e64f4a2aa9645c47efe76f07fe17f794151960ce -
Branch / Tag:
refs/tags/7.6.7 - Owner: https://github.com/Madoa5561
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@e64f4a2aa9645c47efe76f07fe17f794151960ce -
Trigger Event:
release
-
Statement type: