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

使用.VBS脚本发送Discord消息时触发语法错误求助

问题现象

计划编写VBS脚本实现多Discord账号快捷发消息功能(已知Discord自带多账号支持,本项目为个人挑战练习),在原有可正常运行的基础发送脚本上添加UI交互逻辑(面向法语用户设计,界面提示为法语)后,脚本启动报语法错误,错误指向原本可正常运行的消息发送函数。原始代码如下:

On Error Resume Next

'Token selector dialogue box
account=InputBox("Merci d'indiquer le nom du compte ci-dessous","Discord CMD","")

'If user cancels, exit the program
if IsEmpty(account) Then
    WScript.Quit
end if

'Check if token is registered
Const ForReading = 1
Dim File, content, FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
Function FileExists(FilePath)
    If fso.FileExists(FilePath) Then
        FileExists=CBool(1)
    Else
        FileExists=CBool(0)
    End If
End Function
If FileExists("database\accounts\"+account+".bin") Then
    'If the file exist, do nothing and continue the script
    WScript.Sleep(500)
Else
    'If the file doesn't exist, restart the script and display an error
    x=msgbox("This account has not be registered in the database. Please try again.", 0+16, "Error - Does not exist")
    CreateObject("WScript.Shell").Run "Chat.vbs"
    WScript.Quit
End If

'Get the token related the account asked
Set File = fso.OpenTextFile("database\accounts\"+account+".bin", ForReading)
Token = File.ReadAll


'Loop
Do
    'Choose channel
    Echannel=InputBox("Merci d'indiquer l'identifiant du channel ci-dessous. Si il est identique, inscrivez 'Channel'","Discord CMD - " + account,"Channel")
    If (Echannel="Channel") Then
        'If the channel is the same as before, then we don't change it in the code
        WScript.Sleep(500)
    Else
        'If the channel is different, we change to the new value
        channels = Echannel
    End If

    'If user cancels, restart the program
    if IsEmpty(account) Then
        CreateObject("WScript.Shell").Run "Chat.vbs"
        WScript.Quit
    end if


    'The user enters his message
    text=InputBox("Merci d'indiquer le texte ci-dessous, faites OK pour l'envoyer","Discord CMD - " + account + " - Writing...","")

    'If user cancels, restart the program
    if IsEmpty(account) Then
        CreateObject("WScript.Shell").Run "Chat.vbs"
        WScript.Quit
    end if

    'We send the message
    Call commandeexercuter(channels,Token,text)
    Function commandeexercuter(channels,Token,text)
        Set objXmlHttp = CreateObject("Msxml2.ServerXMLHTTP") 
        sRequest = "{" & Chr(34) & "content" & Chr(34) & ": " & Chr(34) & text & Chr(34) & "}"
        objXmlHttp.open "POST","https://discordapp.com/api/v6/channels/" & channels &"/messages", False 
        objXmlHttp.setRequestHeader "Authorization", Token
        objXmlHttp.setRequestHeader "Content-Type", "application/json"
        objXmlHttp.send(sRequest)
    End Function
'We restart the loop
Loop
错误原因
  • 核心语法错误:VBScript明确要求所有Function/Sub过程必须定义在代码顶层作用域,不能嵌套在Do...Loop循环、If...End If判断这类流程控制块内部。原始代码把commandeexercuter发送函数直接写在了Do...Loop循环体里,直接触发语法报错。
  • 逻辑缺陷1:两处用户取消输入的判断逻辑写错,均判断了account变量而非当前输入的Echannel(频道ID)、text(消息内容)变量,用户取消频道/消息输入时无法触发预期的重启逻辑。
  • 逻辑缺陷2:channels变量未做初始化,若用户首次运行直接保留频道输入框默认值Channel,会因变量未定义导致请求URL拼接失败。
  • 潜在运行bug:读取账号token文件后未关闭文件句柄,可能触发文件占用问题;发送消息时未转义消息内容里的双引号,若消息包含双引号会导致JSON格式错误,消息发送失败。
修复方案
  1. 将commandeexercuter消息发送函数移出循环块,放到所有流程控制结构外部的顶层作用域。
  2. 修正取消输入的判断逻辑,分别对Echannel、text变量做空值判断。
  3. 初始化channels变量,增加首次输入校验,避免空值发起无效请求。
  4. 补充文件句柄关闭逻辑、消息内双引号转义逻辑,增加空消息拦截避免发空内容。

修复后可正常运行的完整代码:

On Error Resume Next

'Token selector dialogue box
account=InputBox("Merci d'indiquer le nom du compte ci-dessous","Discord CMD","")

'If user cancels, exit the program
if IsEmpty(account) Then
    WScript.Quit
end if

'Check if token is registered
Const ForReading = 1
Dim File, content, FSO, channels
Set FSO = CreateObject("Scripting.FileSystemObject")
channels = "" '初始化频道变量
Function FileExists(FilePath)
    If fso.FileExists(FilePath) Then
        FileExists=CBool(1)
    Else
        FileExists=CBool(0)
    End If
End Function
If FileExists("database\accounts\"&account&".bin") Then
    WScript.Sleep(500)
Else
    x=msgbox("This account has not be registered in the database. Please try again.", 0+16, "Error - Does not exist")
    CreateObject("WScript.Shell").Run "Chat.vbs"
    WScript.Quit
End If

'Get the token related the account asked
Set File = fso.OpenTextFile("database\accounts\"&account&".bin", ForReading)
Token = File.ReadAll
File.Close '关闭文件句柄避免占用

'消息发送函数 放在顶层作用域
Function commandeexercuter(channels,Token,text)
    Set objXmlHttp = CreateObject("Msxml2.ServerXMLHTTP") 
    '转义消息内的双引号,避免JSON格式错误
    sRequest = "{" & Chr(34) & "content" & Chr(34) & ": " & Chr(34) & Replace(text, Chr(34), "\"&Chr(34)) & Chr(34) & "}"
    objXmlHttp.open "POST","https://discordapp.com/api/v6/channels/" & channels &"/messages", False 
    objXmlHttp.setRequestHeader "Authorization", Token
    objXmlHttp.setRequestHeader "Content-Type", "application/json"
    objXmlHttp.send(sRequest)
End Function

'主循环
Do
    'Choose channel
    Echannel=InputBox("Merci d'indiquer l'identifiant du channel ci-dessous. Si il est identique, inscrivez 'Channel'","Discord CMD - " & account,"Channel")
    '修正取消判断逻辑
    if IsEmpty(Echannel) Then
        CreateObject("WScript.Shell").Run "Chat.vbs"
        WScript.Quit
    end if

    If (Echannel<>"Channel") Then
        channels = Echannel
    End If

    '首次未输入频道ID时提示重输
    If channels = "" Then
        MsgBox "Veuillez d'abord saisir l'identifiant du channel", vbExclamation, "Erreur"
        Loop
    End If

    '获取用户输入的消息
    text=InputBox("Merci d'indiquer le texte ci-dessous, faites OK pour l'envoyer","Discord CMD - " & account & " - Writing...","")
    '修正取消判断逻辑
    if IsEmpty(text) Then
        CreateObject("WScript.Shell").Run "Chat.vbs"
        WScript.Quit
    end if

    '空消息不发送
    If Trim(text) <> "" Then
        Call commandeexercuter(channels,Token,text)
    End If
Loop

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 06:17:02