简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

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)です。これらは混同しないでください。

核心特性

核心フィールドメソッド

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("友達追加してくれてありがとう!")

方法速查表

核心方法

事件基础信息

ロボット情報

会話識別子

メッセージイベントメソッド

メッセージ内容

送信者情報

グループ/チャンネル情報

@メッセージ関連

メッセージタイプ判断

基礎判断

通知イベントメソッド

通知操作者

通知タイプ判断

要求イベントメソッド

要求情報

要求タイプ判断

返信機能

基礎返信

プラットフォーム機能の確認

転送機能

注意: 転送機能はアダプターの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())

返信待ち機能

交互メソッド

交互メソッドの例

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多回対話を参照してください。

コマンド情報

コマンド基礎

元データ

プラットフォーム拡張メソッド

アダプターは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 - 跨プラットフォーム拡張ワイルドカードを参照してください。

関連ドキュメント