I have implemented webhook for revenuecat in .net core C#. But for some reason I am getting 400 badrequest with empty response. I am mostly sure that I am not getting the json response in webook through revenuecat for any of the event occurring.
I have also added endpoint on revenue cat webhook with authentication. I have tried several time and as I have not way to test this on local machine. I need help from revenue cat team to provide some reference doc with sample implementation just to get proper json response. Below is the code snippet that I am using to get json response from the webhook endpoint added in revenuecat.
var webHookSecret = _configuration[Constants.RevenueCatWebHookSecret]; var headerAuthorization = HttpContext.Request.Headers["Authorization"].ToString(); #region Check authorization if (webHookSecret == headerAuthorization) { json = await new StreamReader(HttpContext.Request.Body).ReadToEndAsync(); } else { _logger.Information($"Un-Authorized token access in revenuecat webhook. Returning BadRequest response."); throw new APIException(HttpStatusCode.Unauthorized, new APIError(_configuration, "InternalServerError")); }
Related
I'm trying to read all accounts my user is associated with. The Documentation claims that this should be possible by calling:
GET https://app.vssps.visualstudio.com/_apis/accounts?api-version=5.1
Because the docs are kind of confusing it could be that I have to call
GET https://app.vssps.visualstudio.com/_apis/accounts?ownerId={GUID}&api-version=5.1
instead.
I'm using OAuth-Authentication. In order to get it work I created an ASP.NET Core application. I created an app registration in DevOps and I retrieve an OAuth token with the following scopes without any problem:
vso.auditlog
vso.connected_server
vso.dashboards
vso.entitlements
vso.environment_manage
vso.graph
vso.identity
vso.loadtest
vso.machinegroup_manage
vso.memberentitlementmanagement
vso.profile
vso.project
vso.securefiles_read
vso.security_manage
vso.taskgroups_read
vso.tokenadministration
vso.tokens
vso.variablegroups_read
vso.wiki
According to the docs only vso.profile should be necessary for this request.
However the result I receive is always:
HttpRequestException: Response status code does not indicate success: 401 (TF400813: The user '{AZURE_TENANT_ID}\{MY_MAIL_ADDRESS}' is not authorized to access this resource.).
Other requests are working just fine e.g.:
GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.1
The accounts-request is special because it can be sent without setting the context to a specific organisation or project. I guess this the reason for the different results.
EDIT
After trying ot today using the both URLs mentioned above I now get 400 as the response status code. This is a sample Bearer-Token I got after I decoded it:
{
"nameid": "1340eb0b-cabf-476c-a950-a070c34ca367",
"scp": "vso.profile",
"aui": "a2d8bdf0-9406-415a-aa79-bee9e2600c37",
"appid": "e1bea2a2-****-****-****-************",
"iss": "app.vstoken.visualstudio.com",
"aud": "app.vstoken.visualstudio.com",
"nbf": 1587395030,
"exp": 1587398630
}
Here is some simplified C# code I use:
HttpClient client = _clientFactory.CreateClient("DevOps");
var token = await _authHelper.GetTokenAsync(tokenType);
client.DefaultRequestHeaders.Add("Authorization", $"Bearer { token.AccessToken}");
var uri = "https://app.vssps.visualstudio.com/_apis/accounts?api-version = 5.1";
try
{
var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode();
var content = await response.Content.ReadAsStringAsync();
return content;
}
catch (Exception ex)
{
// ex.Message = Response status code does not indicate success: 400 (Bad Request).
// ...
throw;
}
I was using Azure Text-to-Speech API succesfully for months with this format:
<speak version='1.0' xmlns='w3.org/2001/10/synthesis' xml:lang='en-US'><voice name='Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)'>My text</voice></speak>
But suddenly this request started returning:
HTTP/1.1 400 Bad request
We were using the same request successfully for months (with different phrase of course) but just some weeks ago the same request started returning this error. I don't get any additional information so I don't know where to look. Azure documentation says:
A required parameter is missing, empty, or null. Or, the value passed
to either a required or optional parameter is invalid. A common issue
is a header that is too long.
I also tried making the request more specific by adding gender and language and replacing single quotes with double quotes, but no use:
<speak version="1.0" xmlns="w3.org/2001/10/synthesis" xml:lang="fi-FI" xml:gender="Female"><voice name="Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)">Text.</voice></speak>
Did something change in the API? Or what is missing in my request?
I got a 200 OK with the right content when I send the following payload:
<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='en-US'><voice name='Microsoft Server Speech Text to Speech Voice (fi-FI, HeidiRUS)'>This is my test</voice></speak>
Here is my C# code to send this:
// Generate request
string body = $#"<speak version='1.0' xmlns='http://www.w3.org/2001/10/synthesis' xml:lang='{voiceLang}'><voice name='{voiceName}'>{text}</voice></speak>";
using (var client = new HttpClient())
{
using (var request = new HttpRequestMessage())
{
// Set the HTTP method
request.Method = HttpMethod.Post;
// Construct the URI
request.RequestUri = new Uri(ttsHostUri);
// Set the content type header
request.Content = new StringContent(body, Encoding.UTF8, "application/ssml+xml");
// Set additional header, such as Authorization and User-Agent
request.Headers.Add("Authorization", "Bearer " + accessToken);
request.Headers.Add("Connection", "Keep-Alive");
// Update your resource name
request.Headers.Add("User-Agent", "YOUR_RESOURCE_NAME");
request.Headers.Add("X-Microsoft-OutputFormat", "riff-24khz-16bit-mono-pcm");
// Create a request
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
// Asynchronously read the response
using (var dataStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
{
// ... Process your audio here
}
}
}
}
The only difference that I can see on our payloads is the xmlns value where I have a full url (with http://) whereas yours doesn't get it.
The error may be elsewhere: are you sure you are authenticating yourself when querying the endpoint?
We also suddenly got the 400 error and in our case we had missed to encapsulate the text for the XML request with
<![CDATA[ your text here ]]>
after we did that in our code we got no more reported 400 errors by the users.
I got an api keys for Azure Cognitive services, but I can't find any documentation how I am calling this service through postmen. Anybody has experience with this?
Seems you are trying to call Text To Speech service with your keys. There are two steps for that.
1. Need Access Token
You have to get your token like this format:
Request URL: https://YourResourceEndpoint/sts/v1.0/issuetoken
Method: POST
Hearder: Content-Type:application/x-www-form-urlencoded
Ocp-Apim-Subscription-Key:YourKeys
See The Screen shot for clarity:
Code Snippet:
public async Task<string> GetSpeechServiceToken()
{
try
{
string tokenUrl = $"https://YourServiceURL.cognitiveservices.azure.com/sts/v1.0/issuetoken";
var tokenRequest = new HttpRequestMessage(HttpMethod.Post, tokenUrl);
tokenRequest.Headers.Add("Ocp-Apim-Subscription-Key", "subscriptionKey");
using (var client = new HttpClient())
{
var tokenResponse = await client.SendAsync(tokenRequest);
var token = await tokenResponse.Content.ReadAsStringAsync();
return token;
}
}
catch (Exception ex)
{
ex.Message.ToString();
}
return null;
}
You could have a look on official Docs
2. Get List Of Voices With Token You Have Received Earlier
You can request for Text To Speech voice list Like below:
Request URL: https://centralus.tts.speech.microsoft.com/cognitiveservices/voices/list
Method : GET
Authorization: Bearer Token Paste Your Token Here
See the screen shot for clarity
You could find more details here
Note: In case of your test account You can create here
Update:
I would sent a request and somehow I got an uri or something where I can hear it? is this possible?
Yeah its possible. But in that case you have to use sdk. Here Is the complete sample.
I try to set up a notification for changes in Azure user data (https://learn.microsoft.com/en-us/graph/webhooks).
I send a request from a local client to the Azure Graph API and I have a publicly available server (with SSL) in the payload of the request as notification URL.
Azure now sends a posts request to my server (like in the documentation - exact post request see below) and I try to send the token I got back (like in the documentation). But I always get the following error message "Subscription validation request failed. Response must exactly match validationToken query parameter."
Post request from Azure:
Path: /?validationToken=Validation%3a+Testing+client+application+reachability+for+subscription+Request-Id%3a+3b3f9821-ce3f-23d9-879b-00a23f3
Body: is empty
I tried every part and encoding of the path (like just the request ID or the whole path) but I always get the error message. So whats the right thing to send back?
Firstly, the validation token you receive should be treated as an opaque value and returned unchanged and the error Subscription validation request failed. Response must exactly match validationToken query parameter is trying to tell you that something changed.
Since the validation token comes to you as a URL query parameter, make sure you're working with a properly decoded value in your code before returning it.
Here is the relevant documentation from Microsoft Docs: Notification endpoint validation
POST https://{notificationUrl}?validationToken={opaqueTokenCreatedByMicrosoftGraph}
Other requirements(from the same reference):
response within 10 seconds
200 (OK) status code.
content type must be text/plain.
body must include the validation token.
Code Samples
ASP.NET MVC Sample - Specifically look at the NotificationController.cs file
[HttpPost]
public async Task<ActionResult> Listen()
{
// Validate the new subscription by sending the token back to Microsoft Graph.
// This response is required for each subscription.
if (Request.QueryString["validationToken"] != null)
{
var token = Request.QueryString["validationToken"];
return Content(token, "plain/text");
}
Node.js code sample - Specifically look at listen.js
/* Default listen route */
listenRouter.post('/', (req, res, next) => {
let status;
let clientStatesValid;
// If there's a validationToken parameter in the query string,
// then this is the request that Office 365 sends to check
// that this is a valid endpoint.
// Just send the validationToken back.
if (req.query && req.query.validationToken) {
res.send(req.query.validationToken);
// Send a status of 'Ok'
status = 200;
}
You should return the validationToken from the query string with an HTTP 200 response code. You also have to do that within a few seconds, or the graph will fail the request and your call to create the subscription will fail.
Here is an example of the validation endpoint in ASP.NET Web API 2:
public ActionResult<string> Post([FromQuery]string validationToken = null)
{
if(!string.IsNullOrEmpty(validationToken))
{
Console.WriteLine($"Token: '{validationToken}'");
return Ok(validationToken);
}
}
I'm working on writing an integration to Acumatica's contract based API and I am having issues preventing me from getting data from the API. Here is the error:
System.ServiceModel.FaultException
System.Web.Services.Protocols.SoapException: Server was unable to
process request. ---> PX.Data.PXUndefinedCompanyException: Unable
determine proper company id for the request.
Here is my API integration code which lives inside one of my API controller methods:
public HttpResponseMessage Get()
{
var binding = new System.ServiceModel.BasicHttpBinding()
{
AllowCookies = true
};
var address = new System.ServiceModel.EndpointAddress("http://acumaticasandbox.mydomain.com/MyCompany/entity/Default/5.30.001");
using (DefaultSoapClient client = new DefaultSoapClient(binding, address))
{
client.Login("myuser", "mypassword", "MyCompany", null, null);
Entity[] items = client.GetList(new SalesOrder(), false);
client.Logout();
return Request.CreateResponse(HttpStatusCode.OK, items);
}
}
Obviously "mydomain" and "MyCompany" are real values in my actual code.
I can't seem to get past the client.Login call no matter what I've tried. Any advice is appreciated.
I am using Acumatica endpoint version 5.30.001 and using C# for the integration code.
Instead of using the 'company name' in your request, use the company 'login name'.
You can find the company login name in System->Management->Explore->Companies