사용 설명서 > 개발자 문서 > 번들 규격
manifest 작성법
이 글의 목차
manifest 의 필수 키는 name·sdk_version·permissions·screens·events·variables 입니다. 선택 키는 actions·form_binding 이고, format_version 2 에서만 state 를 더 쓸 수 있습니다.
| 키 | 모양 | 규칙 |
|---|---|---|
| name | 문자열 | 비어 있지 않아야 합니다. |
| sdk_version | "1" | 문자열 "1" 고정. |
| permissions | 문자열 배열 | 아래 권한 표의 값만. 중복 불가. JS 가 쓰는 FC 호출에 필요한 권한은 모두 선언해야 합니다. |
| screens | [{ key, label }] | 화면 이름 목록. HTML 에서 data-screen="key" 요소로 대응시키는 것이 관례입니다. |
| events | [{ name, fields }] | 최대 30개. name 은 소문자로 시작하는 소문자·숫자·점·밑줄(64자). contact.·lead.·order.·tag. 로 시작하는 이름은 예약. |
| variables | [{ name, type, default, ... }] | 사용자가 앱빌더에서 바꿀 수 있는 값. type 은 text·color·number·boolean·select. |
| actions | [{ key, kind, ... }] | 서버가 실행하는 기능(검색·AI·Webhook·이미지·PDF·업로드) 선언. 1~5개. |
| state | [{ name, type, default?, persist? }] | format_version 2 전용. 메모리 상태. persist 는 false 만 가능. |
권한(permissions)
| 권한 | 설명 | 비고 |
|---|---|---|
| ai.generate | 방문자가 입력한 글을 FC AI가 처리한다(요약·분석·분류·추천·대화). 호출마다 크레딧이 든다. | 짝 Action: ai.generate |
| automation.trigger | 앱 이벤트로 자동화를 깨운다. events.emit 이 함께 필요하다(자동으로 포함된다). | 자동 포함: events.emit |
| contacts.tag | 연락처에 태그를 붙인다. 붙일 수 있는 태그는 앱 소유자가 설치 화면에서 미리 허용한 것뿐이다. | - |
| contacts.write | 연락처(이메일·이름·전화 등)를 만든다. | - |
| events.emit | 앱 이벤트를 기록한다(통계·자동화 연결용). | - |
| forms.read | 연결된 Form의 필드 구성을 읽는다. | - |
| forms.submit | 연결된 Form로 제출한다. | - |
| image.generate | 방문자 입력으로 AI 이미지를 만든다. 호출마다 이미지 크레딧이 든다. | 짝 Action: image.generate |
| page.redirect | 방문자를 다른 주소로 이동시킨다. | - |
| pdf.generate | 서버가 PDF 문서를 만들어 방문자가 저장하게 한다. | 짝 Action: pdf.generate |
| search.web | 방문자의 검색어로 웹·뉴스를 검색한다. | 짝 Action: search.web |
| upload.file | 방문자의 이미지·PDF 파일을 받는다(서류 제출·AI 입력 자료). | 짝 Action: upload.file |
| webhook.send | 앱 소유자가 연결해 둔 Webhook 주소로 선언한 필드만 보낸다. | 짝 Action: webhook.post |
권한과 Action 은 짝입니다. search.web·ai.generate·webhook.send·image.generate·pdf.generate·upload.file 권한을 선언하면 같은 종류의 Action 이 있어야 하고, 반대로 Action 이 있으면 그 권한이 있어야 합니다. 권한을 필요 이상으로 늘리지 마세요 — 앱 소유자가 승인 화면에서 모두 보게 됩니다.
events(이벤트) 선언
이벤트는 앱이 보내는 결과 신호(예 quiz.completed)입니다. 선언한 이름·필드와 정확히 맞는 값만 FC.event.emit 으로 보낼 수 있습니다.
{ "name": "roi.completed",
"fields": { "roi_percent": { "type": "number", "required": true },
"revenue": { "type": "number", "required": true, "minimum": 1 } } }
필드 type 은 string·number·boolean 이고 required·enum·minimum·maximum 을 쓸 수 있습니다.
variables(변수)와 settings
변수는 사용자가 앱빌더에서 문구·색상 등을 바꿀 수 있게 열어 두는 값입니다. settings 에 현재 값을 넣고, 앱 JS 는 FC.settings.이름 으로 읽습니다.
| type | 쓸 수 있는 키 |
|---|---|
| text | name, default, min_length, max_length |
| number | name, default, minimum, maximum |
| boolean | name, default |
| color | name, default (#RRGGBB) |
| select | name, default, options |
Action(actions)
검색·AI·Webhook·이미지·PDF·업로드처럼 서버가 대신 실행하는 기능은 번들에 "선언"만 담습니다. API 키·모델·주소는 서버가 정하며 번들에 쓰지 않습니다.
search.web Action
방문자의 검색어로 웹을 검색한다. 앱 JS 는 FC.search.web 로 호출하고, 권한 search.web 이 필요합니다.
필수 키: key, kind, connection / 선택 키: source, top_n, locale
{
"key": "web_search",
"kind": "search.web",
"connection": {
"mode": "managed"
},
"source": "web",
"top_n": 5,
"locale": "ko"
}
- connection 은 { "mode": "managed" } 만 쓴다(검색 API 키·주소를 코드에 쓰지 않는다).
- source 는 web 또는 news, locale 은 ko 또는 en, top_n 은 1~10이다.
ai.generate Action
방문자 입력을 FC AI가 처리한다. 모델·키는 서버가 정한다. 앱 JS 는 FC.ai.generate / FC.ai.chat 로 호출하고, 권한 ai.generate 이 필요합니다.
필수 키: key, kind, connection, instruction / 선택 키: output, fields, mode, search, model
{
"key": "summarize",
"kind": "ai.generate",
"connection": {
"mode": "managed"
},
"instruction": "입력된 글을 한국어로 세 문장 이내로 요약한다.",
"output": "text"
}
- instruction 은 2000자 이내, 방문자에게 보이지 않는 지시문이다. 역할·출력 형식·길이를 구체적으로 적는다.
- output 이 "json" 이면 fields(1~12개, { key, type, description? })를 선언하고 결과는 { data } 로 온다. type 은 string·number·boolean·string_list.
- 대화형은 "mode": "chat" 이고 구조화 출력("json")과 함께 쓸 수 없다.
- "search": { "action": "검색_액션_키" } 로 같은 번들의 search.web Action 을 먼저 실행해 그 결과를 AI에 넘기는 체인을 만들 수 있다.
webhook.post Action
선언한 필드만 앱 소유자가 연결한 Webhook 주소로 보낸다. 앱 JS 는 FC.webhook.send 로 호출하고, 권한 webhook.send 이 필요합니다.
필수 키: key, kind, connection, fields
{
"key": "send_result",
"kind": "webhook.post",
"connection": {
"mode": "connection",
"ref": "mac-xxxxxxxx"
},
"fields": [
{
"key": "email",
"type": "string"
},
{
"key": "score",
"type": "number"
}
]
}
- connection.ref 는 앱 소유자가 앱빌더 연결 화면에서 Webhook 을 만들 때 생기는 값이다. 외부에서 만든 번들은 그 값을 모르므로 올린 뒤 연결 화면에서 고르게 안내한다. 주소(URL)·토큰을 코드에 쓰지 않는다.
- fields 는 1~12개이며 선언하지 않은 키는 전달되지 않는다.
image.generate Action
방문자 입력으로 AI 이미지를 만든다. 호출마다 크레딧이 든다. 앱 JS 는 FC.image.generate 로 호출하고, 권한 image.generate 이 필요합니다.
필수 키: key, kind, connection / 선택 키: style, instruction, reference
{
"key": "draw",
"kind": "image.generate",
"connection": {
"mode": "managed"
},
"style": "illustration"
}
- style 은 realistic·illustration·minimal·flat·3d·watercolor·abstract 중 하나(선택), instruction 은 400자 이하(선택)다.
- 업로드한 사진을 참고하려면 "reference": true 를 선언한다.
pdf.generate Action
견적서·결과 리포트 같은 문서를 서버가 PDF 로 만든다. 앱 JS 는 FC.pdf.generate / FC.pdf.save 로 호출하고, 권한 pdf.generate 이 필요합니다.
필수 키: key, kind, connection / 선택 키: accent, filename
{
"key": "make_pdf",
"kind": "pdf.generate",
"connection": {
"mode": "managed"
},
"accent": "#4A3094",
"filename": "견적서"
}
- 문서는 최대 약 60KB·30쪽이다. 이모지는 지워진다.
upload.file Action
방문자의 이미지·PDF 파일을 받는다. 앱 JS 는 FC.upload.send 로 호출하고, 권한 upload.file 이 필요합니다.
필수 키: key, kind, connection, purpose / 선택 키: accept, max_files
{
"key": "docs",
"kind": "upload.file",
"connection": {
"mode": "managed"
},
"purpose": "submission",
"accept": [
"image",
"pdf"
],
"max_files": 3
}
- purpose 는 submission(서류 제출, 소유자가 받아 봄·90일 보관) 또는 ai_input(AI 입력 자료, 이미지만·24시간 보관)이다.
- max_files 는 1~10, accept 는 image·pdf 이며 ai_input 은 image 만 가능하다.