Markpin은 웹에서 글을 읽으며 형광펜을 긋고 왜 그었는지 적어 두는 Chrome 확장이다. 브라우저에서 되는 것들은 이제 어느 정도 자리를 잡았는데, 그걸 모바일에서도 가능한 만큼 쓸 수 있게 하는 게 이번 작업의 목표였다. 폰에서 읽다가 저장해 둔 글을 PC에서 이어 읽고, PC에서 그어 둔 형광펜을 폰에서 다시 보는 정도까지. 1.3.0에서 그 부분을 어느 정도 해냈고, 이 글은 폰에서 어떻게 쓰는지와 만들면서 왜 이런 모양이 됐는지를 순서대로 적어 보고자 한다.
결과부터
폰에서 markpin.dev/app을 열어 PC에서 쓰는 Google 계정으로 연결하면, PC에서 저장한 글과 형광펜, 메모가 그대로 보인다. Android에서는 글을 읽다가 공유 → Markpin을 고르면 저장되고, 문장을 먼저 선택한 채로 공유하면 그 문장이 마크로 남는다. 본문은 폰이 가져오지 않고 PC Chrome이 채운다. iPhone은 지금 다시 보기까지 되고, 저장과 마킹은 준비 중이다.

왜 Chrome 확장이 아니라 웹앱인가
처음엔 당연히 확장을 그대로 폰에 올리면 되는 줄 알았는데, Chrome Android에는 확장 프로그램이라는 게 없다. Edge Android와 Firefox Android는 확장을 지원하지만 사이드패널이나 getAuthToken 같은 API가 빠져 있어서 지금 코드가 그대로 올라가지는 않고, Safari는 Xcode로 감싸서 App Store에 올려야 한다(연 $99). 결국 폰마다 길이 다 달랐다.
그래서 우선 어느 폰에서든 되는 것부터 하기로 했다. 그게 markpin.dev/app이라는 PWA다. Android Chrome과 삼성 인터넷은 설치한 PWA를 공유 시트의 대상으로 등록할 수 있어서(share_target), 아무 앱에서나 공유 버튼을 누르면 Markpin이 목록에 뜬다. 공유로 넘어오는 건 URL과 선택한 텍스트 정도라서, 문장을 선택하고 공유하면 그 문장이 형광펜 하나가 되고 선택 없이 공유하면 글만 저장된다. 페이지 안에서 직접 형광펜을 긋는 건 PWA로는 안 되는데, 이건 Edge·Firefox용 확장을 따로 만들 생각이다(이게 다음 플랜이다).
본문은 왜 PC가 채우나
폰에서 공유로 받은 글은 제목도 본문도 없이 URL만 있는 상태로 저장된다. PWA가 그 URL을 직접 가져올 수도 있겠지만, 다른 사이트의 HTML을 브라우저 안에서 읽어 오는 건 CORS 때문에 대부분 막히고, 서버를 두고 대신 받아 오는 건 Markpin의 원칙(서버 없음, 계정 없음)과 맞지 않았다. 그래서 PC Chrome의 확장이 동기화할 때 본문이 비어 있는 글을 발견하면 그 URL을 받아 와 읽기 좋게 추출하고(이때 쓰는 게 이번에 추가된 offscreen 권한이다. 서비스 워커에는 DOM이 없어서 보이지 않는 문서에서 파싱한다), 제목과 본문을 채워 다시 Drive에 올린다. 폰은 다음 동기화 때 그걸 받아서 제목이 en.wikipedia.org에서 Pencil로 바뀐다.
이 구조의 단점도 솔직히 적어 두면, PC Chrome이 켜져 있고 Drive에 연결돼 있어야 본문이 채워진다는 것이다. 검증하면서 PC 쪽 확장이 「재연결 필요」 상태인 걸 모르고 한참 기다린 적이 있는데(폰 쪽에는 아무 신호가 없었다…), 그래서 폰의 문구를 「본문은 PC Chrome이 열려 있고 연결돼 있을 때 채워져요」로 바꿨다. PC 상태를 폰에 알려 주는 건 다음 과제로 남겨 뒀다.
같은 Google Drive로 잇기
데스크톱 확장은 처음부터 Google Drive에 drive.file 권한으로만 파일을 쓰는데, 이 권한은 "이 앱이 만든 파일만 보인다"는 뜻이고 여기서 "앱"은 OAuth 클라이언트 단위다. 즉 확장과 PWA가 서로 다른 클라이언트 ID를 쓰면 같은 계정이어도 서로의 파일이 안 보인다. 이걸 조사 단계에서 알고 나서 데스크톱 확장의 인증을 Web 클라이언트로 바꿨고(모바일 작업에서 제일 먼저 한 일이다), PWA도 같은 클라이언트로 리다이렉트 방식으로 로그인한다. 덕분에 서버 없이 양쪽이 같은 폴더를 본다.
두 기기가 같은 글을 고치는 경우도 생겨서 병합 방식도 바꿨다. 전에는 페이지 단위로 늦게 쓴 쪽이 이기고 충돌하면 .conflict 사본을 만들었는데, 이제는 클립·메모·태그 단위로 세 방향 병합을 한다. PC에서 그은 형광펜 2개와 폰에서 공유한 문장 2개가 같은 글에 있으면 4개가 되는 식이다. 검증할 때 실제로 이 경우가 나왔는데 사본 없이 합쳐지는 걸 보고 좀 안심했다.
폰 없이 폰을 검증하기
부끄럽지만 나는 Android 폰이 없다. 그래서 Android 에뮬레이터(Play 스토어 이미지, Chrome 124)를 띄워 놓고 공유 → 저장 → Google 연결 → PC Chrome이 본문 채움 → 폰에 반영까지를 돌렸다. 비행기 모드에서 공유하면 로컬에 먼저 저장됐다가 나중에 올라가는 것, 링크 없는 텍스트를 공유하면 「주소를 찾지 못했어요」가 뜨는 것, 로그인 뒤에 브라우저 탭이 아니라 홈 화면 앱으로 돌아오는 것까지 이때 확인했다. 실기기에서만 보이는 문제가 분명 있을 테니, 써 보고 이상하면 support@markpin.dev로 알려 주시면 감사하겠다.
쓰는 방법
- Android Chrome에서 markpin.dev/app을 연다. 메뉴의 「홈 화면에 추가」에서 「설치」를 고르면 앱처럼 열린다(공유 대상으로 뜨려면 이 설치가 필요하다).
- 「Google 계정으로 연결」을 누르고 PC에서 쓰는 계정으로 로그인한다. 잠시 뒤 「n개 글이 왔어요」와 함께 목록이 채워진다.
- 아무 앱에서 글을 읽다가 공유 → Markpin. 문장을 먼저 선택하고 공유하면 그 문장이 마크가 된다.
- PC Chrome이 켜져 있으면 몇 분 안에 본문과 제목이 채워지고, 폰에서도 다음 동기화 때 바뀐다.
iPhone은 Safari에서 같은 주소를 열고 공유 → 「홈 화면에 추가」를 하면 다시 보기까지는 된다. 저장과 마킹은 Safari 확장으로 만들어야 하는데, 얼마나 필요로 하는지 보고 순서를 정하려고 알림 신청을 받고 있다.
앞으로는 Edge·Firefox Android용 확장을 올려서 폰에서도 페이지 안에 직접 형광펜을 긋게 하는 게 다음 순서인데, 그 전에 이번 PWA를 써 보신 분들의 이야기를 좀 듣고 싶다. 폰에서 저장만 해 두고 PC에서 이어 읽는 흐름이 실제로 쓸 만한지가 제일 궁금하다.