Discord bot C# coding. Too few/too many parameters - c#

I am trying to build a discord bot that fetches IMDb info for movies and series. I have the API and everything set up.
I have managed to get a console response when I use the command !SearchMovie Harry Potter, however it gives me the 'too few parameters' argument if i do !SearchMovie Jaws, or !SearchMovie Twilight. If i remove the (string content) from public async Task SearchMovie, then i get the 'too many parameters' error.
I would also like the bot to post the response body in the discord channel, however i get the 'Message content is too long. Must be equal to or less than 2000 (parameter content)' error. Please, if anyone has any ideas on how to fix this, please help.
This is my code:
[Command("SearchMovie")]
public async Task SearchMovie(string text, string content)
{
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("https://imdb8.p.rapidapi.com/auto-complete?q=%3CREQUIRED%3E"),
Headers =
{
{ "X-RapidAPI-Key", "API-KEY" },
{ "X-RapidAPI-Host", "imdb8.p.rapidapi.com" },
},
};
using (var response = await client.SendAsync(request))
{
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
Console.WriteLine(body);
await ReplyAsync(body);
}

Related

Sending a Post Request to register a new user to a Web API, but receiving 400 : BadRequest

Having issues with my code [ Throwing an Unhandled exception: System.Net.Http.HttpRequestException: Response status code does not indicate success: 400 (Bad Request) ] when trying to connect to WebApi
This is my first time working with await/async methods, but I am needing to return
string msgTask = await response.Content.ReadAsStringAsync(); return msgTask;
At first my Console.WriteLine(await response.Content.ReadAsStringAsync(); returned:
BadRequest {"error":"Password must be at least 8 characters, with at least 1 of each alpha, number and special characters"}
But then I inserted this check: response.EnsureSuccessStatusCode(); which Throws the System.Net.Http.HttpRequestException
Full [top-level styled] Code Below (I am only using Console.WriteLine() to help with debugging, final code will only have return msgTask;) :
HttpRequest.GetHttpResponse();
await WattTime.PostRequest.RegisterUser();
public class HttpRequest
{
public static HttpClient client = new();
public static void GetHttpResponse()
{
// GetRequestMethod to use later
}
}
namespace WattTime
{
class PostRequest : HttpRequest
{
public static async Task<string> RegisterUser()
{
string Url = "https://api2.watttime.org/v2/register";
Dictionary<string, string> parameters = new()
{
{"username", "TestUser" },
{"password", "Password#1" },
{"email", "testuser#yahoo.com" },
{"org", "XYZ" },
};
var jsonDictionary = JsonConvert.SerializeObject(parameters);
var content = new StringContent(jsonDictionary, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync(Url, content);
response.EnsureSuccessStatusCode();
string msgTask = await response.Content.ReadAsStringAsync();
Console.WriteLine(msgTask);
return msgTask;
}
}
}
UPDATE I changed the format of data being sent to the API var data = #"{ ""username"": ""TestUser900"", ""password"": ""Summer$21"", ""email"": ""test65349#yahoo.com""}";
and added var postData = JsonConvert.SerializeObject(data); var postData2 = JsonConvert.DeserializeObject(postData);
If I use Console.WriteLine(await response.Content.ReadAsStringAsync()) I receive the Status and User Created, but if I use return response.StatusCode.ToString(); nothing returns
Looks like you need to change your test data. I tried to run your data in Online API testing tool and it returned the same error and later when I changed the json data it returned status 200 OK. Also I observed that every time you need to send unique data or its returning error.
Your issue may be the # symbol in your data. If sent in the URL it will need to be URL encoded. See this list of characters that need encoding https://www.w3schools.com/tags/ref_urlencode.asp
You can use HttpUtility.UrlEncode to do this on your jsonDictionary variable, HttpServerUtility and WebUtility classes also have this static method.
Change this response.EnsureSuccessStatusCode(); to this
if(response.IsSuccessStatusCode){
//Code here
}

Add a member to Microsoft Teams using Graph API and delegated permissions

I am trying to simply add a member (who is already in the organization) to a specific Microsoft Team. The observerID is the id of the the member that I want to add and teamID is is the ID of the specific Team. I am using delegated permission with TeamMembers.ReadWrite.All enabled.
My code looks like this:
string json = $#"
{{
""#odata.type"": ""#microsoft.graph.aadUserConversationMember"",
""roles"": [""member""],
""user#odata.bind"": ""https://graph.microsoft.com/beta/users({observerID})""
}}";
var body = new StringContent(json, Encoding.UTF8, "application/json");
Console.WriteLine("Add observer");
return await protectedApiCallHelper.CallWebApiAsync(WebApiUrlTeams + teamID + "/members", accessToken, body);
public async Task<JObject> CallWebApiAsync(string webApiUrl, string accessToken, HttpContent content)
{
if (!string.IsNullOrEmpty(accessToken))
{
var defaultRequestHeaders = HttpClient.DefaultRequestHeaders;
if (defaultRequestHeaders.Accept == null || !defaultRequestHeaders.Accept.Any(m => m.MediaType == "application/json"))
{
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
defaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", accessToken);
HttpResponseMessage response = await HttpClient.PostAsync(webApiUrl, content);
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
JObject result = JsonConvert.DeserializeObject(json) as JObject;
return result;
}
}
return null;
}
My problem is that the http call fails with the status code 400; 'Bad Request'. I have tried again and again to find any issues with my call but I can't seem to find the problem. When I Console.WriteLine the json I use for the body it looks like this:
{
"odata.type": "#microsoft.graph.aadUserConversationMember",
"roles": ["member"],
"user#odata.bind": "https://graph.microsoft.com/beta/users(d52c2663-1c41-401b-8015-1216f0e68960)"
}
And the url looks like: "https://graph.microsoft.com/beta/teams/a9f9ac33-fba5-4ce2-9515-8c498c70af85/members" and when I try the call through Postman it still returns a error code 400.
Does anyone have any insight on what might be wrong?
In fact, this error is very simple. Reporting 400 is usually a parameter error. Your json file is missing the special symbols # and ". I tested it locally and worked for me.

Why do I get "invalid_form_data" error when trying to post to Slack-API?

When I use this method:
public async Task<HttpResponseMessage> UploadFileAsync(MultipartFormDataContent requestContent)
{
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, UriMethod);
request.Content = requestContent;
var response = await _httpClient.SendAsync(request);
return response;
}
I allways get the answer:
{"ok":false,"error":"invalid_form_data"}
so I tried to explicitly tell it the 'mediaType', I tried "application/json" and others, but with all of them I get the same error. Here is the full Main-method that calls the upper method:
namespace TestArea
{
class MainArea
{
public static void Main( string[] args)
{
try
{
Task.WaitAll(SendMessage());
}
catch(Exception ex)
{
Console.WriteLine(ex);
Console.ReadKey();
}
}
private static async Task SendMessage()
{
var client = new BpsHttpClient("https://slack.com/api/chat.postMessage");
JsonObject JO = new JsonObject();
JO.channel = "DCW21NBHD";
JO.text = "This is so much fun :D !";
var Json = JsonConvert.SerializeObject(JO, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var StringJson = new StringContent(Json, Encoding.UTF8, "application/json");
var requestContent = new MultipartFormDataContent();
requestContent.Add(StringJson);
var Response = await client.UploadFileAsync(requestContent);
string AnswerContent = await Response.Content.ReadAsStringAsync();
}
When I use this method:
public async Task<HttpResponseMessage> SendMessageAsync(FormUrlEncodedContent content)
{
var response = await _httpClient.PostAsync(UriMethod, content);
return response;
}
so basically I am passing "FormUrlEncodedContent" instead of "MultipartFormDataContent" in this, and then I get the response I want and can work wiht it. BUT this is of little use to me since I have to use "MultipartFormDataContent" to be able to send files with my requests.
Anyone have an idea what is failing here? Why does it not like the one content-type but the other one? I'd be gratefull for tipps and ideas!
You get the error "invalid_form_data", because the API method chat.postMessage does not support requests with multipart/form-data.
As you can see from the documentation under "Accepted content types" this method only accepts: application/x-www-form-urlencoded, application/json
Note that you can not upload files to chat.postMessage.
If you want to upload files, please use the API method files.upload, which also supports multipart/form-data.
See also my answer here for how to upload files with a comment.

Bot Framework Direct Line Only Works in Debugger

I have a BOT that uses QnA Maker and LUIS to answer FAQ and requests and I am trying to implement a Direct Line to another BOT. Basically whenever my BOT does not know the answer it sends the user message to the other BOT to check if it knows the answer and outputs the result. The Direct Line works fine when I step through the code with Debugger (the GET request responds with the message I sent and the reply from the BOT). However, when I just run the code normally the response only contains the message I sent and not the reply from the other BOT. I'm thinking that the GET request is just ending too fast for the BOT to respond when the code is run outside the debugger and I have no idea on how to fix or extend the request. Any ideas?
Here's the relevant code:
public class EdwardComponent
{
public static async Task<string> TalkToEdward(string userInput, string conversationID, string streamURL)
{
var DirectLineURL = ConfigurationManager.AppSettings["DirectLineURL"];
var BearerToken = ConfigurationManager.AppSettings["BearerToken"];
var DirectLineURLConversationID = ConfigurationManager.AppSettings["DirectLineURLConversationID"];
DirectLineURLConversationID = DirectLineURLConversationID.Replace("abc123", conversationID);
var postclient = new RestClient(DirectLineURLConversationID);
var postrequest = new RestRequest(Method.POST);
postrequest.AddHeader("Authorization", BearerToken);
postrequest.AddHeader("Content-Type", "application/json");
postrequest.RequestFormat = DataFormat.Json;
var idv = new { id = "user1" };
postrequest.AddBody(new { type = "message", from = idv, text = userInput });
var cancellationTokenSource = new CancellationTokenSource();
var postresponse = postclient.ExecuteAsPost(postrequest, "POST");
var getrequest = new RestRequest(Method.GET);
getrequest.AddHeader("Authorization", BearerToken);
var getresponse = await postclient.ExecuteGetTaskAsync(getrequest);
string content = getresponse.Content.ToString();
return content;
}
}
}
Here is the correct serialized response from debugging:
Activity 0 is the message sent, Activity 1 is the response from BOT
Here is the response when ran outside debugger:
Only Activity 0 returned
Fixed it by using a small delay and a loop that will continue making the GET request until the Bot responds.

Can't get Microsoft.ProjectOxford.Vision or REST method working in PCL

This should be pretty straightforward, but I can't get it to work. I'm using these instructions. I've tried using the Nuget package in my PCL targeting 259 as as well as in another PCL targeting 7. Both PCLs never return after these lines. I've tried both.
//text = await client.RecognizeTextAsync(imageURL);
text = await client.RecognizeTextAsync(imageURL, languageCode: "en", detectOrientation: true);
Here is the REST code I've also tried. This works with my HTTP Helper.
public static async Task<OcrResults> PostReceiptAsync(string imageURL)
{
try
{
var apiKey = "KEY 1";
var content = await HttpHelper.Request(null, String.Format("https://eastus2.api.cognitive.microsoft.com/vision/v1.0?language=en&detectOrientation=true&subscription-key={0}&url={1}", apiKey, imageURL), null, HttpRequestType.POST);
return Mapper<OcrResults>.MapFromJson(await content.ReadAsStringAsync());
}
catch (Exception e)
{
throw;
}
}
In both methods, I'm trying to use a Blob image URL. Here is my calling method.
takePhoto.Clicked += async (sender, args) =>
{
}
It's almost seems like a deadlock issue.
Any help is much appreciated. Thanks!
UPDATE: I finally got the REST method to work with Android and UWP using this bit of code, but it fails in my iOS app. The main problem I had is that the URL that you copy out of Azure does not include the ocr? parameter. The Json Mapper is something that my SDK uses. OcrResults comes from the Project Oxford Nuget package.
public static async Task<OcrResults> ProcessReceiptAsync(string imageUrl)
{
// Instantiate a HTTP Client
var client = new HttpClient();
var apiKey = "KEY 1";
// Request parameters and URI
string requestParameters = "language=en&detectOrientation =true";
string uri = "https://eastus2.api.cognitive.microsoft.com/vision/v1.0/ocr?" + requestParameters;
// Pass subscription key thru the HTTP Request Header
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
// Format Request body
byte[] byteData = Encoding.UTF8.GetBytes($"{{\"url\": \"{imageUrl}\"}}");
using (var content = new ByteArrayContent(byteData))
{
// Specify Request body Content-Type
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
// Send Post Request
HttpResponseMessage response = await client.PostAsync(uri, content);
// Read Response body into the model
//return await response.Content.ReadAsStringAsync(OcrResults);
var result = Mapper<OcrResults>.MapFromJson(await response.Content.ReadAsStringAsync());
return result;
}
}
UPDATE 2: This method also works on Android and UWP, but fails with a BadRequest in my iOS app. I wanted to change up how the image URL gets encoded.
public static async Task<OcrResults> ProcessReceiptAsync2(string imageUrl)
{
// Instantiate a HTTP Client
var client = new HttpClient();
var apiKey = "KEY 1";
// Request parameters and URI
string requestParameters = "language=en&detectOrientation =true";
string uri = "https://eastus2.api.cognitive.microsoft.com/vision/v1.0/ocr?" + requestParameters;
// Pass subscription key thru the HTTP Request Header
client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", apiKey);
// Format Request body
var dict = new Dictionary<string, string>();
dict.Add("url", imageUrl);
//var param = JsonConvert.SerializeObject($"{{\"url\": \"{imageUrl}\"}}");
var param = JsonConvert.SerializeObject(dict);
HttpContent contentPost = new StringContent(param, Encoding.UTF8, "application/json");
// Specify Request body Content-Type
//contentPost.Headers.ContentType = new MediaTypeHeaderValue("application/json");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// Send Post Request
HttpResponseMessage response = await client.PostAsync(uri, contentPost);
// Read Response body into the model
//return await response.Content.ReadAsStringAsync(OcrResults);
var result = Mapper<OcrResults>.MapFromJson(await response.Content.ReadAsStringAsync());
return result;
}
UPDATE 3: I tried this code, but it failed with a Bad Request on iOS. I'm using the ExtractTextFromImageUrlAsync. I did get a "file too large" error using the ExtractTextFromImageStreamAsync, so that method appears to have worked.
https://github.com/HoussemDellai/Microsoft-Cognitive-Services-API/blob/master/ComputerVisionApplication/ComputerVisionApplication/Services/ComputerVisionService.cs
UPDATE 4: I removed Microsoft.Net.Http 2.9 from all the Projects and commented out System.Net.Http from all the app.config files. Both methods now work in the Android and UWP app. I still can't get the iOS app to work. The Project Oxford Nuget fails at this line requestObject.url = imageUrl; (see GitHub). The Rest method fails with a Bad Request, but I managed to catch a "InvalidImageUrl" message, so something is happening when the imageUrl is encoded. At this stage, I believe this is a Xamarin issue that's specific to iOS 10.4.0.

Categories

Resources