본문 바로가기
배포/스프레드 시트

roll20 핸드아웃 다중생성 API

by 청화화 2025. 9. 15.

 

inSANe과 같이 핸드아웃이 많을 때 사용할 수 있는 Roll20 API입니다.

아쉽게도 핸드아웃 css는 적용이 안되지만 그외에는 무난히 잘 올라갑니다.

 

API

더보기

// Handout Manager - Google 시트의 데이터를 받아 핸드아웃을 생성/업데이트하는 스크립트
on("chat:message", function(msg) {
    if (msg.type === "api" && msg.content.startsWith("!update-handout")) {
        const jsonString = msg.content.substring("!update-handout".length).trim();
        log("Received Handout JSON: " + jsonString);

        try {
            const handoutsData = JSON.parse(jsonString);

            if (!Array.isArray(handoutsData)) {
                sendChat("API", "핸드아웃 오류: 데이터 형식이 JSON 배열이 아닙니다.");
                return;
            }

            handoutsData.forEach(data => {
                const handoutName = data.handoutName;
                if (!handoutName) {
                    log("핸드아웃 오류: handoutName이 없어 해당 항목을 건너뜁니다.");
                    return;
                }

                let handout = findObjs({ _type: "handout", name: handoutName })[0];

                if (!handout) {
                    handout = createObj('handout', { name: handoutName });
                    sendChat("API", `핸드아웃 '${handoutName}'이(가) 생성되었습니다.`);
                }

                // 'Bio & Info' (notes)와 'GM Notes' (gmnotes)를 설정합니다.
                if (data.notes !== undefined) {
                    handout.set('notes', data.notes);
                }
                if (data.gmnotes !== undefined) {
                    handout.set('gmnotes', data.gmnotes);
                }

                // 이미지, 플레이어 저널, 수정 권한을 설정합니다.
                if (data.image_url) {
                    handout.set('avatar', data.image_url);
                }
                if (data.inplayerjournals) {
                    handout.set('inplayerjournals', data.inplayerjournals);
                }
                if (data.controlledby) {
                    handout.set('controlledby', data.controlledby);
                }
            });
            
            sendChat("API", "핸드아웃 업데이트가 완료되었습니다.");

        } catch (e) {
            sendChat("API", `핸드아웃 JSON 파싱 오류: ${e.message}`);
            log("Handout JSON Parsing Failed for: " + jsonString);
        }
    }
});

 


스프레드 시트