How do I send a post request to telegram API from C#? - c#

I have my telegram application with app's api_id and app's api_hash.
I used TLSharp library for implementing my own things. But now I need to use this https://core.telegram.org/method/auth.checkPhone telegram api method, but it's not implemented in TLSharp library!
I don't mind doing it all manually, but I don't know how!
I know how you send post requests in C#, example:
var response = await client.PostAsync("http://www.example.com/index", content);
but in this specific case I don't. Because I don't know:
1) what link should I use for sending post requests? I couldn't find it on the telegram's website.
2) what content should I pass there? Should it be just "(auth.checkPhone "+380666454343")" or maybe the whole "(auth.checkPhone "+380666454343")=(auth.checkedPhonephone_registered:(boolFalse)phone_invited:(boolFalse))" ?
So, How do I sent this post request to the telegram api? (NOT telegram bot api!)

Try to use System.Net.Http like in this example (auth request to the server):
var user = new { login = "your login", password = "your pass" };
string json = JsonConvert.SerializeObject(user);
HttpContent content = new StringContent(json, Encoding.UTF8, "application/json");
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage();
request.RequestUri = new Uri("server route link"); // can be like https://a100.technovik.ru:1000/api/auth/authenticate
request.Method = HttpMethod.Post;
request.Content = content;
HttpResponseMessage response = await client.SendAsync(request);
responseText.Text = await response.Content.ReadAsStringAsync();

I think based on a brief look, that it would be more along the lines of your second example, e.g.:
var phonenumber = "0123456789";
var content =
$#"(auth.checkPhone ""{phonenumber}"")"+
"=(auth.checkedPhone phone_registered: (boolFalse) phone_invited:(boolFalse))";
var result = DoHttpPost("http://some.example.com/api/etc", content);
(note: I've not listed the actual mechanics of an HTTP Request here, as that is covered in plenty of detail elsewhere - not least in the other current answer supplied to you; DoHttpPost() is not a real method and exists here only as a placeholder for this process)
And since the payload of this appears to indicate the exact function and parameters required, that you'd just send it to the base api endpoint you use for everything, but I can't say for sure...
I do note they do appear to have links to source code for various apps on the site though, so perhaps you'd be better off looking there?

Related

Moving emails/messages using Microsoft Graph SDK's Batch Requests

My objective is to process emails in a folder and then move them to another folder to which I have the id. To ease the workload I'm trying to make use of the batch functionality.
Unfortunately, every time I try to run the batch function I'm presented with an exception with the message Code: invalidRequest Message: Unable to deserialize content..
The code in question, simplified for just one request, can be found below.
var batch = new BatchRequestContent();
var json = JsonSerializer.Serialize( new { destinationId = Graph.Me.Messages[messageId].Move(folderId).Request().RequestBody.DestinationId } );
var jsonMessage = Graph.HttpProvider.Serializer.SerializeAsJsonContent(json);
var request = Graph.Me.Messages[messageId].Move(folderId).Request().GetHttpRequestMessage();
request.Method = HttpMethod.Post;
request.Content = jsonMessage;
batch.AddBatchRequestStep(request);
var res = await Graph.Batch.Request().PostAsync(batch);
I've narrowed down the problem to be about the request.Content because without that it will go through, though getting back with a 400 error about missing body.
Copying the string from batch.ReadAsStringAsync() and pasting that directly into the Graph Explorer and using that to run the query returns a 200 success.
Based on what I've tried I'm starting to lean on it being a limitation of the SDK's batch.
Any ideas?
While this wasn't the solution I was looking for, it works as a band aid solution.
Basically, after you add all your steps to the BatchRequestContent you use the ReadAsStringAsync() to get the body of the request. Then you use the library itself to send the HTTP Request, as instructed here.
HttpRequestMessage hrm = Graph.Batch.Request().GetHttpRequestMessage();
hrm.Method = HttpMethod.Post;
hrm.Content = Graph.HttpProvider.Serializer.SerializeAsJsonContent(await batch.ReadAsStringAsync());
// Authenticate (add access token) our HttpRequestMessage
await Graph.AuthenticationProvider.AuthenticateRequestAsync(hrm);
// Send the request and get the response.
HttpResponseMessage res = await Graph.HttpProvider.SendAsync(hrm);

C#: How to htttps get request with bearer token in header

Hello everyone my name is Taniguchi.
I've tried retrieving an entity from Dynamics 365 Finance and Operations and i did it on postman but now i having difficulties in asp.net core I was able to get the token but when i try to retrieve the entity the response gives me a html and this html leads me to the Dynamics 365 Finance and Operations Page.
My code:
`
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
const string environmentsUri = "https://trial-0z4qfj.sandbox.operations.dynamics.com/data/PartyContacts";
var response = httpClient.GetAsync(environmentsUri).Result;
var content = response.Content.ReadAsStringAsync().Result;
what am i doing wrong ? do i need to authenticate again ?
I suspect the Token you receive is not correct/complete.
I remember I faced the similar issue, I would request you to follow this blog post and try to receive Token as shown This shall help you solve your issue.
In addition I would recommend you use Organizaiton service with Webapi/Access Token. It will give you native library usage and you could query crm easily.
Try this blog for Orgservice
Seems like you are only using the parameter accessToken instead of the variable value. Depends on how you declared accessToken ofc. The rest seems fine.
Try:
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token.accessToken);

Sharepoint online API returns: HTTP Error 400. A request header field is too long

I have a loop that will loop through records in my DB, pulling information i need and then creating 3 folders & upload a file.
This works OK for like 40 records but then it starts erroring out with the below response back from sharepoint: <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\r\n<HTML><HEAD><TITLE>Bad Request</TITLE>\r\n<META HTTP-EQUIV=\"Content-Type\" Content=\"text/html; charset=us-ascii\"></HEAD>\r\n<BODY><h2>Bad Request - Header Field Too Long</h2>\r\n<hr><p>HTTP Error 400. A request header field is too long.</p>\r\n</BODY></HTML>
I am not sure whats going on, i read online its todo with cookies but i am using HTTPClient to send the request so i dont know how that would effect it? I also seen onlne about changing the kestrel?
Can anybody shed some light on this for me? Provide me with an easy but working solution? I dont use CSOM for integrating to sharepoint online, i use HTTP Requests, below is a sample of how i interact with sharepoint.
It seems as if i get blocked or banned temporarily cause if i wait a good bit, i can then make the same request that failed previously, and it will work! So strange.
Sample code (Used to create a resource at Sharepoint):
//Set Endpoint
var sharePointEndpoint = $"https://{hostname}/sites/{site}/_api/web/folders";
//Set default headers
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", sharePointToken); //Set token
client.DefaultRequestHeaders.Add("Accept", "application/json;odata=verbose");
//Pre-Body data setup
var metaData = new MetaDataModel();
metaData.type = "SP.Folder";
//Body data setup
var bodyModel = new ExpandoObject() as IDictionary<string, object>;
bodyModel.Add("__metadata", metaData);
bodyModel.Add("ServerRelativeUrl", location + "/" + directoryName + "/");
//Set content headers
HttpContent strContent = new StringContent(JsonConvert.SerializeObject(bodyModel));
strContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
strContent.Headers.ContentType.Parameters.Add(new NameValueHeaderValue("odata", "verbose"));
// Send request, grab response
var response = await client.PostAsync(sharePointEndpoint, strContent);
//Return response message
return response;
It turns out I needed to use Content-Length header when sending the request, once done I was able to successfully communicate with sharepoint without encountering this error.
More information here: https://social.technet.microsoft.com/Forums/en-US/26459f1c-945d-4112-9200-69c5a33a37ff/sharepoint-online-rest-api-returns-http-error-400-a-request-header-field-is-too-long?forum=sharepointdevelopment
Thanks.

GET call to a Google API responds with "Unauthorized"

UPDATE: Figured this out. I DID need to add the authorization header as answered below but I also believe the issue for my particular use case is that the access token (which I verified through Postman) required more scopes to authenticate me fully, which makes sense since this API contains surveys that I am trying to access, which are also linked to a Google account. Once I added the extra scopes needed to access the surveys to the token request along with the authorization header code below I was able to connect successfully.
More info on adding scopes to C# code can be found here: http://www.oauthforaspnet.com/providers/google/
Hope this helps anyone running into similar issues. Thanks all!
I am trying to make a GET call to a Google API but it keeps responding with "Unauthorized" while I am logged in to Gmail. I've already implemented Google+ Sign-In in StartUp.Auth.cs and even saved the access token for later use.
So how do I get the HttpClient to authorize me?
I have an access token available but I do not know how to pass it in properly. I've seen examples with usernames and passwords, but I should not need to pass those parameters if I already have an access token? If anything, I should be able to have the user redirected to a login page instead if needed when I log out before running the solution.
What I am expecting when the project is run, is the result of the GET call to come back in the form of json but it always says I'm "Unauthorized" and I am probably missing 1 line of code somewhere...
Here is the code I am using:
using (HttpClient client = new HttpClient())
{
string _url = "https://www.googleapis.com/consumersurveys/v2/surveys?key={MY_API_KEY}";
client.BaseAddress = new Uri(_url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (HttpResponseMessage response = client.GetAsync(_url).Result)
{
if (response.IsSuccessStatusCode)
{
using (HttpContent content = response.Content)
{
var Content = content.ReadAsStringAsync();
ViewBag.GoogleResponse = Content.ToString();
}
}
else
{
// THIS IS ALWAYS UNAUTHORIZED!
ViewBag.GoogleResponse = response.StatusCode + " - " + response.ReasonPhrase;
}
}
}
Please help with ideas or suggestions. Thanks!
You need to pass the auth token in an Authorization Header:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
Have you ever gotten an response for this api/survey? If you were unable to get a response from the API by hitting it with Postman, you may have issues in the way you are targeting the API. The error being returned there seems like you weren't including the token in your request header. Did you click the Authorization tab below the request URL to add the OAuth token to your header? (Keep in mind that the {} characters need to be URL encoded)
Also, when you are referencing MY_API_KEY, is that analagous to your surveyId?
I don't have a lot of experience here, but I have a couple of suggestions :
1) I agree with Pedro, you definitely need to include the Authorization Header in your request.
2) If your MY_API_KEY is in fact the survey ID, you may be providing an incorrect URL (GoogleAPIs documentation indicates that it should be < http://www.googleapis.com/consumer-surveys/v2/surveys/surveyId >
Recommendation (after moving your API key to a string var named MY_API_KEY) :
string _url = "https://www.googleapis.com/consumersurveys/v2/surveys/";
client.BaseAddress = new Uri(_url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ViewBag.GoogleAccessToken);
using (HttpResponseMessage response = client.GetAsync(MY_API_KEY).Result)
{
if (response.IsSuccessStatusCode)
{
using (HttpContent content = response.Content)
{
var Content = content.ReadAsStringAsync();
ViewBag.GoogleResponse = Content.ToString();
}
}
Reference:
https://developers.google.com/consumer-surveys/v2/reference/
http://www.asp.net/web-api/overview/advanced/calling-a-web-api-from-a-net-client

How to specify message body in a WebClient?

In the console, I follow up a call the site I'm on is is making and I can see the address (some.site.com/gettoken), message header and something that FF calls Message Body. It's in the latter that I can see the credentials that I've entered on the site that are being sent.
So, I've got the URL and the message body. Then, I've tried to implement the behavior using C# for my Azure service layer like so.
String url = #"https://some.site.com/gettoken";
String credentials = "username=super&password=secret";
using (WebClient client = new WebClient())
{
String output = client.UploadString(url, credentials);
result = output;
}
However, I get error 400 - bad result. What did I miss?
I've googled for some stuff but the only remotely relevant hits are talking about the upload methods, which I've used. Am I barking up the wrong tree entirely or just missing something tiny? Some people seem to get it to work but they're not tokenizing around. And I'm not certain enough to determine whether it's of relevance or not.
So, as a summary of what has been discussed in the comments: you can use the more modern HttpClient instead.
Note that this is the System.Net.Http.HttpClient and not Windows.Web.Http.HttpClient.
An example implementation could look like this:
public async Task<string> SendCredentials()
{
string url = #"https://some.site.com/gettoken";
string credentials = "username=super&password=secret";
using(var client = new HttpClient())
{
var response = await client.PostAsync(url, new StringContent(credentials));
return await response.Content.ReadAsStringAsync();
}
}
You might also be interested in System.Net.Http.FormUrlEncodedContent which allows you to pass in the parameters and their values so you don't have to construct the credentials value yourself.
More information on async/await.

Categories

Resources