양식의 작동 방식
가입 양식은 사람들을 오디언스에 넣습니다. 여기서 양식을 만들고, 링크로 공유하거나, 어느 사이트에든 삽입하거나, 내 코드에서 양식으로 전송할 수 있습니다.
초안과 게시된 사본
양식은 방문자에게 보이는 내용의 사본을 두 개 보관합니다. document는 편집하는 초안이고, publishedDocument는 호스팅된 페이지, 삽입 코드, subscribe 엔드포인트가 쓰는 것입니다. 저장하면 초안만 바뀌고, POST /forms/{id}/publish가 초안을 게시된 사본으로 복사합니다. hasUnpublishedChanges는 둘이 다르다는 것을 알려 줍니다.
draft: 한 번도 게시되지 않았습니다. 아무도 볼 수 없고, 이를 통해 가입할 수도 없습니다.live: 게시되었고 가입을 받는 중입니다.paused: 게시되었지만 마감되었습니다. 페이지는 문구에 있는 마감 메시지를 보여 주고, 가입은 거부됩니다.
settings는 다릅니다. 가입이 들어갈 곳, 더블 옵트인, 보내는 주소, 가입 후 동작, 각 가입을 누구에게 알릴지를 정합니다. 게시 여부와 상관없이 저장하는 즉시 적용됩니다.
필드
문서는 fields 목록, 그 주변의 문구인 copy, 그리고 style로 이루어집니다. 각 입력 필드에는 key가 있으며, 이는 답변이 전송될 때 쓰이는 이름입니다. 소문자 하나로 시작하고 그 뒤에 소문자, 숫자, 밑줄이 최대 39자까지 이어지며, 양식 안에서 고유해야 하고 oe_로 시작할 수 없습니다. 모든 양식에는 키가 email이고 필수인 email 필드가 정확히 하나 있습니다.
- 입력:
email,text,textarea,number,phone,url,date. - 선택형:
select,radio,checkboxes이며, 각각options를 가집니다. checkbox는 예 또는 아니요를 위한 것이고,consent는 필수일 때 반드시 체크해야 하는 상자를 위한 것입니다.audiences는 사람이 목록을 고르게 합니다. 각 옵션의value는 이 워크스페이스의 오디언스 id입니다.hidden은 방문자에게 보이지 않는 값을 담습니다. 페이지가 전송한 값이며, 없으면defaultValue로, 예를 들면 캠페인 이름입니다.heading,paragraph,divider는 양식의 배치에만 쓰이며 아무것도 전송하지 않습니다.
텍스트 필드의 mapsTo를 firstName, lastName, name 중 하나로 설정하면, 그 답변이 가입으로 만들어지는 연락처의 이름이 됩니다. 이미 있는 연락처는 원래 이름을 유지합니다. 모든 답변은 당시의 레이블과 함께 제출에 보관되므로, 양식이 바뀐 뒤에도 예전 제출을 제대로 읽을 수 있습니다.
더블 옵트인
settings.doubleOptIn이 켜져 있으면 가입은 pending으로 저장되고, 이 워크스페이스의 주소인 settings.senderAddress에서 그 사람에게 링크가 이메일로 발송됩니다. 그 사람이 링크를 열면 오디언스에 들어갑니다. 링크는 7일 동안 유효합니다. 예전에 오디언스 구독을 해지한 사람은 이 방법으로만 다시 구독되며, 싱글 옵트인 양식으로는 절대 다시 구독되지 않습니다. 확인 전에 다시 가입하면 새 가입이 추가되지 않고 대기 중인 가입이 업데이트됩니다.
메일을 받는 사람들을 보호하기 위해, 한 주소는 양식마다 10분에 최대 한 통, 워크스페이스 전체에서 하루 다섯 통까지만 확인 메일을 받습니다. 확인 대기 중인 가입은 직접 승인하거나 새 링크를 보낼 수 있습니다.
누가 무엇을 볼 수 있는가
- 읽기에는
forms:read, 변경에는forms:write가 필요합니다. 가입을 승인하면 연락처가 추가되므로contacts:write도 필요합니다. - 양식이 메일을 보내게 하는 작업에는
emails:send도 필요합니다. 더블 옵트인 켜기, 보내는 주소나 확인 메일 설정, 더블 옵트인 양식의 게시나 재개, 확인 메일 다시 보내기가 여기에 해당합니다. - API 키와 소유자는 워크스페이스의 모든 양식을 봅니다. 멤버가 연결한 앱은 그 멤버가 만든 양식만 보고, 오디언스도 그 멤버가 만든 것과 내장된 것만 봅니다.
- 보내는 주소나 알림 주소가 제한된 키나 앱이 닿을 수 있는 범위를 벗어난 양식을 만들거나, 수정하거나, 게시하거나, 재개하거나, 복제하면 422
capability_unsupported로 응답합니다. - 일부 주소로 제한된 키나 앱은 자신이 가진 주소만 보내는 주소와 알림 주소로 설정할 수 있습니다.
- 양식을 삭제할 때는 다른 파괴적인 변경과 마찬가지로 OAuth 앱에 인증 코드를 요구합니다. API 키에는 인증 코드가 필요 없습니다.
form.submitted와 form.confirmed 웹훅이 모든 가입을 내 시스템에 알려 줍니다. 가입은 워크스페이스 전체에 속하므로, 일부 주소로 제한된 웹훅은 이 이벤트를 받지 않습니다.
봇과 한도
oe_website라는 이름의 필드는 봇을 잡는 함정입니다. 위의 HTML처럼 비워 두고 화면 밖에 두세요. 이 필드를 채운 가입은 평소와 같은 응답을 받지만 버려집니다.- 호스팅된 페이지와 삽입 코드는 서명된 시작 시각도 검사하며, 사람이 작성할 수 있는 것보다 빨리 돌아온 양식도 같은 방식으로 버려집니다.
- 한 네트워크는 모든 양식을 통틀어, 결과와 상관없이 10분에 40번까지 가입을 보낼 수 있습니다. 그 뒤에는 JSON 호출자는 429
form_rate_limited를 받고, 순수 HTML 양식은?outcome=limited가 붙은 호스팅된 페이지로 이동합니다. - 워크스페이스는 기본적으로 양식을 100개까지 가질 수 있습니다.
코드, 터미널, 에이전트에서
여기 있는 모든 것은 SDK에서는 openemail.forms, CLI에서는 openemail forms로도 쓸 수 있고, MCP 서버에는 양식 도구가 있으므로, 에이전트가 양식을 만들고, 게시하고, 지켜볼 수 있습니다. MCP에서는 클라이언트가 디자인을 직접 작성해 document로 넘깁니다.
내 코드에서 subscribeUrl로 전송할 때는 자격 증명이 필요 없습니다. 답변은 JSON으로 보내고, 양식이 있던 페이지를 oe_source로 더하고, oe_started는 빼고, oe_website는 빈 값으로 보내거나 아예 빼세요. 한 네트워크에서 오는 모든 가입은 10분마다 40번이라는 한도를 함께 쓰므로, 많은 사람의 가입을 중계하는 서버는 금방 한도에 닿습니다. 이미 아는 사람은 대신 오디언스 가져오기로 추가하세요.