OpenClaw와 BlueBubbles 연동: iMessage 통합 가이드
번들 플러그인
섹션 제목: “번들 플러그인”현재 OpenClaw 릴리스에는 BlueBubbles가 포함되어 있으므로, 일반적인 패키지 빌드를 사용하는 경우 별도의 openclaw plugins install 단계를 거칠 필요가 없습니다.
OpenClaw BlueBubbles 개요
섹션 제목: “OpenClaw BlueBubbles 개요”OpenClaw BlueBubbles 통합은 macOS의 iMessage 기능을 활용하여 메시지를 주고받는 강력한 방법입니다.
- BlueBubbles 도우미 앱(bluebubbles.app)을 통해 macOS에서 실행됩니다.
- 권장 및 테스트 완료 환경: macOS Sequoia (15). macOS Tahoe (26)에서도 작동하지만, 현재 Tahoe에서는 편집 기능이 작동하지 않으며 그룹 아이콘 업데이트 시 성공으로 표시되어도 동기화되지 않을 수 있습니다.
- OpenClaw는 REST API(
GET /api/v1/ping,POST /message/text,POST /chat/:id/*)를 통해 통신합니다. - 수신 메시지는 webhook을 통해 전달되며, 발신 답장, 입력 표시기, 읽음 확인 및 tapback은 REST 호출로 처리됩니다.
- 첨부 파일과 스티커는 인바운드 미디어로 수집되어 가능한 경우 에이전트에게 표시됩니다.
- 페어링 및 허용 목록은
channels.bluebubbles.allowFrom과 페어링 코드를 사용하여 다른 채널과 동일한 방식으로 작동합니다. - 반응(Reactions)은 Slack이나 Telegram처럼 시스템 이벤트로 표시되므로, 에이전트가 답장을 보내기 전에 해당 반응을 “언급”할 수 있습니다.
- 고급 기능: 메시지 편집, 전송 취소, 답장 스레딩, 메시지 효과, 그룹 관리 기능을 지원합니다.
빠른 시작
섹션 제목: “빠른 시작”BlueBubbles 서버를 설정하고 OpenClaw와 연결하려면 다음 단계를 따르세요.
-
Mac에 BlueBubbles 서버를 설치하세요(bluebubbles.app/install의 지침을 따르세요).
-
BlueBubbles 설정에서 web API를 활성화하고 비밀번호를 설정하세요.
-
openclaw onboard를 실행하여 BlueBubbles를 선택하거나, 수동으로 구성하세요:{channels: {bluebubbles: {enabled: true,serverUrl: "http://192.168.1.100:1234",password: "example-password",webhookPath: "/bluebubbles-webhook",},},} -
BlueBubbles webhook을 Gateway로 지정하세요(예:
https://your-gateway-host:3000/bluebubbles-webhook?password=<password>). -
Gateway를 시작하면 webhook 핸들러가 등록되고 페어링이 시작됩니다.
보안 참고 사항:
- 항상 webhook 비밀번호를 설정하세요.
- Webhook 인증은 항상 필수입니다. OpenClaw는 루프백이나 프록시 구성과 관계없이
channels.bluebubbles.password와 일치하는 비밀번호/guid(예:?password=<password>또는x-password)가 포함되지 않은 BlueBubbles webhook 요청을 거부합니다. - 비밀번호 인증은 전체 webhook 본문을 읽거나 파싱하기 전에 확인됩니다.
Messages.app 활성 상태 유지 (VM / 헤드리스 설정)
섹션 제목: “Messages.app 활성 상태 유지 (VM / 헤드리스 설정)”일부 macOS VM이나 상시 가동 환경에서는 Messages.app이 “유휴(idle)” 상태가 되어 앱을 열거나 포그라운드로 가져오기 전까지 수신 이벤트가 중단될 수 있습니다. 간단한 해결책은 AppleScript와 LaunchAgent를 사용하여 5분마다 Messages.app을 확인하는 것입니다.
1) AppleScript 저장하기
섹션 제목: “1) AppleScript 저장하기”다음 경로에 파일을 저장하세요:
~/Scripts/poke-messages.scpt
예시 스크립트(비대화형; 포커스를 가로채지 않음):
try tell application "Messages" if not running then launch end if
-- Touch the scripting interface to keep the process responsive. set _chatCount to (count of chats) end tellon error -- Ignore transient failures (first-run prompts, locked session, etc).end try2) LaunchAgent 설치하기
섹션 제목: “2) LaunchAgent 설치하기”다음 경로에 파일을 저장하세요:
~/Library/LaunchAgents/com.user.poke-messages.plist
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"> <dict> <key>Label</key> <string>com.user.poke-messages</string>
<key>ProgramArguments</key> <array> <string>/bin/bash</string> <string>-lc</string> <string>/usr/bin/osascript "$HOME/Scripts/poke-messages.scpt"</string> </array>
<key>RunAtLoad</key> <true/>
<key>StartInterval</key> <integer>300</integer>
<key>StandardOutPath</key> <string>/tmp/poke-messages.log</string> <key>StandardErrorPath</key> <string>/tmp/poke-messages.err</string> </dict></plist>참고:
- 이 작업은 300초마다 그리고 로그인 시 실행됩니다.
- 처음 실행할 때 macOS 자동화(Automation) 권한 요청(
osascript→ Messages)이 나타날 수 있습니다. LaunchAgent를 실행하는 동일한 사용자 세션에서 이를 승인하세요.
로드 방법:
launchctl unload ~/Library/LaunchAgents/com.user.poke-messages.plist 2>/dev/null || truelaunchctl load ~/Library/LaunchAgents/com.user.poke-messages.plistOnboarding
섹션 제목: “Onboarding”OpenClaw는 대화형 온보딩 프로세스를 통해 BlueBubbles 설정을 간편하게 도와줍니다. 다음 명령어를 실행하여 설정을 시작하세요.
openclaw onboard마법사는 다음 항목들을 차례로 물어봅니다:
- Server URL (필수): BlueBubbles 서버 주소 (예:
http://192.168.1.100:1234) - Password (필수): BlueBubbles Server 설정에 있는 API 비밀번호
- Webhook path (선택): 기본값은
/bluebubbles-webhook입니다. - DM policy: pairing, allowlist, open, 또는 disabled 중 선택
- Allow list: 전화번호, 이메일 또는 대화 대상
CLI를 사용하여 직접 BlueBubbles를 추가할 수도 있습니다:
openclaw channels add bluebubbles --http-url http://192.168.1.100:1234 --password <password>Access control (DMs + groups)
섹션 제목: “Access control (DMs + groups)”DM과 그룹 대화에 대한 접근 제어는 보안과 운영 효율성을 위해 매우 중요합니다. OpenClaw BlueBubbles 설정에서 대화 정책을 세밀하게 조정할 수 있습니다.
DM:
- 기본값:
channels.bluebubbles.dmPolicy = "pairing". - 알 수 없는 발신자는 페어링 코드를 받게 되며, 승인 전까지 메시지는 무시됩니다 (코드는 1시간 후 만료).
- 승인 방법:
openclaw pairing list bluebubblesopenclaw pairing approve bluebubbles <CODE>
- 페어링은 기본적인 토큰 교환 방식입니다. 자세한 내용은 Pairing을 확인하세요.
그룹:
channels.bluebubbles.groupPolicy = open | allowlist | disabled(기본값:allowlist).channels.bluebubbles.groupAllowFrom은allowlist가 설정되었을 때 그룹 내에서 누가 트리거를 사용할 수 있는지 제어합니다.
Contact name enrichment (macOS, optional)
섹션 제목: “Contact name enrichment (macOS, optional)”BlueBubbles 그룹 webhook은 종종 원시 참가자 주소만 포함합니다. GroupMembers 컨텍스트에 로컬 연락처 이름을 표시하고 싶다면 macOS에서 연락처 정보를 가져오도록 설정할 수 있습니다.
channels.bluebubbles.enrichGroupParticipantsFromContacts = true를 설정하여 조회를 활성화합니다. 기본값은false입니다.- 조회는 그룹 접근, 명령어 권한, 멘션 게이팅이 메시지를 허용한 후에만 실행됩니다.
- 이름이 없는 전화번호 참가자만 정보가 보강됩니다.
- 로컬 일치 항목이 없을 경우 원시 전화번호가 대체 값으로 유지됩니다.
{ channels: { bluebubbles: { enrichGroupParticipantsFromContacts: true, }, },}Mention gating (groups)
섹션 제목: “Mention gating (groups)”BlueBubbles는 iMessage나 WhatsApp과 유사하게 그룹 채팅에 대한 멘션 게이팅을 지원합니다.
agents.list[].groupChat.mentionPatterns(또는messages.groupChat.mentionPatterns)를 사용하여 멘션을 감지합니다.- 그룹에
requireMention이 활성화되면, 에이전트는 멘션되었을 때만 응답합니다. - 권한이 있는 발신자의 제어 명령어는 멘션 게이팅을 우회합니다.
그룹별 설정 예시:
{ channels: { bluebubbles: { groupPolicy: "allowlist", groupAllowFrom: ["+15555550123"], groups: { "*": { requireMention: true }, // default for all groups "iMessage;-;chat123": { requireMention: false }, // override for specific group }, }, },}Command gating
섹션 제목: “Command gating”- 제어 명령어(예:
/config,/model)는 권한 부여가 필요합니다. allowFrom및groupAllowFrom을 사용하여 명령어 권한을 결정합니다.- 권한이 있는 발신자는 그룹에서 멘션 없이도 제어 명령어를 실행할 수 있습니다.
ACP conversation bindings
섹션 제목: “ACP conversation bindings”BlueBubbles 대화는 전송 계층을 변경하지 않고도 지속적인 ACP 워크스페이스로 전환할 수 있습니다.
빠른 운영자 흐름:
- DM 또는 허용된 그룹 채팅 내에서
/acp spawn codex --bind here를 실행합니다. - 해당 BlueBubbles 대화의 향후 메시지는 생성된 ACP 세션으로 라우팅됩니다.
/new및/reset은 바인딩된 동일한 ACP 세션을 현재 위치에서 초기화합니다./acp close는 ACP 세션을 종료하고 바인딩을 제거합니다.
설정된 지속적 바인딩은 type: "acp" 및 match.channel: "bluebubbles"를 포함하는 최상위 bindings[] 항목을 통해 지원됩니다.
match.peer.id는 지원되는 모든 BlueBubbles 대상 형식을 사용할 수 있습니다:
+15555550123또는user@example.com과 같은 정규화된 DM 핸들chat_id:<id>chat_guid:<guid>chat_identifier:<identifier>
안정적인 그룹 바인딩을 위해서는 chat_id:* 또는 chat_identifier:*를 사용하는 것이 좋습니다.
예시:
{ agents: { list: [ { id: "codex", runtime: { type: "acp", acp: { agent: "codex", backend: "acpx", mode: "persistent" }, }, }, ], }, bindings: [ { type: "acp", agentId: "codex", match: { channel: "bluebubbles", accountId: "default", peer: { kind: "dm", id: "+15555550123" }, }, acp: { label: "codex-imessage" }, }, ],}공유 ACP 바인딩 동작에 대해서는 ACP Agents를 참조하세요.
Typing + read receipts
섹션 제목: “Typing + read receipts”- Typing indicators: 응답 생성 전과 생성 중에 자동으로 전송됩니다.
- Read receipts:
channels.bluebubbles.sendReadReceipts에 의해 제어됩니다 (기본값:true). - Typing indicators: OpenClaw는 타이핑 시작 이벤트를 전송하며, BlueBubbles는 전송 시 또는 타임아웃 시 자동으로 타이핑 상태를 지웁니다 (DELETE를 통한 수동 중지는 신뢰할 수 없습니다).
{ channels: { bluebubbles: { sendReadReceipts: false, // disable read receipts }, },}고급 작업
섹션 제목: “고급 작업”OpenClaw BlueBubbles 설정을 통해 메시지 전송 시 다양한 고급 기능을 활용할 수 있습니다. 설정 파일에서 다음 옵션을 활성화하여 기능을 제어해 보세요.
{ channels: { bluebubbles: { actions: { reactions: true, // tapbacks (default: true) edit: true, // edit sent messages (macOS 13+, broken on macOS 26 Tahoe) unsend: true, // unsend messages (macOS 13+) reply: true, // reply threading by message GUID sendWithEffect: true, // message effects (slam, loud, etc.) renameGroup: true, // rename group chats setGroupIcon: true, // set group chat icon/photo (flaky on macOS 26 Tahoe) addParticipant: true, // add participants to groups removeParticipant: true, // remove participants from groups leaveGroup: true, // leave group chats sendAttachment: true, // send attachments/media }, }, },}사용 가능한 작업 목록은 다음과 같습니다.
- react: Tapback 반응을 추가하거나 제거합니다 (
messageId,emoji,remove). - edit: 전송된 메시지를 수정합니다 (
messageId,text). - unsend: 메시지 전송을 취소합니다 (
messageId). - reply: 특정 메시지에 답장을 보냅니다 (
messageId,text,to). - sendWithEffect: iMessage 효과를 적용하여 전송합니다 (
text,to,effectId). - renameGroup: 그룹 채팅 이름을 변경합니다 (
chatGuid,displayName). - setGroupIcon: 그룹 채팅 아이콘이나 사진을 설정합니다 (
chatGuid,media). macOS 26 Tahoe에서는 불안정할 수 있으며, API가 성공을 반환해도 아이콘이 동기화되지 않을 수 있습니다. - addParticipant: 그룹에 참가자를 추가합니다 (
chatGuid,address). - removeParticipant: 그룹에서 참가자를 제거합니다 (
chatGuid,address). - leaveGroup: 그룹 채팅에서 나갑니다 (
chatGuid). - upload-file: 미디어나 파일을 전송합니다 (
to,buffer,filename,asVoice).- 음성 메모: MP3 또는 CAF 오디오 파일과 함께
asVoice: true를 설정하면 iMessage 음성 메시지로 전송됩니다. BlueBubbles는 음성 메모 전송 시 MP3를 CAF로 변환합니다. - 레거시 별칭:
sendAttachment도 여전히 작동하지만,upload-file이 표준 작업 이름입니다.
- 음성 메모: MP3 또는 CAF 오디오 파일과 함께
메시지 ID (단축 vs 전체)
섹션 제목: “메시지 ID (단축 vs 전체)”OpenClaw는 토큰을 절약하기 위해 단축(short) 메시지 ID(예: 1, 2)를 노출할 수 있습니다.
MessageSid/ReplyToId는 단축 ID일 수 있습니다.MessageSidFull/ReplyToIdFull에는 제공업체의 전체 ID가 포함됩니다.- 단축 ID는 메모리에 저장되므로, 재시작하거나 캐시가 삭제되면 만료될 수 있습니다.
- 작업 시 단축 ID와 전체
messageId를 모두 사용할 수 있지만, 단축 ID가 더 이상 유효하지 않으면 오류가 발생합니다.
지속적인 자동화와 저장을 위해서는 전체 ID를 사용하세요.
- 템플릿:
{{MessageSidFull}},{{ReplyToIdFull}} - 컨텍스트: 인바운드 페이로드의
MessageSidFull/ReplyToIdFull
템플릿 변수에 대한 자세한 내용은 Configuration을 확인하세요.
블록 스트리밍
섹션 제목: “블록 스트리밍”응답을 단일 메시지로 보낼지, 아니면 블록 단위로 스트리밍할지 제어할 수 있습니다.
{ channels: { bluebubbles: { blockStreaming: true, // enable block streaming (off by default) }, },}미디어 및 제한 사항
섹션 제목: “미디어 및 제한 사항”수신되는 첨부 파일은 미디어 캐시에 다운로드되어 저장됩니다. OpenClaw 미디어 처리 기능을 사용할 때 참고하세요.
- 인바운드 및 아웃바운드 미디어에 대한 미디어 용량 제한은
channels.bluebubbles.mediaMaxMb를 통해 설정하며, 기본값은 8MB입니다. - 아웃바운드 텍스트는
channels.bluebubbles.textChunkLimit설정에 따라 청크 단위로 나뉘며, 기본값은 4000자입니다.
구성 참조
섹션 제목: “구성 참조”전체 구성에 대한 자세한 내용은 Configuration 문서를 확인해 주세요. OpenClaw 구성 옵션은 다음과 같습니다.
제공자 옵션:
channels.bluebubbles.enabled: 채널 활성화 또는 비활성화 여부를 결정합니다.channels.bluebubbles.serverUrl: BlueBubbles REST API의 기본 URL입니다.channels.bluebubbles.password: API 비밀번호입니다.channels.bluebubbles.webhookPath: webhook 엔드포인트 경로이며, 기본값은/bluebubbles-webhook입니다.channels.bluebubbles.dmPolicy:pairing | allowlist | open | disabled중 선택하며, 기본값은pairing입니다.channels.bluebubbles.allowFrom: DM 허용 목록으로, 핸들, 이메일, E.164 번호,chat_id:*,chat_guid:*등을 처리합니다.channels.bluebubbles.groupPolicy:open | allowlist | disabled중 선택하며, 기본값은allowlist입니다.channels.bluebubbles.groupAllowFrom: 그룹 발신자 허용 목록입니다.channels.bluebubbles.enrichGroupParticipantsFromContacts: macOS에서 게이팅 통과 후 로컬 연락처를 기반으로 이름 없는 그룹 참가자 정보를 보강할지 여부를 결정하며, 기본값은false입니다.channels.bluebubbles.groups: 그룹별 설정(requireMention등)입니다.channels.bluebubbles.sendReadReceipts: 읽음 확인 메시지 전송 여부이며, 기본값은true입니다.channels.bluebubbles.blockStreaming: 블록 스트리밍 활성화 여부이며, 기본값은false입니다(스트리밍 응답에 필요).channels.bluebubbles.textChunkLimit: 아웃바운드 텍스트 청크 크기(문자 단위)이며, 기본값은 4000입니다.channels.bluebubbles.sendTimeoutMs:/api/v1/message/text를 통한 아웃바운드 텍스트 전송 시 요청당 제한 시간(밀리초)이며, 기본값은 30000입니다. macOS 26 설정에서 Private API iMessage 전송이 iMessage 프레임워크 내에서 60초 이상 지연될 수 있으므로, 필요 시45000또는60000으로 높이세요. 프로브, 채팅 조회, 반응, 편집 및 상태 확인은 현재 10초의 짧은 기본값을 유지하며, 향후 반응 및 편집까지 범위를 넓힐 계획입니다. 계정별 재정의는channels.bluebubbles.accounts.<accountId>.sendTimeoutMs를 사용하세요.channels.bluebubbles.chunkMode:length(기본값)는textChunkLimit를 초과할 때만 분할하며,newline은 길이 제한 적용 전 빈 줄(단락 경계)에서 분할합니다.channels.bluebubbles.mediaMaxMb: 인바운드/아웃바운드 미디어 용량 제한(MB 단위)이며, 기본값은 8입니다.channels.bluebubbles.mediaLocalRoots: 아웃바운드 로컬 미디어 경로에 대해 허용되는 절대 로컬 디렉토리 목록입니다. 이 설정이 없으면 로컬 경로 전송은 기본적으로 거부됩니다. 계정별 재정의는channels.bluebubbles.accounts.<accountId>.mediaLocalRoots를 사용하세요.channels.bluebubbles.historyLimit: 컨텍스트를 위한 최대 그룹 메시지 수이며, 0으로 설정 시 비활성화됩니다.channels.bluebubbles.dmHistoryLimit: DM 기록 제한입니다.channels.bluebubbles.actions: 특정 작업의 활성화/비활성화 여부입니다.channels.bluebubbles.accounts: 다중 계정 구성입니다.
관련 전역 옵션:
agents.list[].groupChat.mentionPatterns(또는messages.groupChat.mentionPatterns).messages.responsePrefix.
주소 지정 및 전송 대상
섹션 제목: “주소 지정 및 전송 대상”메시지를 보낼 때 안정적인 라우팅을 위해 chat_guid를 사용하는 것을 권장합니다.
chat_guid:iMessage;-;+15555550123(그룹 채팅에 권장)chat_id:123chat_identifier:...- 직접 핸들:
+15555550123,user@example.com- 만약 직접 핸들에 대한 기존 DM 채팅이 없다면, OpenClaw는
POST /api/v1/chat/new를 통해 새로운 채팅을 생성합니다. 이 기능을 사용하려면 BlueBubbles Private API가 활성화되어 있어야 합니다.
- 만약 직접 핸들에 대한 기존 DM 채팅이 없다면, OpenClaw는
webhook 요청은 guid/password 쿼리 매개변수나 헤더를 channels.bluebubbles.password와 비교하여 인증합니다.
- API 비밀번호와 webhook 엔드포인트는 자격 증명처럼 취급하여 안전하게 보관하세요.
- BlueBubbles webhook 인증에는 localhost 우회 기능이 없습니다. webhook 트래픽을 프록시하는 경우, 요청의 처음부터 끝까지 BlueBubbles 비밀번호를 유지해야 합니다.
gateway.trustedProxies는 여기서channels.bluebubbles.password를 대체하지 않습니다. 자세한 내용은 Gateway 보안 문서를 확인하세요. - BlueBubbles 서버를 LAN 외부로 노출하는 경우, 반드시 HTTPS를 활성화하고 방화벽 규칙을 설정하세요.
문제 해결
섹션 제목: “문제 해결”메시지 입력이나 읽음 상태 이벤트가 제대로 작동하지 않는다면, BlueBubbles webhook 로그를 확인하고 Gateway 경로가 channels.bluebubbles.webhookPath 설정과 일치하는지 확인해 보세요.
- 페어링 코드는 한 시간 뒤에 만료됩니다. 코드를 다시 확인하려면 CLI에서
openclaw pairing list bluebubbles를 입력하고, 승인하려면openclaw pairing approve bluebubbles <code>를 사용하세요. - 메시지 반응(Reactions) 기능을 사용하려면 BlueBubbles API의 private API(
POST /api/v1/message/react)가 필요합니다. 서버 버전이 해당 기능을 지원하는지 꼭 확인해 주세요. - 메시지 수정 및 전송 취소 기능은 macOS 13 이상과 호환되는 BlueBubbles 서버 버전이 필요합니다. macOS 26(Tahoe)에서는 private API 변경으로 인해 현재 수정 기능이 정상적으로 작동하지 않습니다.
- 그룹 아이콘 업데이트는 macOS 26(Tahoe)에서 불안정할 수 있습니다. API는 성공 응답을 보내더라도 실제 아이콘은 동기화되지 않을 수 있습니다.
- OpenClaw는 BlueBubbles 서버의 macOS 버전을 감지하여 알려진 문제가 있는 동작을 자동으로 숨깁니다. 만약 macOS 26(Tahoe)에서 수정 버튼이 계속 보인다면,
channels.bluebubbles.actions.edit=false설정을 통해 수동으로 비활성화하세요. - 상태 및 시스템 진단 정보가 필요할 때는
openclaw status --all또는openclaw status --deep명령어를 실행하세요.
채널 워크플로우에 대한 일반적인 정보는 Channels 가이드와 Plugins 문서를 참고해 주세요.
관련 문서
섹션 제목: “관련 문서”- Channels Overview — 지원되는 모든 채널 정보
- Pairing — DM 인증 및 페어링 흐름 안내
- Groups — 그룹 채팅 동작 및 멘션 제어 설정
- Channel Routing — 메시지 세션 라우팅 방식
- Security — 접근 모델 및 보안 강화 가이드
OpenClaw Expert
아직 막혀 있나요?
이 문서에서 답을 못 찾았다면 OpenClaw Expert에게 바로 물어보세요.