iMessage (imsg)

상태: 외부 CLI 통합. Gateway는 imsg rpc(JSON-RPC over stdio)를 실행합니다.

빠른 설정 (초보자용)

  1. 이 Mac에서 Messages가 로그인되어 있는지 확인합니다.
  2. imsg 설치:
    • brew install steipete/tap/imsg
  3. channels.imessage.cliPathchannels.imessage.dbPath로 OpenClaw를 구성합니다.
  4. Gateway를 시작하고 macOS 프롬프트를 승인합니다(Automation + Full Disk Access).

최소 설정:

{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "/usr/local/bin/imsg",
      dbPath: "/Users/<you>/Library/Messages/chat.db"
    }
  }
}

개요

  • macOS의 imsg를 기반으로 하는 iMessage 채널입니다.
  • 결정론적 라우팅: 응답은 항상 iMessage로 돌아갑니다.
  • DM은 에이전트의 메인 세션을 공유하며, 그룹은 격리됩니다(agent:<agentId>:imessage:group:<chat_id>).
  • is_group=false로 도착한 다중 참가자 스레드는 channels.imessage.groups를 사용하여 chat_id로 격리할 수 있습니다(아래 "그룹형 스레드" 참조).

설정 쓰기

기본적으로 iMessage는 /config set|unset으로 트리거된 설정 업데이트 쓰기가 허용됩니다(commands.config: true 필요).

비활성화:

{
  channels: { imessage: { configWrites: false } }
}

요구사항

  • Messages가 로그인된 macOS.
  • OpenClaw + imsg에 대한 Full Disk Access(Messages DB 접근).
  • 전송 시 Automation 권한.
  • channels.imessage.cliPath는 stdin/stdout을 프록시하는 모든 명령을 가리킬 수 있습니다(예: 다른 Mac에 SSH로 접속하여 imsg rpc를 실행하는 래퍼 스크립트).

설정 (빠른 경로)

  1. 이 Mac에서 Messages가 로그인되어 있는지 확인합니다.
  2. iMessage를 구성하고 Gateway를 시작합니다.

전용 봇 macOS 사용자 (격리된 ID용)

봇이 별도의 iMessage ID로 전송하고 개인 Messages를 깨끗하게 유지하려면, 전용 Apple ID + 전용 macOS 사용자를 사용하세요.

  1. 전용 Apple ID를 생성합니다(예: [email protected]).
    • Apple은 인증/2FA를 위해 전화번호가 필요할 수 있습니다.
  2. macOS 사용자를 생성하고(예: openclawhome) 로그인합니다.
  3. 해당 macOS 사용자에서 Messages를 열고 봇 Apple ID로 iMessage에 로그인합니다.
  4. Remote Login을 활성화합니다(시스템 설정 → 일반 → 공유 → Remote Login).
  5. imsg 설치:
    • brew install steipete/tap/imsg
  6. ssh <bot-macos-user>@localhost true가 비밀번호 없이 작동하도록 SSH를 설정합니다.
  7. channels.imessage.accounts.bot.cliPath를 봇 사용자로 imsg를 실행하는 SSH 래퍼로 지정합니다.

첫 실행 참고사항: 전송/수신 시 봇 macOS 사용자에서 GUI 승인(Automation + Full Disk Access)이 필요할 수 있습니다. imsg rpc가 멈추거나 종료되면, 해당 사용자로 로그인하고(화면 공유 도움), 일회성으로 imsg chats --limit 1 / imsg send ...를 실행하고, 프롬프트를 승인한 후 재시도하세요.

래퍼 예시(chmod +x). <bot-macos-user>를 실제 macOS 사용자명으로 교체하세요:

#!/usr/bin/env bash
set -euo pipefail

# 호스트 키 수락을 위해 먼저 대화형 SSH를 한 번 실행:
#   ssh <bot-macos-user>@localhost true
exec /usr/bin/ssh -o BatchMode=yes -o ConnectTimeout=5 -T <bot-macos-user>@localhost \
  "/usr/local/bin/imsg" "$@"

설정 예시:

{
  channels: {
    imessage: {
      enabled: true,
      accounts: {
        bot: {
          name: "Bot",
          enabled: true,
          cliPath: "/path/to/imsg-bot",
          dbPath: "/Users/<bot-macos-user>/Library/Messages/chat.db"
        }
      }
    }
  }
}

단일 계정 설정의 경우, accounts 맵 대신 플랫 옵션(channels.imessage.cliPath, channels.imessage.dbPath)을 사용하세요.

원격/SSH 변형 (선택사항)

다른 Mac에서 iMessage를 사용하려면, channels.imessage.cliPath를 SSH를 통해 원격 macOS 호스트에서 imsg를 실행하는 래퍼로 설정하세요. OpenClaw는 stdio만 필요합니다.

래퍼 예시:

#!/usr/bin/env bash
exec ssh -T gateway-host imsg "$@"

원격 첨부파일: cliPath가 SSH를 통해 원격 호스트를 가리킬 때, Messages 데이터베이스의 첨부파일 경로는 원격 머신의 파일을 참조합니다. OpenClaw는 channels.imessage.remoteHost를 설정하여 SCP를 통해 자동으로 가져올 수 있습니다:

{
  channels: {
    imessage: {
      cliPath: "~/imsg-ssh",                     // 원격 Mac으로의 SSH 래퍼
      remoteHost: "user@gateway-host",           // SCP 파일 전송용
      includeAttachments: true
    }
  }
}

remoteHost가 설정되지 않으면, OpenClaw는 래퍼 스크립트의 SSH 명령을 파싱하여 자동 감지를 시도합니다. 안정성을 위해 명시적 구성을 권장합니다.

Tailscale을 통한 원격 Mac (예시)

Gateway가 Linux 호스트/VM에서 실행되지만 iMessage는 Mac에서 실행되어야 하는 경우, Tailscale이 가장 간단한 브리지입니다: Gateway가 tailnet을 통해 Mac과 통신하고, SSH를 통해 imsg를 실행하며, SCP로 첨부파일을 가져옵니다.

아키텍처:

┌──────────────────────────────┐          SSH (imsg rpc)          ┌──────────────────────────┐
│ Gateway 호스트 (Linux/VM)     │──────────────────────────────────▶│ Messages + imsg가 있는 Mac │
│ - openclaw gateway           │          SCP (attachments)        │ - Messages 로그인됨       │
│ - channels.imessage.cliPath  │◀──────────────────────────────────│ - Remote Login 활성화됨   │
└──────────────────────────────┘                                   └──────────────────────────┘
              ▲
              │ Tailscale tailnet (hostname 또는 100.x.y.z)
              ▼
        user@gateway-host

구체적인 설정 예시 (Tailscale 호스트명):

{
  channels: {
    imessage: {
      enabled: true,
      cliPath: "~/.openclaw/scripts/imsg-ssh",
      remoteHost: "[email protected]",
      includeAttachments: true,
      dbPath: "/Users/bot/Library/Messages/chat.db"
    }
  }
}

래퍼 예시 (~/.openclaw/scripts/imsg-ssh):

#!/usr/bin/env bash
exec ssh -T [email protected] imsg "$@"

참고사항:

  • Mac이 Messages에 로그인되어 있고, Remote Login이 활성화되어 있는지 확인하세요.
  • ssh [email protected]가 프롬프트 없이 작동하도록 SSH 키를 사용하세요.
  • remoteHost는 SCP가 첨부파일을 가져올 수 있도록 SSH 타겟과 일치해야 합니다.

다중 계정 지원: 계정별 설정 및 선택적 name과 함께 channels.imessage.accounts를 사용하세요. 공유 패턴은 gateway/configuration을 참조하세요. ~/.openclaw/openclaw.json은 커밋하지 마세요(종종 토큰이 포함됨).

접근 제어 (DM + 그룹)

DM:

  • 기본값: channels.imessage.dmPolicy = "pairing".
  • 알 수 없는 발신자는 페어링 코드를 받으며, 승인될 때까지 메시지가 무시됩니다(코드는 1시간 후 만료).
  • 승인 방법:
    • openclaw pairing list imessage
    • openclaw pairing approve imessage <CODE>
  • 페어링은 iMessage DM의 기본 토큰 교환입니다. 자세한 내용: Pairing

그룹:

  • channels.imessage.groupPolicy = open | allowlist | disabled.
  • channels.imessage.groupAllowFromallowlist가 설정된 경우 그룹에서 누가 트리거할 수 있는지 제어합니다.
  • iMessage에는 네이티브 멘션 메타데이터가 없으므로, 멘션 게이팅은 agents.list[].groupChat.mentionPatterns(또는 messages.groupChat.mentionPatterns)를 사용합니다.
  • 다중 에이전트 재정의: agents.list[].groupChat.mentionPatterns에 에이전트별 패턴을 설정합니다.

작동 방식 (동작)

  • imsg는 메시지 이벤트를 스트리밍하며, Gateway는 이를 공유 채널 envelope로 정규화합니다.
  • 응답은 항상 동일한 chat id 또는 핸들로 라우팅됩니다.

그룹형 스레드 (is_group=false)

일부 iMessage 스레드는 여러 참가자를 가질 수 있지만, Messages가 채팅 식별자를 저장하는 방식에 따라 is_group=false로 도착할 수 있습니다.

channels.imessage.groups 아래에 chat_id를 명시적으로 구성하면, OpenClaw는 해당 스레드를 "그룹"으로 처리합니다:

  • 세션 격리 (별도의 agent:<agentId>:imessage:group:<chat_id> 세션 키)
  • 그룹 허용목록 / 멘션 게이팅 동작

예시:

{
  channels: {
    imessage: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15555550123"],
      groups: {
        "42": { "requireMention": false }
      }
    }
  }
}

특정 스레드에 대한 격리된 personality/모델이 필요한 경우 유용합니다(Multi-agent routing 참조). 파일시스템 격리는 Sandboxing을 참조하세요.

미디어 + 제한사항

  • channels.imessage.includeAttachments를 통한 선택적 첨부파일 수집.
  • channels.imessage.mediaMaxMb를 통한 미디어 제한.

제한사항

  • 아웃바운드 텍스트는 channels.imessage.textChunkLimit(기본값 4000)로 청크됩니다.
  • 선택적 줄바꿈 청킹: channels.imessage.chunkMode="newline"로 설정하여 길이 청킹 전에 빈 줄(단락 경계)로 분할합니다.
  • 미디어 업로드는 channels.imessage.mediaMaxMb(기본값 16)로 제한됩니다.

주소 지정 / 전달 대상

안정적인 라우팅을 위해 chat_id 사용 권장:

  • chat_id:123 (권장)
  • chat_guid:...
  • chat_identifier:...
  • 직접 핸들: imessage:+1555 / sms:+1555 / [email protected]

채팅 목록:

imsg chats --limit 20

설정 참조 (iMessage)

전체 설정: Configuration

제공자 옵션:

  • channels.imessage.enabled: 채널 시작 활성화/비활성화.
  • channels.imessage.cliPath: imsg 경로.
  • channels.imessage.dbPath: Messages DB 경로.
  • channels.imessage.remoteHost: cliPath가 원격 Mac을 가리킬 때 SCP 첨부파일 전송을 위한 SSH 호스트(예: user@gateway-host). 설정되지 않으면 SSH 래퍼에서 자동 감지됨.
  • channels.imessage.service: imessage | sms | auto.
  • channels.imessage.region: SMS 지역.
  • channels.imessage.dmPolicy: pairing | allowlist | open | disabled (기본값: pairing).
  • channels.imessage.allowFrom: DM 허용목록 (핸들, 이메일, E.164 번호 또는 chat_id:*). open"*"가 필요합니다. iMessage에는 사용자명이 없으므로 핸들이나 채팅 타겟을 사용합니다.
  • channels.imessage.groupPolicy: open | allowlist | disabled (기본값: allowlist).
  • channels.imessage.groupAllowFrom: 그룹 발신자 허용목록.
  • channels.imessage.historyLimit / channels.imessage.accounts.*.historyLimit: 컨텍스트로 포함할 최대 그룹 메시지 수 (0은 비활성화).
  • channels.imessage.dmHistoryLimit: 사용자 턴 단위의 DM 히스토리 제한. 사용자별 재정의: channels.imessage.dms["<handle>"].historyLimit.
  • channels.imessage.groups: 그룹별 기본값 + 허용목록 (전역 기본값은 "*" 사용).
  • channels.imessage.includeAttachments: 첨부파일을 컨텍스트에 수집.
  • channels.imessage.mediaMaxMb: 인바운드/아웃바운드 미디어 제한 (MB).
  • channels.imessage.textChunkLimit: 아웃바운드 청크 크기 (문자).
  • channels.imessage.chunkMode: length (기본값) 또는 newline으로 길이 청킹 전에 빈 줄(단락 경계)로 분할.

관련 글로벌 옵션:

  • agents.list[].groupChat.mentionPatterns (또는 messages.groupChat.mentionPatterns).
  • messages.responsePrefix.