You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Google Form指定问题的回复设为Discord线程名称?

问题

我想把Google Form里某条指定回复用作Discord表单线程的标题,本人主力语言不是JavaScript,求解决方案。以下是我目前的代码:

// The Post url to send the embed to. This is where you should paste your webhook link.
var POST_URL = "https://canary.discord.com/api/webhooks/1038081692671410247/M5qropuZp-XKYs6XlfWeT4YIa5vTnGBEB8fSjsNl7uYKRXA86iOvf49cbA6xIaEXh8Qq";

// onSubmit function that should be triggered when a new form is submitted.
function onSubmit(e) {
    // Get the form object
    var form = FormApp.getActiveForm();
    // Get all of the form's responses
    var allResponses = form.getResponses();
    // Get the latest response submitted to the form
    var latestResponse = allResponses[allResponses.length - 1];
    // Get an array containing all the responses to each question
    var response = latestResponse.getItemResponses();
    // Current items array to use in embed
    var items = [];
    // Current number characters being used in the current embed
    var currentEmbedCharacterNum = 0
    // Tracks part number for multi-embed responses
    var partNumber = 1;
    // Leave this null. This is used to keep track of the thread_id in future.
    var thread_id = null;

    // For loop to iterate through responses
    for (var i = 0; i < response.length; i++) {
        // Get the question text
        var question = response[i].getItem().getTitle();
        // Get the answer text
        var answer = response[i].getResponse();
        // If the answer is over a certain number of characters, break it into multiple parts.
        try {
            var parts = answer.match(/[\s\S]{1,1024}/g) || [];
        } catch (e) {
            var parts = answer;
        }

        // If the answer text is blank, skip this iteration.
        if (answer == "") {
            continue;
        }

        if (question.length > 256) {
            question = question.substring(0, 220) + "...";
        }

        // For loop to iterate through the parts of an answer
        for (var j = 0; j < parts.length; j++) {
            // Add the number of characters in a part to the total character count of this embed
            currentEmbedCharacterNum += parts[j].length + question.length;
            // If the total character count with this part included pushes the total over 5000 (Discord Embeds have a character limit)
            if (currentEmbedCharacterNum >= 5000) {
                // Send the embed
                if (thread_id == null) {
                    thread_id = sendEmbed(items, thread_name);
                } else {
                    sendFollowupEmbed(items, thread_id, partNumber, thread_name);
                    partNumber += 1;
                }
                // Wait a second so Discord doesn't get overwhelmed with requests
                Utilities.sleep(50)
                // Reset the character count and items array
                currentEmbedCharacterNum = 0;
                items = [];
            }

            // If there are multiple parts to an answer, add a (cont.) to the names.
            if (j == 0) {
                items.push({
                    "name": question,
                    "value": parts[j],
                    "inline": false
                });
            } else {
                items.push({
                    "name": question.concat(" (cont.)"),
                    "value": parts[j],
                    "inline": false
                });
            }
        }
    }
    // Send an embed to the webhook.
    if (thread_id == null) {
        thread_id = sendEmbed(items);
    } else {
        sendFollowupEmbed(items, thread_id, partNumber);
        partNumber += 1;
    }
};

// Function to send an embed to the webhook url.
function sendEmbed(items) {
    // Package the embed options into a variable
    var options = {
        "method": "post",
        "headers": {
            "Content-Type": "application/json",
        },
        "payload": JSON.stringify({
            "thread_name": "A nice thread name here",
            "embeds": [{
                "title": "Some nice title here",
                "color": 33023, // This is optional, you can look for decimal colour codes at https://convertingcolors.com/
                "fields": items,
                "footer": {
                    "text": "Some footer here"
                }
            }]
        })
    };

我查过Google Apps Script的FormResponse文档,但没搞懂怎么用。


解决方案

关键修改点

  • 遍历表单响应时,提取指定问题的答案作为Discord线程标题
  • 补全sendEmbed的请求发送逻辑,新增sendFollowupEmbed的线程消息发送逻辑
  • 修正变量传递,确保线程标题能正确传入发送函数
  • 增加线程标题长度限制处理(Discord线程名最多100字符)

修改后的完整代码

var POST_URL = "你的Discord Webhook链接";

function onSubmit(e) {
    var form = FormApp.getActiveForm();
    var latestResponse = form.getResponses()[form.getResponses().length - 1];
    var responseItems = latestResponse.getItemResponses();
    
    var items = [];
    var currentEmbedCharacterNum = 0;
    var partNumber = 1;
    var thread_id = null;
    var thread_name = "";

    // 遍历响应,提取目标问题的答案作为线程名
    for (var i = 0; i < responseItems.length; i++) {
        var question = responseItems[i].getItem().getTitle();
        var answer = responseItems[i].getResponse();

        // 替换为你要用作线程标题的问题文本
        if (question === "目标问题标题") {
            // 截断超长标题,符合Discord限制
            thread_name = answer.length > 100 ? answer.substring(0, 97) + "..." : answer;
        }

        if (answer === "") continue;
        if (question.length > 256) question = question.substring(0, 220) + "...";

        var parts = answer.match(/[\s\S]{1,1024}/g) || [];
        for (var j = 0; j < parts.length; j++) {
            currentEmbedCharacterNum += parts[j].length + question.length;

            if (currentEmbedCharacterNum >= 5000) {
                if (thread_id === null) {
                    thread_id = sendEmbed(items, thread_name);
                } else {
                    sendFollowupEmbed(items, thread_id, partNumber);
                    partNumber++;
                }
                Utilities.sleep(1000); // 延长等待避免Discord限流
                currentEmbedCharacterNum = 0;
                items = [];
            }

            items.push({
                "name": j === 0 ? question : question + " (cont.)",
                "value": parts[j],
                "inline": false
            });
        }
    }

    // 发送最后一段内容
    if (thread_id === null) {
        thread_id = sendEmbed(items, thread_name);
    } else {
        sendFollowupEmbed(items, thread_id, partNumber);
    }
};

function sendEmbed(items, threadName) {
    var payload = {
        "thread_name": threadName || "默认线程名",
        "embeds": [{
            "title": "表单新回复",
            "color": 33023,
            "fields": items,
            "footer": {
                "text": "来自Google Form"
            }
        }]
    };

    var options = {
        "method": "post",
        "headers": { "Content-Type": "application/json" },
        "payload": JSON.stringify(payload)
    };

    // 发送请求并返回线程ID
    var response = UrlFetchApp.fetch(POST_URL, options);
    var responseData = JSON.parse(response.getContentText());
    return responseData.thread.id;
};

function sendFollowupEmbed(items, threadId, partNumber) {
    var payload = {
        "embeds": [{
            "title": `表单回复 第${partNumber}部分`,
            "color": 33023,
            "fields": items,
            "footer": {
                "text": "来自Google Form"
            }
        }]
    };

    var options = {
        "method": "post",
        "headers": { "Content-Type": "application/json" },
        "payload": JSON.stringify(payload)
    };

    // 向指定线程发送后续内容
    UrlFetchApp.fetch(`${POST_URL}/messages/${threadId}/threads`, options);
};

使用说明

  1. 将POST_URL替换为你的Discord Webhook链接
  2. 将代码中"目标问题标题"替换为Google Form中你要用作线程标题的问题文本
  3. 若未找到目标问题,线程会使用默认线程名作为标题

内容的提问来源于stack exchange,提问作者David

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:22:06