Error creating Calendly webhook subscription with .Net HttpClient() - c#

I am trying to Create a webhook subscription with .net HttpClient() for Calendly
https://developer.calendly.com/docs/webhook-subscriptions
I am attempting to convert this Curl command to .Net
curl --header "X-TOKEN: <your_token>" --data "url=https://blah.foo/bar&events[]=invitee.created&events[]=invitee.canceled" https://calendly.com/api/v1/hooks
Here is my .Net code:
private static async Task<HttpResponseMessage> PostCreateWebhookSubscription()
{
var client = new HttpClient {BaseAddress = new Uri("https://calendly.com")};
var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/hooks/");
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("url",
"https://requestb.in/17ruxqh1&events[]=invitee.created&events[]=invitee.canceled")
};
request.Content = new FormUrlEncodedContent(keyValues);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded") {CharSet = "UTF-8"};
request.Content.Headers.Add("X-TOKEN", "<my_calendly_token>");
return await client.SendAsync(request);
}
I get this error 422 error, but unable to figure out what to change to make this work.
getting error Unprocessable Entity
{"type":"validation_error","message":"Validation failed","errors":{"events":["can't be blank"]}}
I am able to run the Curl command and it works fine from the same machine, so I know that is working.
I created a .net HttpClient call to test the basic Token, which worked fine.
Any suggestions?

Finally came back this which figured it out as soon as I looked at the code again.
Originally I was looking at the whole URL as one big string, but did not realize at first the & symbol which was separating the values to pass.
The bad code below:
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("url",
"https://requestb.in/17ruxqh1&events[]=invitee.created&events[]=invitee.canceled")
};
Should have been changed to this seperating each value from their documentation:
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("url","https://requestb.in/17ruxqh1"),
new KeyValuePair<string, string>("events[]","invitee.created"),
new KeyValuePair<string, string>("events[]","invitee.canceled")
};
So for those that want to use .Net to create webhook subscriptions with Calendly here is a full TestMethod code to try it out. Just replace the first parameter with your requestb.in or post url. Also put in your Calendly api key.
[TestMethod]
public void CreateCalendlyWebhookSubscription()
{
var task = PostCreateWebhookSubscription();
task.Wait();
var response = task.Result;
var body = response.Content.ReadAsStringAsync().Result;
}
private static async Task<HttpResponseMessage> PostCreateWebhookSubscription()
{
var client = new HttpClient {BaseAddress = new Uri("https://calendly.com")};
var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/hooks/");
var keyValues = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("url","https://requestb.in/17ruxqh1"),
new KeyValuePair<string, string>("events[]","invitee.created"),
new KeyValuePair<string, string>("events[]","invitee.canceled")
};
request.Content = new FormUrlEncodedContent(keyValues);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded") {CharSet = "UTF-8"};
request.Content.Headers.Add("X-TOKEN", "<your Calendly ApiKey>");
return await client.SendAsync(request);
}
Hope this helps somebody!

Related

Send form-data using HttpClient C#

I'm trying to make an API call to third party URL, which is working fine through postman, but same request through C# HttpClient not working.
This is how I'm sending request in postman
C# Sample Code
var nvc = new List<KeyValuePair<string, string>>();
nvc.Add(new KeyValuePair<string, string>("PARAM1", "PARAM1 Value"));
nvc.Add(new KeyValuePair<string, string>("PARAM2", "PARAM2 Value"));
nvc.Add(new KeyValuePair<string, string>("PARAM3", "PARAM3 Value"));
var req = new HttpRequestMessage(HttpMethod.Post, "Https://ThirdPartyURL") {
Content = new FormUrlEncodedContent(nvc)
};
Am I doing anything wrong here?
UPDATE #1:
**
Fiddler Traces for postman request(which is working fine)
Fiddler Traces for C# Request(which is failing)
Thanks in advance!
Regards,
Moksh
Instead of
var nvc = new List<KeyValuePair<string, string>>();
try to create a new class:
public class RecipientSender
{
public string Recipient_First_Name {get; set;}
public string Recipient_Last_Name {get; set;}
.....
}
and create httpclientrequest like this:
....
....
var recipientSender=new RecipientSender { Recipient_FirstName=..., }
var contentType = new MediaTypeWithQualityHeaderValue("application/json");
httpClient.DefaultRequestHeaders.Accept.Add(contentType);
var stringData = JsonConvert.SerializeObject(recipientSender);
contentData = new StringContent(stringData, Encoding.UTF8, "application/json");
var httpResponseMessage=client.PostAsync(url, contentData);
.....

Twilio REST Api call bad request

I've implemented Twilio REST API with C# successfully earlier. However, all of a sudden the API calls that are made keep getting 400 - BAD REQUEST.
The response body doesn't contain any specific error either...
I'll say it again, it worked for a week or two and all of sudden it returns BAD REQUEST.
The code is exact the following below.
public async Task SendSmsAsync(string number, string message)
{
var accountSid = _configuration["Authentication:Twilio:AccountSID"];
var authToken = _configuration["Authentication:Twilio:AuthToken"];
var twilioNumber = _configuration["Authentication:Twilio:Number"];
var credentials = new NetworkCredential(accountSid, authToken);
var handler = new HttpClientHandler { Credentials = credentials };
using (var client = new HttpClient(handler))
{
var url = $"https://api.twilio.com/2010-04-01/Accounts/{ accountSid }/Messages";
var body = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("To", number),
new KeyValuePair<string, string>("From", twilioNumber),
new KeyValuePair<string, string>("Body", message),
};
var content = new FormUrlEncodedContent(body);
content.Headers.ContentType.CharSet = "UTF-8";
var response = await client.PostAsync(url, content);
if (response.IsSuccessStatusCode)
{
//Uri success = response.Headers.Location;
}
}
}

Supplying api key in HttpClient's headers not working

I'm trying to get data from https://ndb.nal.usda.gov, basing on instructions provided here https://ndb.nal.usda.gov/ndb/doc/apilist/API-FOOD-REPORT.md
I'm using HttpClient as follows, but can't seem to be able to pass the api_key correctly. Shouldn't I be adding it to headers? I tried
public static async Task<string> DownloadItemData(string itemName)
{
using (HttpClient client = new HttpClient())
{
HttpContent requestContent =
new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("api_key", "myKey"),
new KeyValuePair<string, string>("ndbno", "01009"),
new KeyValuePair<string, string>("type", "f")
});
requestContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
HttpResponseMessage response = await client.PostAsync("http://api.nal.usda.gov/ndb/reports", requestContent);
using (StreamReader reader = new StreamReader(await response.Content.ReadAsStreamAsync()))
{
// Write the output.
string result = await reader.ReadToEndAsync();
return result;
}
}
But all I'm getting is:
{
"error": {
"code": "API_KEY_MISSING",
"message": "No api_key was supplied. Get one at http://api.nal.usda.gov"
}
}
I also tried this, but with the same result:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("api_key", "myKey");
Any ideas how to pass the api_key correctly? Thanks in advance!

API Post request C# URL

I got this url
http://www.stuff.com/ws/BIWS/service.php?key=sdf9&type=find&query=funktioner:orsearch(%224804255620%22)
I need a "post"-api request, with XML returned data.
I need to use a post because get is limited to ~2000 characters, and I need to send a lot of data in orsearch. What am I doing wrong, how can I debug this?
var clientt = new HttpClient();
clientt.BaseAddress = new Uri("http://www.stuff.com");
var request = new HttpRequestMessage(HttpMethod.Post, "/ws/BIWS/service.php?");
var keyValues = new List<KeyValuePair<string, string>>();
keyValues.Add(new KeyValuePair<string, string>("key", "sdf9"));
keyValues.Add(new KeyValuePair<string, string>("type", "find"));
keyValues.Add(new KeyValuePair<string, string>("query", "funktioner:orsearch('4804255620')"));
request.Content = new FormUrlEncodedContent(keyValues);
var response = await clientt.SendAsync(request);
string content = await response.Content.ReadAsStringAsync();
// Error wrong key entered or something, but url works fine

Post Method in Windows Phone 8

I need to send some parameters to a php server using post method in WP8 app and get response in json format. I've tried everything that I found on stackoverflow and other sites, still could not.
The last code piece I come up with is:
public static async void GetData(string url, string data)
{
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.PostAsync(new Uri(url), new StringContent(data));
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
MessageBox.Show(responseBody); // just showing the response for now
}
It shows a message from the server (which is an error stating some fields are missing) that it actually communicates with the server but the problem is with sending data. I call the above method like:
GetData("http_address_here", "?action=REGISTER&email=asc#fsdf.com&password=54561wefwe&firstname=sdfsdf&lastname=sdfsdf&picture=10");
But I saw an example sending data in xml. Possibly the mistake is about calling the method. Having seen tens of sample codes and trying everything, I really got confused about it. Any help is appreciated.
I finally managed to solve the problem. Thanks everyone for helping. The working code is below, it uses POST method and the resulting json object is stored as a string.
var values = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("email", "qewfwef"),
new KeyValuePair<string, string>("password", "qewfwef"),
new KeyValuePair<string, string>("firstname", "qewfwef"),
new KeyValuePair<string, string>("lastname", "qewfwef"),
new KeyValuePair<string, string>("picture", "123456")
};
var httpClient = new HttpClient(new HttpClientHandler());
HttpResponseMessage response = await httpClient.PostAsync(url, new FormUrlEncodedContent(values));
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
MessageBox.Show(responseString.ToString()); // just to see what we get
Can you try this
public static async Task<string> SendRequestPostResponse()
{
try
{
var postRequest = (HttpWebRequest)WebRequest.Create("your Url Here");
postRequest.ContentType = "application/x-www-form-urlencoded"; // Whichever content type you want to POST
postRequest.Method = "POST";
using (var requestStream = await postRequest.GetRequestStreamAsync())
{
byte[] postDataArray = Encoding.UTF8.GetBytes("your data here"); // Data for the POST request here
await requestStream.WriteAsync(postDataArray, 0, postDataArray.Length);
}
WebResponse postResponse = await postRequest.GetResponseAsync();
if (postResponse != null)
{
var postResponseStream = postResponse.GetResponseStream();
var postStreamReader = new StreamReader(postResponseStream);
string response = await postStreamReader.ReadToEndAsync();
return response;
}
return null;
}
}
HTTPWebRequest would be another alternative.

Categories