Event 包装クラスの詳細
Event モジュールは、強力な Event 包装クラスを提供し、イベント処理を簡素化します。
event パラメータに型注釈を追加する
イベントハンドラの event パラメータは Event 包装クラス(dict のサブクラス)です。このパラメータに型注釈を付けることを強く推奨します:
from ErisPulse.Core.Event import Event
@message.on_private_message()
async def handler(event: Event):
text = event.get_text() # IDE が便利なメソッドをすべて自動補完
await event.reply(text) # 静的チェック時に誤字が発見される
型注釈を付けない場合、IDE は Event 上のメソッド(get_text() / reply() / wait_reply() / プラットフォーム拡張メソッドなど)を認識できず、すべて手動で記憶して入力する必要があります。
注意:イベントハンドラのコールバックの
eventは Event 包装クラス(注釈はEvent)です。一方、モジュールのライフサイクルメソッドon_load/on_unloadのeventは普通の dict(注釈はdict)です。これらは混同しないでください。
核心特性
- 完全互換性:Event は dict を継承しています
- 便利なメソッド:多数の便利なメソッドを提供しています
- プロパティアクセス:イベントフィールドにドット演算子でアクセスできます
- 後方互換性:すべてのメソッドはオプションです
核心フィールドメソッド
from ErisPulse.Core.Event import command
@command("info")
async def info_command(event: Event):
event_id = event.get_id()
platform = event.get_platform()
time = event.get_time()
print(f"ID: {event_id}, プラットフォーム: {platform}, 時間: {time}")
メッセージイベントメソッド
from ErisPulse.Core.Event import message
@message.on_private_message()
async def private_handler(event: Event):
text = event.get_text()
user_id = event.get_user_id()
nickname = event.get_user_nickname()
await event.reply(f"こんにちは、{nickname}!")
メッセージタイプの判断
from ErisPulse.Core.Event import message
@message.on_group_message()
async def group_handler(event: Event):
is_private = event.is_private_message()
is_group = event.is_group_message()
is_at = event.is_at_message()
await event.reply(f"タイプ: {'プライベートチャット' if is_private else 'グループチャット'}")
回答機能
from ErisPulse.Core.Event import command
@command("ask")
async def ask_command(event: Event):
await event.reply("あなたの名前を入力してください:")
reply = await event.wait_reply(timeout=30)
if reply:
name = reply.get_text()
await event.reply(f"こんにちは、{name}!")
@command("price")
async def price_command(event: Event):
await event.reply("金額を入力してください(例:5元):")
# 回答が正規表現に一致しない場合、タイムアウトするまで待機し続ける
reply = await event.wait_reply(timeout=30, regex=r"\d+\s*元")
if reply:
await event.reply(f"金額を受け取りました: {reply.get_text()}")
インタラクティブな会話の高度な機能
Note
本機能は ErisPulse 2.8.0+ が必要です。
# 会話の定期的なリマインダー:5 分間返信がない場合にリマインダーを送信し、ユーザーが返信すると自動的にキャンセル
reminder = event.remind(300, "まだですか?話したくない場合は「退出」を入力してください")
reminder.cancel() # 手動でキャンセルすることも可能です
# タイムアウトによる昇格:時間経過後に必ず通知(返信によってキャンセルされない)、例えば長時間未処理の通知を主人に通知
event.escalate(1800, lambda e: notify_master("工単がタイムアウトしました"))
# 複数ルートの待機:「同意」および「拒否」のいずれかを同時に待機し、先に到着したものを優先
which, reply = await event.select(
event.expect(pattern="同意*", user="10001"),
event.expect(pattern="拒绝*", user="10002"),
timeout=60,
)
if which is None:
await event.reply("承認がタイムアウトしました")
# 会話レベルの待機:同じグループ内の誰からの返信でも対象になります(グループ協力)
reply = await event.wait_reply(session=True, prompt="誰か回答していただけますか?")
# 会話の受信箱:現在の会話における最新の 20 件のメッセージ(ロボット、AI のコンテキスト / リピート防止の基盤を含む)
messages = await event.history(20)
# メッセージトランザクション:例外が発生した場合、トランザクション内で送信されたメッセージを自動的に撤回
async with event.message_tx():
await event.reply("処理中です、少々お待ちください...")
result = await do_something()
await event.reply(f"完了:{result}")
コマンド情報の取得
from ErisPulse.Core.Event import command
@command("cmdinfo")
async def cmdinfo_command(event: Event):
cmd_name = event.get_command_name()
cmd_args = event.get_command_args()
await event.reply(f"コマンド: {cmd_name}, 引数: {cmd_args}")
通知イベントメソッド
from ErisPulse.Core.Event import notice
@notice.on_friend_add()
async def friend_add_handler(event: Event):
await event.reply("友達追加してくれてありがとう!")
方法速查表
核心方法
事件基础信息
get_id()- イベントIDを取得get_time()- イベントのタイムスタンプ(Unix秒単位)を取得get_type()- イベントのタイプ(message/notice/request/meta)を取得get_detail_type()- イベントの詳細タイプ(private/group/friend等)を取得get_platform()- プラットフォーム名を取得
ロボット情報
get_self_platform()- ロボットのプラットフォーム名を取得get_self_user_id()- ロボットのユーザーIDを取得get_self_account_id()- ロボットのアカウントID(複数Botモード)を取得get_self_info()- ロボットの完全な情報辞書を取得
会話識別子
get_target_id()- 統一されたターゲットIDを取得(グループチャットはgroup_id、チャンネルはchannel_id、プライベートチャットはuser_idを返す。group → channel → guild → thread → userの順に最初の非空値を返す)get_session_id()- セッションの唯一の識別子を取得、形式は{platform}:{detail_type}:{target_id}
メッセージイベントメソッド
メッセージ内容
get_message()- メッセージセグメントの配列を取得(OneBot12形式)get_alt_message()- メッセージの代替テキストを取得get_text()- 純粋なテキスト内容を取得(get_alt_message()のエイリアス)get_message_text()- 純粋なテキスト内容を取得(get_alt_message()のエイリアス)
送信者情報
get_user_id()- 送信者のユーザーIDを取得get_user_nickname()- 送信者のニックネームを取得get_sender()- 送信者の完全な情報辞書を取得
グループ/チャンネル情報
get_group_id()- グループIDを取得(グループメッセージ)get_channel_id()- チャンネルIDを取得(チャンネルメッセージ)get_guild_id()- サーバーIDを取得(サーバーメッセージ)get_thread_id()- トピック/サブチャンネルIDを取得(トピックメッセージ)
@メッセージ関連
has_mention()- @ロボットが含まれているかget_mentions()- すべての@されたユーザーIDのリストを取得
メッセージタイプ判断
基礎判断
is_message()- メッセージイベントであるかis_private_message()- プライベートチャットメッセージかis_group_message()- グループチャットメッセージかis_at_message()- @メッセージか(has_mention()のエイリアス)
通知イベントメソッド
通知操作者
get_operator_id()- 操作者のIDを取得get_operator_nickname()- 操作者のニックネームを取得
通知タイプ判断
is_notice()- 通知イベントであるかis_group_member_increase()- グループメンバー増加イベントis_group_member_decrease()- グループメンバー減少イベントis_friend_add()- 友達追加イベント(detail_type == "friend_increase"に一致)is_friend_delete()- 友達削除イベント(detail_type == "friend_decrease"に一致)
要求イベントメソッド
要求情報
get_comment()- 要求の付言を取得
要求タイプ判断
is_request()- 要求イベントであるかis_friend_request()- 友達要求かis_group_request()- グループ要求か
返信機能
基礎返信
reply(content, method="Text", at_sender=False, quote=False, at_users=None, reply_to=None, at_all=False, via=None, **kwargs)- 一般的な返信メソッドcontent: 送信内容(テキスト、URLなど)method: 送信方法、デフォルトは "Text"、"Image"/"Voice"/"Video"/"File" などat_sender: 送信者を@するか(自動的に user_id を抽出)quote: 現在のメッセージを引用して返信するか(自動的に message_id を抽出)at_users: @するユーザーIDのリスト、例:["user1", "user2"]reply_to: 手動で返信するメッセージIDを指定at_all: 全員を@するか**kwargs: 余分なパラメータ(例: Mentionメソッドの user_id)
reply_ob12(message)- OneBot12メッセージセグメントを使って返信message: OneBot12メッセージセグメントのリストまたは辞書、MessageBuilderを使って構築
プラットフォーム機能の確認
supports(method)- 現在のプラットフォームが特定の送信方法(例:"Image"、"Voice")をサポートしているか確認、boolを返すavailable_methods()- 現在のプラットフォームで利用可能な送信方法の一覧を取得、メソッド名のリストを返す
転送機能
注意: 転送機能はアダプターのSend DSLによって実装される必要があり、Eventラッパークラス自体は直接の転送メソッドを提供しない。
# メッセージをグループに転送
adapter = sdk.adapter.get(event.get_platform())
target_id = event.get_group_id() # または他のグループIDを指定
await adapter.Send.To("group", target_id).Text(event.get_text())
返信待ち機能
wait_reply(prompt=None, timeout=60.0, callback=None, validator=None, method="Text", pattern=None, regex=None)- ユーザーからの返信を待つprompt: プロンプトメッセージ、提供された場合ユーザーに送信されるtimeout: 待ち時間のタイムアウト(秒)、デフォルトは60秒callback: 返信を受け取ったときに実行されるコールバック関数validator: 返信が有効かどうかを検証する関数method: プロンプトメッセージの送信方法、デフォルトは "Text"pattern: globワイルドカード(*/?/[seq])、返信テキストが一致する必要がある、一致しない場合は待機を続けるregex: 正規表現、返信テキストが一致する必要がある(patternとregexのどちらか一方を選択)、一致しない場合は待機を続ける- ユーザーの返信のEventオブジェクトを返す、タイムアウト時は
Noneを返す
交互メソッド
confirm(prompt=None, timeout=60.0, yes_words=None, no_words=None, method="Text", hint=False)- 確認対話True(確認)/False(否定)/None(タイムアウト)を返す- 内部的に中英語の確認語を自動認識し、カスタム語集を指定可能
method: 送信方法、デフォルトは "Text"、"Image"/"Markdown" などの非テキスト方式もサポートhint: プロンプトの末尾に自動的に確認語のヒント(例: "(はい/いいえ)")を追加するか、デフォルトはFalse
choose(prompt, options, timeout=60.0, method="Text", options_format="auto", merge_prompt=False, placeholder="{options}")- 選択メニューoptions: 選択肢のテキストリスト- 選択肢のインデックス(0ベース)を返す、タイムアウト時は
Noneを返す method: 送信方法、デフォルトは "Text"、テキスト系メソッド (Text/Markdown/md/Html/h5) はデフォルトで選択肢を末尾にマージoptions_format: 選択肢のフォーマット(デフォルト: "auto"、methodに応じて自動的に組み込みスタイルを選択)"auto": Markdown→箇条書き(- 1.選択肢)、Html→順序付きリスト(<ol>)、その他の場合は純粋なテキストリスト"list": 各行に1つずつ、例:1. 選択肢A\n2. 選択肢B"inline": 1行に表示、例:1.A | 2.B"md": Markdownの箇条書き"html": Htmlの順序付きリストcallable: 自作の関数、list[str]を受け取りstrを返す
merge_prompt: 強制的に1つのメッセージにマージして送信するか、デフォルトはFalseFalse(デフォルト): テキスト系メソッドは自動的にマージ、非テキスト系メソッドはまずpromptを送信してからTextの選択肢を送信True: どんなmethodでも1つのメッセージにマージしてユーザーが指定したmethodで送信
placeholder: 選択肢を挿入する占位符、デフォルトは{options}、promptにこのマーカーが含まれる場所に選択肢のテキストを置き換え、空文字に設定すると常に末尾に追加
collect(fields, timeout_per_field=60.0)- フォーム収集fields: フィールドのリスト、各項目にはkey、prompt、オプションvalidator、オプションmethodが含まれる{key: value}の辞書を返す、いずれかのフィールドがタイムアウトするとNoneを返す- 各フィールドは
methodキーで送信方法を指定可能、例: 画像を収集する場合{"key": "avatar", "prompt": "プロフィール画像を送ってください", "method": "Image"} - 各フィールドは
optionsキー(リスト)をオプションで提供可能、提供された場合、該当フィールドは選択問題になる(chooseのロジックを自動的に呼び出す) - 各フィールドは
options_format、merge_prompt、placeholderキーをオプションで提供可能、選択肢のフォーマット、メッセージのマージ動作、占位符を制御
wait_for(event_type="message", condition=None, timeout=60.0)- 任意のイベントを待つcondition: 条件関数、Trueを返した場合に一致する- 一致するEventオブジェクトを返す、タイムアウト時は
Noneを返す
conversation(timeout=60.0)- 複数回対話コンテキストを作成Conversationオブジェクトを返す、say()/wait()/confirm()/choose()/collect()/stop()がサポートされるis_active属性は対話がアクティブかどうかを示す
交互メソッドの例
confirm() - 確認対話:
@command("delete", help="データを削除")
async def delete_handler(event: Event):
if await event.confirm("すべてのデータを削除してもよろしいですか?"):
sdk.storage.delete("all_data")
await event.reply("データを削除しました")
else:
await event.reply("キャンセルしました")
confirm() - ヒント付き:
# hint=True はプロンプトの末尾に "(はい/いいえ)" を追加
if await event.confirm("続行してもよろしいですか?", hint=True):
await event.reply("続行しました")
# ユーザーが表示する: 続行してもよろしいですか?(はい/いいえ)
choose() - 選択メニュー:
@command("color", help="色を選択")
async def color_handler(event: Event):
choice = await event.choose("色を選択してください:", ["赤", "緑", "青"])
if choice is not None:
colors = ["赤", "緑", "青"]
await event.reply(f"選択した色は:{colors[choice]}")
choose() - 選択肢のフォーマットとメッセージのマージ:
# inline形式:選択肢を1行に表示
choice = await event.choose("選択してください:", ["A", "B", "C"], options_format="inline")
# 出力: 1.A | 2.B | 3.C
# 自作のフォーマット
choice = await event.choose("選択してください:", ["猫", "犬"],
options_format=lambda opts: " / ".join(opts))
# 出力: 猫 / 犬
# options_format="auto"(デフォルト):methodに応じて自動的に組み込みスタイルを選択
# Markdown → 箇条書き
choice = await event.choose(
"## 選択してください", ["猫", "犬"],
method="Markdown", # autoは自動的にmdリストを認識
)
# 出力:
# ## 選択してください
# - 1. 猫
# - 2. 犬
# Html → 順序付きリスト
choice = await event.choose(
"<h2>選択してください</h2>", ["猫", "犬"],
method="Html", merge_prompt=True, # autoは自動的にhtmlリストを認識
)
# 出力:
# <h2>選択してください</h2>
# <ol><li>1. 猫</li><li>2. 犬</li></ol>
# マージモード + 占位符
choice = await event.choose(
"## 選択してください\n{options}\n番号を返信してください",
["猫", "犬"],
method="Markdown", merge_prompt=True,
)
# 自作の占位符
choice = await event.choose(
"選択してください: [choices]",
["猫", "犬"],
placeholder="[choices]",
)
collect() - フォーム収集:
@command("register", help="登録")
async def register_handler(event: Event):
data = await event.collect([
{"key": "name", "prompt": "お名前を入力してください:"},
{"key": "age", "prompt": "年齢を入力してください:",
"validator": lambda e: e.get_text().isdigit()},
])
if data:
await event.reply(f"登録完了!{data['name']}、{data['age']}歳")
非テキストメソッドのreply:
await event.reply("http://example.com/img.jpg", method="Image")
await event.reply("http://example.com/audio.mp3", method="Voice")
from ErisPulse.Core.Event import MessageBuilder
segments = MessageBuilder.text("この画像を見てください:").image("http://example.com/img.jpg").build()
await event.reply_ob12(segments)
完全なConversation多回対話の使い方はConversation多回対話を参照してください。
コマンド情報
コマンド基礎
get_command_name()- コマンド名を取得get_command_args()- コマンド引数のリストを取得get_command_raw()- コマンドの元のテキストを取得get_command_info()- 完全なコマンド情報の辞書を取得is_command()- コマンドか
元データ
get_raw()- プラットフォームの元のイベントデータを取得get_raw_type()- プラットフォームの元のイベントタイプを取得
プラットフォーム拡張メソッド
アダプターはEventラッパークラスにプラットフォーム固有のメソッドを登録できる。メソッドは対応するプラットフォームのEventインスタンスでのみ利用可能で、他のプラットフォームでアクセスするとAttributeErrorが発生する。
プラットフォームメソッドはEvent.__getattribute__により、内蔵メソッドよりも優先して有効になるため、confirm、choose、collect、wait_replyなどの内蔵インタラクティブメソッドを覆い、プラットフォーム特有の実装(例: ボタン、カードなど)を提供できる。内蔵実装は_builtin_*関数としてエクスポートされ、覆い書き側で利用可能。
# メールイベント - メールメソッドのみ
event = Event({"platform": "email", "email_raw": {"subject": "Hello"}})
event.get_subject() # ✅ "Hello"を返す
event.get_chat_type() # ❌ AttributeError
# Telegramイベント - Telegramメソッドのみ
event = Event({"platform": "telegram", "telegram_raw": {"chat": {"type": "private"}}})
event.get_chat_type() # ✅ "private"を返す
event.get_subject() # ❌ AttributeError
# 内蔵メソッドは常に利用可能
event.get_text() # ✅ どのプラットフォームでも
event.reply("hi") # ✅ どのプラットフォームでも
登録されたメソッドの照会
from ErisPulse.Core.Event import get_platform_event_methods
methods = get_platform_event_methods("email")
# ["get_subject", "get_from", ...]
hasattr と dir のサポート
hasattr(event, "get_subject") # platform="email"のときのみTrueを返す
"get_subject" in dir(event) # 同上
跨プラットフォーム拡張(ワイルドカード)
register_event_methodとregister_event_mixinはプラットフォーム名として"*"を渡すことができ、登録されたメソッドはすべてのプラットフォームのEventインスタンスで利用可能になる。AI対話、コンテキスト管理など、跨プラットフォームで再利用可能な機能に適している。
from ErisPulse.Core.Event.wrapper import register_event_method
@register_event_method("*")
async def ai_chat(self, prompt: str):
# selfはEventインスタンス、イベントデータと内蔵メソッドにアクセス可能
await self.reply(f"AI: {prompt}")
登録後、どのプラットフォームのイベントハンドラでもevent.ai_chat(...)を呼び出すことができる。
メソッドの優先順位(高い順): プラットフォーム固有メソッド → ワイルドカードメソッド → 内蔵メソッド → 辞書キーアクセス。
アダプター開発者が拡張メソッドを登録する方法はイベントシステムAPI - 跨プラットフォーム拡張ワイルドカードを参照してください。