@yuka-mori

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

ExcelVBAからChatGPTを呼び出す際に出るエラーを解消したい

解決したいこと

ExcelVBAからChatGPTを呼び出す際に出るエラーを解消したい。

書籍を読みながら行っているのですが、その書籍ではWindows用の方法の記載しかなく、Macで行う方法を模索しております。
以下のエラーの解決方法を教えてください。

発生している問題・エラー

{
    "error": {
        "message": "You didn't provide an API key. You need to provide your API key in an Authorization header using Bearer auth (i.e. Authorization: Bearer YOUR_KEY), or as the password field (with blank username) if you're accessing the API from your browser and are prompted for a username and password. You can obtain an API key from https://platform.openai.com/account/api-keys.",
        "type": "invalid_request_error",
        "param": null,
        "code": null
    }

おそらく(i.e. Authorization: Bearer YOUR_KEY)を記載していないことが原因だと思われますが、書籍に載っているWindows用のコードをそのまま使ってしまうと「オブジェクトが必要です」とエラーが出てきてしまいます。

↓試したコード

Dim result As String
    result = HTTPGet("https://api.openai.com/v1/chat/completions", "")
    client.setRequestHeader "Authorization", "Bearer " & apikey
    Debug.Print result

*本番では自分のapikeyを入力しています。

該当するソースコード

わたしがMacで行っているコード

Dim result As String
    result = HTTPGet("https://api.openai.com/v1/chat/completions", "")
    Debug.Print result
    

書籍に載っているWindows用のコード

' APIの呼び出し
    Dim client As Object
    Set client = CreateObject("MSXML2.ServerXMLHTTP")
    client.setTimeouts 30000, 30000, 30000, 60000
    client.Open "POST", "https://api.openai.com/v1/chat/completions"
    client.setRequestHeader "Content-Type", "application/json"
    client.setRequestHeader "Authorization", "Bearer " & ApiKey
    client.send JsonConverter.ConvertToJson(data)
0 likes

1Answer

残念ながら、先ほどのHTTPGetでは、リクエストヘッダに情報(apikey、他)をセットすることができません。
以下に、リクエストヘッダに情報をセットすることができるHTTPGet2のコードを掲示するので、それで試してみてください。ただし、セットできるリクエストヘッダ情報は一つだけです。

Function HTTPGet2(sUrl As String, sRequestHeader As String) As String

    Dim sCmd As String
    Dim sResult As String
    Dim lExitCode As Long

    sCmd = "curl -X POST -H '" & sRequestHeader & "' " & sUrl
    sResult = execShell(sCmd, lExitCode)

    ' ToDo check lExitCode

    HTTPGet2 = sResult

End Function
使い方
Sub test2()
    Dim result As String
    Const apiKey = "xxxxxxxxxx"
    result = HTTPGet2("https://api.openai.com/v1/chat/completions", "Authorization: Bearer " & apiKey)
    Debug.Print result
End Sub
1Like

Comments

  1. @yuka-mori

    Questioner

    エラーが解消しました!ありがとうございます!
    なるほど、そのようなやり方があるんですね、、!
    私一人では本当に諦めていたと思います。ありがとうございます:cry:

    また違うエラーが発生し、もう1つヘッダ情報をセットしなくてはいけなくなったのですが、教えていただきたいです:bow_tone1:
    質問立てますね!

  2. なるほど、そのようなやり方があるんですね、、!

    内部でcurlコマンドを実行しているだけですから、curlコマンドの引数で指定できるものなら、何でもできます。

    もう1つヘッダ情報をセットしなくてはいけなくなった

    それは、Content-Type: application/jsonですか?

    そうであれば、固定値なので、引数ではなく直接書けばよいかと思います。

    sCmd = "curl -X POST -H 'Content-Type: application/json' -H '" & sRequestHeader & "' " & sUrl
    
  3. @yuka-mori

    Questioner

    ありがとうございます!!

    試してみたのですが、イミディエイトウィンドウに何も返ってきませんでした、、
    下記のページを参考にすると、Authorization: Bearerと同じような記述をされているのですが、何か代替案などないでしょうか:sob:
    https://qiita.com/uezo/items/6d9c7ede17bbdc9204e9

    私が今回書いたコードは以下です。

    Public Sub HelloChatGPT()
        Dim apikey As String
        apikey = "sk-----"
        
        Dim messages(0) As New Dictionary
        messages(0).Add "role", "user"
        messages(0).Add "content", " こんにちは、ChatGPT!"
    
        Dim data As New Dictionary
        data.Add "messages", messages
        data.Add "model", "gpt-3.5-turbo"
    End Sub
    
    
    Function HTTPGet2(sUrl As String, sRequestHeader As String) As String
    
        Dim sCmd As String
        Dim sResult As String
        Dim lExitCode As Long
    
    
        sCmd = "curl -X POST -H 'Content-Type: application/json' -H '" & sRequestHeader & "' " & sUrl
    
        sResult = execShell(sCmd, lExitCode)
    
        ' ToDo check lExitCode
    
        HTTPGet2 = sResult
    
    End Function
    
    Sub test2()
        Dim result As String
        Const apikey = "sk--------"
        result = HTTPGet2("https://api.openai.com/v1/chat/completions", "Authorization: Bearer  sk-----------")
    
        Debug.Print result
    End Sub
    
    
    
    
    
    
  4. @yuka-mori

    Questioner

    すみません以下のエラーが返ってきました!
    まだ自分でも調べられていないのですが、一応先に共有しておきます:bow_tone1:

    {
        "error": {
            "message": "We could not parse the JSON body of your request. (HINT: This likely means you aren't using your HTTP library correctly. The OpenAI API expects a JSON payload, but what was sent was not valid JSON. If you have trouble figuring out how to fix this, please contact us through our help center at help.openai.com.)",
            "type": "invalid_request_error",
            "param": null,
            "code": null
        }
    }
    
  5. Authorization: Bearerと同じような記述をされているのですが、

    Authorizationと同じ書き方をしていますよ。
    以前の回答に書きましたが、今回の環境はMacということで、@yuka-mori さんが探してきた方法が、「curlコマンドを使ってHTTPリクエストする」という方法です。

    curlコマンドの引数をよく見てください。

    • -H '" & sRequestHeader & "' "

    sRequestHeader"Authorization: Bearer sk-----------"ですから、文字列が置換されて、結果として、
    -H 'Authorization: Bearer sk-----------'になります。

    一方、先ほど追加した方は、

    -H 'Content-Type: application/json'

    ほらね、curlコマンドにおいては、同じ書き方です。

    すみません以下のエラーが返ってきました!

    ですよね

  6. すみません以下のエラーが返ってきました!
    まだ自分でも調べられていないのですが、一応先に共有しておきます:bow_tone1:

    そのエラーは、

    書籍に載っているWindows用のコード
     APIの呼び出し
        Dim client As Object
        Set client = CreateObject("MSXML2.ServerXMLHTTP")
        client.setTimeouts 30000, 30000, 30000, 60000
        client.Open "POST", "https://api.openai.com/v1/chat/completions"
        client.setRequestHeader "Content-Type", "application/json"
        client.setRequestHeader "Authorization", "Bearer " & ApiKey
        client.send JsonConverter.ConvertToJson(data)
    

    一番最後のclient.send JsonConverter.ConvertToJson(data)に相当するデータを渡していないから起きています。
    ここは、JSONです。今回はどんなJSONデータを渡したいのですか?

  7. @yuka-mori

    Questioner

    丁寧な解説ありがとうございます!
    curlコマンドの部分についてよく理解することができました!
    またJSONデータを渡せていないことによるエラーだということも理解できました。

    大変申し訳ないのですが、client.send JsonConverter.ConvertToJson(data)をどのように記述すれば良いかがわかりません。教えていただきたいです:sweat:
    また、渡すべきべきJSONデータというのはJsonconverterのファイルデータで合っていますでしょうか?
    image.png

Your answer might help someone💌