Adriaan
Adriaan

Reputation: 806

Indy Post to discord webhook gives bad request 400

I'm trying to send a message to a Discord channel using a Discord webhook. The only thing is that I keep getting a 400 Bad Request error.

I have the following code:

procedure TForm1.btn1Click(Sender: TObject);
var
  params: TStringList;
begin
  httpclient1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36';
  httpclient1.Request.ContentType := 'multipart/form-data';
  params := TStringList.Create;
  try
    params.add('{"content": "Test", "username": "testname", "avatar_url": "https://i.imgur.com/ivUiaOr.png"}');
  finally
    httpclient1.Post('https://discordapp.com/api/webhooks/443763508073594880/r8Oba0ws7WeN-n57TeF6BF6CKFFjviov6XMrMVVDUY_G18zmmY7VUwZqCiAOs9nz-CyC', params);
    params.Free;
  end;
end;

I have no idea what I'm doing wrong.

Upvotes: 1

Views: 1778

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 597570

You are not posting your data using the correct TIdHTTP.Post() method.

You are using the overloaded Post() method that takes a TStrings as input. That method is intended for sending HTML webforms in application/x-www-webform-urlencoded format. But you are setting the Request.ContentType property to 'multipart/form-data', so you are sending a malformed request.

To send data in multipart/form-data format, you need to use the overloaded Post() method that takes a TIdMultipartFormDataStream as input, eg:

procedure TForm1.btn1Click(Sender: TObject);
var
  params: TIdMultipartFormDataStream;
begin
  params := TIdMultipartFormDataStream.Create;
  try
    params.AddFormField('content', 'Test');
    params.AddFormField('username', 'testname');
    params.AddFormField('avatar_url', 'https://i.imgur.com/ivUiaOr.png');

    httpclient1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36';
    httpclient1.Post('https://discordapp.com/api/webhooks/443763508073594880/r8Oba0ws7WeN-n57TeF6BF6CKFFjviov6XMrMVVDUY_G18zmmY7VUwZqCiAOs9nz-CyC', params);
  finally
    params.Free;
  end;
end;

If you are not uploading an actual file (which you would do using the TIdMultipartFormDataStream.AddFile() method), then you can post your text fields in 'application/json' format using a TStream (not a TStringList), eg:

procedure TForm1.btn1Click(Sender: TObject);
var
  params: TStringStream;
begin
  params := TStringStream.Create('{"content": "Test", "username": "testname", "avatar_url": "https://i.imgur.com/ivUiaOr.png"}', TEncoding.UTF8);
  try
    httpclient1.Request.ContentType := 'application/json';
    httpclient1.Request.UserAgent := 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36';
    httpclient1.Post('https://discordapp.com/api/webhooks/443763508073594880/r8Oba0ws7WeN-n57TeF6BF6CKFFjviov6XMrMVVDUY_G18zmmY7VUwZqCiAOs9nz-CyC', params);
  finally
    params.Free;
  end;
end;

Upvotes: 2

Related Questions