Google Cloud Text-to-Speech 401 Unauthorized using C# HttpClient AuthenticationHeaderValue Bearer with API key - c#

As far as I'm aware, Google Cloud has been configured properly. I've tried both API Key and Service Account key but keep getting 401 Unauthorized when using curl to connect. Results in 401 Unauthorized. I am not using Google library because I do not have access to it for this small application I am trying to build.
public async Task GenerateResponse(Input input, Voice voice, AudioConfig audioConfig, string outputFile)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "MyAPIKey");
var request = new { input = input, voice=voice, audioConfig=audioConfig };
var jsonRequest = JsonConvert.SerializeObject(request);
var content = new StringContent(jsonRequest, Encoding.UTF8, "application/json");
using (var response = await client.PostAsync("https://texttospeech.googleapis.com/v1/text:synthesize", content))
{
response.EnsureSuccessStatusCode();
using (var audioStream = await response.Content.ReadAsStreamAsync())
{
using (var outputStream = File.Create(outputFile))
{
await audioStream.CopyToAsync(outputStream);
}
}
}
}
}

Related

How can I make a discord timeout command with discord.net C#

Im trying to make a Discord C# Command That uses Discords new Timeout function using discord.NET
I tried using HTTP Requests instead cause i couldnt find a discord.NET function but It returns an unauthorized error
public static async Task PatchData(string url, string data, string token)
{
// Create a new HttpClient instance
using var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Authorization",token);
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent(data, Encoding.UTF8, "application/json");
var response = await httpClient.PatchAsync(url, content);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Data patched successfully!");
}
else
{
Console.WriteLine(response.StatusCode);
}
}
and for the execution
await Patch.PatchData($"https://discord.com/api/v9/guilds/{Context.Guild.Id}/members/{user.Id}",
"{\"communication_disabled_until\": "
+ current_time + time_in_minutes + "}",botToken);

C# -- Login with Amazon oauth2 -- error when doing POST-request

I am trying to make a POST request to the amazon api to get a token for login with amazon. I am doing this with Xamarin.
What I want is the response from amazon with the token. I tried it according to this tutorial:
Code-Based Linking (CBL) for Amazon Alexa Devices
When using Postman it works fine, I get the right response. When I try to implement this in my Xamarin project I always get the error:
"error_description":"The Content-type is not supported by the authorization server.", "error":"invalid_request"
Here's my code:
client = new HttpClient();
client.BaseAddress = new Uri("https://api.amazon.com/auth/O2/create/codepair");
string contentRaw = "response_type=device_code&client_id=hereIsTheClient_ID&scope=alexa:all";
var content = new StringContent(contentRaw, Encoding.UTF8, "application/x-www-form-urlencoded");
string uriEncoded = Uri.EscapeDataString(contentRaw);
HttpResponseMessage response = await client.PostAsync("https://api.amazon.com/auth/O2/create/codepair", content);
var result = await response.Content.ReadAsStringAsync();
return result;
Here's what I did using JSON, but I still get the "Content-Type is not supported by the authorization server"
O2authRequest o2AuthRequest = new O2authRequest();
o2AuthRequest.response_type = "device_code";
o2AuthRequest.client_id = "amzn1.application-oa2-client....";
o2AuthRequest.scope = "alexa:all";
o2AuthRequest.scope_data = new Scope_Data();
o2AuthRequest.scope_data.productID = "MyAppID";
o2AuthRequest.scope_data.productInstanceAttributes = new Productinstanceattributes();
o2AuthRequest.scope_data.productInstanceAttributes.deviceSerialNumber = "12345";
string contentRaw = JsonConvert.SerializeObject(o2AuthRequest);
var content = new StringContent(contentRaw, Encoding.UTF8, "application/json");
string uriEncoded = Uri.EscapeDataString(contentRaw);
HttpResponseMessage response = await client.PostAsync("https://api.amazon.com/auth/O2/create/codepair", content);
var result = await response.Content.ReadAsStringAsync();

How to call API using MultiPartFormDataContetnt and get a response in C#

I Have an API that takes an IFormFile and returns an IActionsresult with some values. When i call the API with postman it works fine I get a nice 200 Ok response with the data I am looking for. But when I trie to call the API from within another program I get nothing in response. I get no errors, it's just that the program seems to wait for a response that never shows. I am simply wondering if anyone can see the problem with this code any help would be greately apriciated.
Both my API and my program is on the same computer and here is the code i use to call the API.
public static async Task<string> Calculate()
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var content = new MultipartFormDataContent())
{
var img = Image.FromFile("path");
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.jpeg);
content.Add(new StreamContent(new MemoryStream(ms.ToArray())), "image", "myImage.jpg");
using (var response = await client.PostAsync($"http://localhost:####/api/1.0/###", content))
{
var responseAsString = await response.Content.ReadAsStringAsync();
return responseAsString;
}
}
}
}
Successful request using postman:
Post Request using Postman
Try this-
using (var client = new HttpClient())
{
client.BaseAddress = new Uri($"http://localhost/###");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
using (var content = new MultipartFormDataContent())
{
content.Add(new StreamContent(new MemoryStream(image)), "image", "myImage.jpg");
using (var response = await client.PostAsync($"http://localhost:#####/###/###/###", content).ConfigureAwait(false))
{
if (response.StatusCode == HttpStatusCode.OK)
{
var responseAsString = response.Content.ReadAsStringAsync().Result;
var receiptFromApi = JsonConvert.DeserializeObject<Receipt>(responseAsString);
var metadata = new metadata(bilaga)
{
Value1 = fromApi.Value1.Value,
Value2 = fromApi.Value2.Value,
Value3 = fromApi.Value3.Value,
Value4 = fromApi.Value4.Value
};
return metadata;
}
else
{
throw new InvalidProgramException();
}
}
}
}
reference- https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html

write a http post request to bot framework running on localhost

I have a bot running on http://localhost:3978/api/messages.
Instead of debugging it using an emulator, can I go about using a http post request to the messaging endpoint of the bot?
If so, how do I go about doing it?
I am using c# microsoft bot framework, and I am new to this application.
I do not want to use any channels or DirectLine api, just using Httpclient.
You can do this with C# using code similar to below. Note that you would have to construct an Activity to send by setting the appropriate properties for your needs, which is not included in this code.
//make a call to get an auth token
string token;
using (var client = new WebClient())
{
var values = new NameValueCollection();
values["grant_type"] = "client_credentials";
values["client_id"] = "YOUR APP ID";
values["client_secret"] = "NcOXRwb51joibEfzUuNE04u";
values["scope"] = "YOUR APP ID/.default";
var response =
client.UploadValues("https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token", values);
var responseString = Encoding.Default.GetString(response);
var result = JsonConvert.DeserializeObject<ResponseObject>(responseString);
token = result.access_token;
}
//you will need to adjust this value for your project.
//this example for a proxy project so the service url here is
//just an arbitrary endpoint I was using to send activities to
activity.ServiceUrl = "http://localhost:4643/api/return";
var jsonActivityAltered = JsonConvert.SerializeObject(activity);
using (var client = new WebClient())
{
client.Headers.Add("Content-Type", "application/json");
client.Headers.Add("Authorization", $"Bearer {token}");
try
{
var btmResponse = client.UploadString("http://localhost:3971/api/messages", jsonActivityAltered);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
Have you tried using something like postman? (it's free and easy to use)
https://www.getpostman.com/
You can also write scripts in postman
otherwise you can just go to the endpoint of your API in the browser
http://localhost:3978/api/
I see you mentioned you wanted to make a console application.
You could do that. I'd suggest using postman though.
Here is an example of sending a file as well as some querystring data and Authentication using a Bearer token.
Sorry it may not be exact. Had to do a bit of copy pasting/deleting from some code examples if have
using (HttpClient client = new HttpClient())
{
JObject jsonModel = new JObject();
client.BaseAddress = new Uri("http://localhost:3978/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", AuthToken);
using (var multipartFormDataContent = new MultipartFormDataContent())
{
var values = new[]
{
new KeyValuePair<string, string>("firstname", lastname),
new KeyValuePair<string, string>("lastname", lastname),
new KeyValuePair<string, string>("payloadFile", FileName)
};
foreach (var keyValuePair in values)
{
multipartFormDataContent.Add(new StringContent(keyValuePair.Value),
String.Format("\"{0}\"", keyValuePair.Key));
}
ByteArrayContent fileContent = new ByteArrayContent(File.ReadAllBytes(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
string FullxmlString = File.ReadAllText(Path.Combine(HttpContext.Current.Server.MapPath("~/uploads/output/" + FileName)));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("payloadFile") { FileName = "payloadFile" };
multipartFormDataContent.Add(fileContent);
HttpResponseMessage response = client.PostAsync("api/message", multipartFormDataContent).Result;
string returnString = response.Content.ToString();
using (HttpContent content = response.Content)
{
string res = "";
Task<string> result = content.ReadAsStringAsync();
res = result.Result;
}
}
}

How to send remote mp3 file to Telegram channel using Telegram Bot API's sendAudio method in C#

I create a bot (#mp3lyric_bot_test) in telegram and set it as administrator in my channel (#mp3lyric_test). Now I want to make a request to send an mp3 to channel using telegram api.
my mp3 is in web, something like this: http://bayanbox.ir/download/7028444634071302239/Sound-1.mp3
At first i download mp3 with this method:
public static Task<byte[]> DownloadAsync(string requestUriSt)
{
var requestUri = new Uri(requestUriSt);
byte[] fileBytes;
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
{
using (var responseMessage = await httpClient.SendAsync(request))
{
fileBytes = await responseMessage.Content.ReadAsByteArrayAsync();
var audioString = Encoding.UTF8.GetString(fileBytes, 0, fileBytes.Length);
}
}
}
return fileBytes;
}
if there is a way to send mp3 directly without download, please tell me how? thanks.
Then send that byte array (fileBytes) using this code:
my bot token is 247655935:AAEhpYCeoXA5y7V8Z3WrVcNJ3AaChORjfvw
using (var client = new HttpClient())
{
var uri = new Uri("https://api.telegram.org/bot247655935:AAEhpYCeoXA5y7V8Z3WrVcNJ3AaChORjfvw/sendAudio");
using (var multipartFormDataContent = new MultipartFormDataContent(
"SendAudio----" + DateTime.Now.ToString(CultureInfo.InvariantCulture)))
{
multipartFormDataContent.Add(
new StringContent("#mp3lyric_test"),
string.Format("\"{0}\"", "chat_id")
);
multipartFormDataContent.Add(
new StreamContent(new MemoryStream(fileBytes)),
'"' + "audio" + '"'
);
using (var message = await client.PostAsync(uri, multipartFormDataContent))
{
var contentString = await message.Content.ReadAsStringAsync();
}
}
}
I have two error:
"Request Entity Too Large" when my mp3 is about 6mb or 7mb or ... (not using http://bayanbox.ir/download/7028444634071302239/Sound-1.mp3)
error_code:400, description:"Bad Request: URL must be in UTF-8" (after using that mp3 for test that is 28kb)
To send a new AudioFile you use the SendAudio method but with the InputFile field.
First create an InputFile object, then pass those bytes in the audio parameter of the SendAudio method
If you need to resend the same AudioFile to another user, then you can use the String option as the audio parameter in the SendAudio
I chaged my codes for send the byte array (fileBytes) and now it works:
using (var client = new HttpClient())
{
var uri = new Uri("https://api.telegram.org/bot247655935:AAEhpYCeoXA5y7V8Z3WrVcNJ3AaChORjfvw/sendAudio?chat_id=#mp3lyric_test");
using (var multipartFormDataContent = new MultipartFormDataContent())
{
var streamContent = new StreamContent(new MemoryStream(fileBytes));
streamContent.Headers.Add("Content-Type", "application/octet-stream");
streamContent.Headers.Add("Content-Disposition", "form-data; name=\"audio\"; filename=\"Sound-1.mp3\"");
multipartFormDataContent.Add(streamContent, "file", "Sound-1.mp3");
using (var message = await client.PostAsync(uri, multipartFormDataContent))
{
var contentString = await message.Content.ReadAsStringAsync();
}
}
}

Categories

Resources