LINE Official User API wrapper library for Python
Project description
LINELib
LINE Official Account の chat.line.biz / manager.line.biz を Python から扱うためのライブラリです。
この README は、今の実装に合わせた使い方のドキュメントとして読めるように整理しています。
概要
LINELib でできること:
- 送信
- 受信
- SSE polling
- 画像 / 動画 / ファイルの保存
- ステッカー画像の保存
- link メッセージの JSON 保存
- 管理系 API の取得
インストール
pip install lineoa
開発用:
git clone https://github.com/Madoa5561/LINELib.git
cd LINELib
pip install -e .
セットアップ
最初に Cookie ベースでログイン済みの状態を用意するのが基本です。
from LINELib import LineBot
bot = LineBot(cookie_path="lineoa-storage.json")
Cookie がない場合は email / password を渡してログインを試みます。
bot = LineBot(
cookie_path="lineoa-storage.json",
email="your@email.com",
password="yourpassword",
)
基本送信
テキスト送信
bot.sendMessage(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
text="Hello from LINELib!",
)
ファイル送信
bot.sendFile(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
file_path="./image.png",
)
返信付き送信
bot.sendMessage(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
chat_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
text="reply",
quoteToken="xxxxxxxx",
)
受信
イベント登録
@bot.event
def on_message(event):
print(event)
使えるイベント名
on_initon_pingon_messageon_mediaon_unknown
on_media は image / video / file / audio / sticker / link をまとめて扱う入口です。
メディアイベントの正規化
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
print(normalized["kind"])
print(normalized["message_type"])
print(normalized.get("media_url"))
SSE / Polling
基本
bot.listen(botid="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
非同期実行
thread = bot.listen(botid="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", block=False)
import time
time.sleep(60)
bot.stop()
thread.join()
polling の挙動
polling は次の順序で動きます。
streamingApiTokenを取得streaming/stateを{"connectionId": "...", "idle": true}で送信streamingApiBaseUrlとstreamingApiVersionに従って SSE 接続lastEventIdを引き継いで再接続expiredAtを見て、期限前に張り替え
HAR に合わせて、init と ping も通常イベントとして扱えます。
メディア保存
画像
event = ...
bot.save_message_media(event, "./downloaded/image")
拡張子なしで渡すと、種別に応じて補完されます。
image->.jpgvideo->.mp4file->.binaudio->.m4asticker->.pnglink->.json
画像プレビューを直接保存
bot.save_image_preview(
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
content_hash="xxxxxxxx",
file_path="./preview.jpg",
)
ステッカー画像を直接保存
bot._lib._chat_service.save_sticker_image(
sticker_id="123456789",
file_path="./sticker.png",
session=bot._session,
)
link メッセージの保存
link は画像保存ではなく、メタデータ JSON を保存します。
bot.save_message_media(event, "./downloaded/link")
保存される JSON には次が入ります。
message_idbot_idchat_idtitleurltexttimestampraw
メッセージ正規化
normalize_message_event() を使うと、受信イベントを共通構造にできます。
normalized = bot.normalize_message_event(event)
print(normalized["kind"])
print(normalized["message_type"])
print(normalized.get("media_url"))
主な kind:
medialinkstickeraudiounknown
管理系 API
HAR に出てきた管理画面寄りの API もいくつかラッパー化しています。
bot.get_me()
bot.get_whitelist_domains()
bot.get_me_settings_pc()
bot.get_chat_mode(bot_id)
bot.get_chat_mode_schedules(bot_id)
bot.get_available_features(bot_id)
bot.get_banner_web(bot_id)
bot.get_call_session(bot_id)
bot.get_activities(bot_id, chat_id)
bot.get_notes(bot_id, chat_id)
bot.get_authorized_users(bot_id)
bot.get_use_manual_chat(bot_id, chat_id)
bot.get_recent_stickers(bot_id)
bot.get_recent_emojis(bot_id)
bot.get_saved_replies(bot_id)
bot.get_clock_now()
bot.get_holiday("JP")
bot.get_plugins(bot_id)
クラス参照
LineBot
よく使う入口だけをまとめたラッパーです。
| メソッド | 説明 |
|---|---|
sendMessage(bot_id, chat_id, text, quoteToken=None) |
テキスト送信 |
sendFile(bot_id, chat_id, file_path) |
ファイル送信 |
listen(botid, block=True) |
SSE polling 開始 |
stop() |
polling 停止 |
event(func) |
イベントハンドラ登録 |
normalize_message_event(event) |
受信イベントの正規化 |
save_message_media(event, file_path) |
メディア保存 |
save_image_preview(bot_id, content_hash, file_path) |
画像プレビュー保存 |
ChatService
低レベルの API です。必要なら直接使えます。
| メソッド | 説明 |
|---|---|
get_streaming_api_token(bot_id, ...) |
polling 用トークン取得 |
stream_events(streaming_api_token, ...) |
SSE 接続 |
streaming_state(bot_id, state) |
streaming state 送信 |
get_content_preview(bot_id, content_hash, ...) |
画像/動画/ファイルプレビュー |
get_sticker_image(sticker_id, ...) |
ステッカー画像取得 |
save_content_preview(bot_id, content_hash, file_path, ...) |
プレビュー保存 |
save_sticker_image(sticker_id, file_path, ...) |
ステッカー保存 |
SSEEvent
SSE 1件を表します。
| メソッド | 説明 |
|---|---|
payload |
JSON パース済み payload |
normalized_message() |
メッセージ正規化 |
image_url() |
画像プレビュー URL |
例
画像イベント保存
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
if normalized.get("message_type") == "image":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
ステッカー保存
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
if normalized.get("message_type") == "sticker":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
link 保存
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
if normalized.get("message_type") == "link":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
実戦向け polling
import os
import time
from LINELib import LineBot
BOT_ID = os.environ["LINEOA_BOT_ID"]
bot = LineBot(cookie_path=os.environ.get("LINEOA_COOKIE_PATH", "lineoa-storage.json"), ping_secs=30, max_stream_seconds=7200)
@bot.event
def on_message(event):
normalized = bot.normalize_message_event(event)
if normalized.get("message_type") == "text" and normalized.get("text") == "ping":
bot.sendMessage(bot_id=normalized["bot_id"], chat_id=normalized["chat_id"], text="pong")
if normalized.get("kind") == "media":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
bot.listen(botid=BOT_ID)
while True:
time.sleep(1)
ステッカー保存
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
if normalized.get("message_type") == "sticker":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
動画保存
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
if normalized.get("message_type") == "video":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
link メタデータ保存
@bot.event
def on_media(event):
normalized = event.get("normalized", {})
if normalized.get("message_type") == "link":
bot.save_message_media(event, f"./outputs/{normalized['message_id']}")
async 送信
import asyncio
from LINELib.LINELib import LINELib
async def main():
lib = LINELib(storage="lineoa-storage.json")
await lib.async_send_message(
user_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
context="async send",
bot_id="Uxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
)
asyncio.run(main())
テスト
python -m unittest discover -s tests
注意
- このライブラリは LINE の Web UI 由来の非公開 API を使っています
- 仕様変更に弱いので、HAR 取得と再確認が重要です
- Cookie は漏えいしないように扱ってください
Example まとめ
example/ には、README と同じ内容の実行例を置いてあります。
example_send_text.pysendfile.pyexample_send_flex.pyexample_polling.pyexample_async.pyexample_hybrid.pyexample_media_save.py
実行前に必要な環境変数:
LINEOA_COOKIE_PATHLINEOA_BOT_IDLINEOA_CHAT_IDLINEOA_AT_IDLINEOA_FILE_PATHLINEOA_EVENT_JSON
ライセンス
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.7.7.tar.gz.
File metadata
- Download URL: lineoa-7.7.7.tar.gz
- Upload date:
- Size: 27.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a42d760f3fc23e9e5bfd4db0813e46d670b6bdb336515e2f9420b6a3b1ea7ee0
|
|
| MD5 |
0e753c3e207a5ff2b4d545604d07c0f2
|
|
| BLAKE2b-256 |
28a4b6f225d462f00b2ab00a24ef405949170539935a10543263d558f3a138e4
|
Provenance
The following attestation bundles were made for lineoa-7.7.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.7.7.tar.gz -
Subject digest:
a42d760f3fc23e9e5bfd4db0813e46d670b6bdb336515e2f9420b6a3b1ea7ee0 - Sigstore transparency entry: 2135650297
- Sigstore integration time:
-
Permalink:
Madoa5561/LINELib@70286d482adcae3535cdcc020fa666def77332aa -
Branch / Tag:
refs/tags/7.7.7 - Owner: https://github.com/Madoa5561
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@70286d482adcae3535cdcc020fa666def77332aa -
Trigger Event:
release
-
Statement type:
File details
Details for the file lineoa-7.7.7-py3-none-any.whl.
File metadata
- Download URL: lineoa-7.7.7-py3-none-any.whl
- Upload date:
- Size: 31.1 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 |
02e48b8dd14ee65b6879a015cbe9ea0d5c935ea5ef4ace9caca55d54a2234400
|
|
| MD5 |
ad143742b7bd5b6256d6fc2d81c1dcd1
|
|
| BLAKE2b-256 |
5cbb3cdabee8e81eab3c9a66fc02d26e5304f41cd45b012897199bed4c70dab2
|
Provenance
The following attestation bundles were made for lineoa-7.7.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.7.7-py3-none-any.whl -
Subject digest:
02e48b8dd14ee65b6879a015cbe9ea0d5c935ea5ef4ace9caca55d54a2234400 - Sigstore transparency entry: 2135650337
- Sigstore integration time:
-
Permalink:
Madoa5561/LINELib@70286d482adcae3535cdcc020fa666def77332aa -
Branch / Tag:
refs/tags/7.7.7 - Owner: https://github.com/Madoa5561
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@70286d482adcae3535cdcc020fa666def77332aa -
Trigger Event:
release
-
Statement type: