Hello. I tried to send a http request to openai whisper-1 with VBA to transcript a speech but did not work. i do provide a model parameter but it returns following error. { “error”: { “message”: “you must provide a model parameter”, “type”: “invalid_request_error”, “param”: null, “code”: null } }
My code is as follows;
Public Function CreateTranscription(ByVal filePath As String, _
Optional MODEL As String = "whisper-1", _
Optional ByVal response_format As String, _
Optional ByVal language As String, _
Optional ByVal inputText As String, _
Optional ByVal temperature As Single = 0.0 _
) As Dictionary
Dim tempStream As ADODB.Stream
Set tempStream = New ADODB.Stream
tempStream.Type = adTypeText
tempStream.Charset = "UTF-8"
tempStream.Open
Call SetParameter(tempStream, "model", MODEL, BOUNDARY1)
Call SetBinary(tempStream, "file", filePath, BOUNDARY1)
If response_format <> "" Then
Call SetParameter(tempStream, "response_format", response_format, BOUNDARY1)
End If
If language <> "" Then
Call SetParameter(tempStream, "language", language, BOUNDARY1)
End If
If inputText <> "" Then
Call SetParameter(tempStream, "prompt", inputText, BOUNDARY1)
End If
If temperature >= 0 Then
Call SetParameter(tempStream, "temperature", temperature, BOUNDARY1)
End If
Call SetFooter(tempStream, BOUNDARY1)
Dim client As New MSXML2.ServerXMLHTTP60
client.setTimeouts 30000, 30000, 30000, RESPONSE_TIMEOUT_SEC * 1000
client.Open "POST", "https://api.openai.com/v1/audio/transcriptions", True
client.setRequestHeader "Content-Type", "multipart/form-data; boundary=" & BOUNDARY1
client.setRequestHeader "Authorization", "Bearer " & OPENAI_KEY
tempStream.Position = 0
client.send tempStream
client.waitForResponse RESPONSE_TIMEOUT_SEC
Select Case client.Status
Case Is >= 500
Debug.Print client.responseText
Err.Raise BASE_ERROR_NUMBER + client.Status, _
Description:="Saver Error" & vbCrLf & _
client.responseText
Case 400
Debug.Print BASE_ERROR_NUMBER + client.Status & vbCrLf & client.responseText
Err.Raise BASE_ERROR_NUMBER + client.Status, _
Description:="Client Error" & vbCrLf & _
client.responseText
Case 401
Debug.Print client.responseText
Err.Raise BASE_ERROR_NUMBER + client.Status, _
Description:="Invalid API KEY" & vbCrLf & _
client.responseText
Case Is > 400
Debug.Print client.responseText
Err.Raise BASE_ERROR_NUMBER + client.Status, _
Description:="Other Call Error" & vbCrLf & _
client.responseText
End Select
Dim response As Dictionary
Set CreateTranscription = JsonConverter.ParseJson(client.responseText)
tempStream.Close
Set tempStream = Nothing
End Function
Private Sub SetParameter(ByRef tempStream As Object, ByVal key As String, ByVal val As String, ByVal bndry As String)
If tempStream.Type <> adTypeText Then
Dim p As Long
p = tempStream.Position
tempStream.Type = adTypeText
tempStream.Charset = "UTF-8"
tempStream.Position = p
End If
Dim param As String
param = ""
param = param & "--" & bndry & vbCrLf
param = param & "Content-Disposition: form-data; name=""" & key & """" & vbCrLf
param = param & vbCrLf
param = param & val & vbCrLf
tempStream.WriteText param
End Sub
Private Sub SetBinary(ByRef tempStream As Object, ByVal paramName As String, ByVal filePath As String, ByVal bndry As String)
If tempStream.Type <> adTypeText Then
Dim p As Long
p = tempStream.Position
tempStream.Position = 0
tempStream.Type = adTypeText
tempStream.Charset = "UTF-8"
tempStream.Position = p
End If
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
Dim fileName As String
fileName = fso.GetFileName(filePath)
Set fso = Nothing
Dim param As String
param = ""
param = param & "--" & bndry & vbCrLf
param = param & "Content-Disposition: form-data; name=""" & paramName & """; filename=""" & fileName & """" & vbCrLf
' param = param & "Content-Disposition: form-data; name=""" & paramName & """; filename=""" & filePath & """" & vbCrLf
' param = param & "Content-Type: application/octet-stream" & vbCrLf
param = param & "Content-Type: audio/mpeg" & vbCrLf
param = param & vbCrLf
tempStream.WriteText param
' Switch stream to binary type for writing the file content '
If tempStream.Type <> adTypeBinary Then
Debug.Print "adTypeBinary"
p = tempStream.Position
tempStream.Position = 0
tempStream.Type = adTypeBinary
tempStream.Position = p
End If
' Load the file content into the stream '
Dim fileStream As Object
Set fileStream = CreateObject("ADODB.Stream")
fileStream.Type = adTypeBinary
fileStream.Open
fileStream.LoadFromFile filePath
tempStream.Write fileStream.Read
fileStream.Close
Set fileStream = Nothing
' Switch back to text type for further text additions '
If tempStream.Type <> adTypeText Then
p = tempStream.Position
tempStream.Position = 0
tempStream.Type = adTypeText
tempStream.Charset = "UTF-8"
tempStream.Position = p
End If
tempStream.WriteText vbCrLf
End Sub
Private Sub SetFooter(ByRef tempStream As Object, ByVal bndry As String)
If tempStream.Type <> adTypeText Then
Dim p As Long
p = tempStream.Position
tempStream.Position = 0
tempStream.Type = adTypeText
tempStream.Charset = "UTF-8"
tempStream.Position = p
End If
tempStream.WriteText "--" & bndry & "--" & vbCrLf
End Sub
I tried with a real api key, not “OPENAI_KEY”. The string “BOUNDARY1” is correctly set to “----boundary”.
Here is printed http request body.
----boundary
Content-Disposition: form-data; name=“model”
whisper-1
----boundary
Content-Disposition: form-data; name=“file”; filename=“speech.mp3”
Content-Type: audio/mpeg
(bianary data of speech.mp3)
----boundary–
What am I missing? Any suggestions would be great help for me.
thank you!