Cloud Recoding RESTful API Error of Agora.io - agora.io

I would like to implement your Cloud Recoding of Live Broadcasting via RESTful API. I implemented it with NodeJs. Could you please help me why I get an error and how I can fix it?
On the manual,
"Status Code 400: The input is in the wrong format."
But I do not know what is wrong.
error: null
body: { resourceId: '', code: 400 }
var plainCredentials = new Buffer.from(agoraCustomerId+":"+agoraCustomerCertificate);
var base64Credentials = plainCredentials.toString("base64");
var options = {
url: "https://api.agora.io/v1/apps/AGORA_APP_ID/cloud_recording/acquire",
method: "POST",
headers: {
"Authorization": "Basic " + base64Credentials,
"Content-type": "application/json;charset=utf-8"
},
body:{
"cname": "190724060650293",
"uid": "060716332",
"clientRequest": {}
}
};
request.post(options, function (error, response, body) {
console.log("error: " + error);
console.log("body: ", body);
});

Agora's Cloud Recording is an add-on feature so it's not enabled by default, it needs to be enabled on your account for a specific AppID. The error you may be receiving is because the feature is not enabled on your account.
UPDATE:
Enabling Agora.io's Cloud Recording on your project is now available through the Agora.io Dashboard.
To enable Cloud Recording on your project, you’ll need to click into the Products & Usage section of the Agora.io Dashboard and select the Project name from the drop-down in the upper left-hand corner, click the Duration link below Cloud Recording.
After you click Enable Cloud Recording, you will be prompted to confirm the concurrent channels settings which defaults to 50, but you can contact sales#agora.io if you need more.
Theres a getting started tutorial that leverages a POSTMAN collection for quick testing.
QuickStart Tutorial: https://medium.com/#hermes_11327/agora-cloud-recording-quickstart-guide-with-postman-demo-c4a6b824e708
Postman Collection: https://documenter.getpostman.com/view/6319646/SVSLr9AM?version=latest

In my case it was mistake in Region settings . I used AP_NORTHEAST_1 but 10 need be used

1 - Make sure you have enable agora recording
2- Check the link and send all parameters.
https://docs-preprod.agora.io/en/cloud-recording/cloud_recording_webpage_mode?platform=RESTful
EX: {
"cname": "httpClient463224",
"uid": "527841",
"clientRequest":{
"resourceExpiredHour": 24,
"scene": 1
}
}
You forgot to put "resourceExpiredHour": 24,"scene": 1
More info:
PHP: you need to put strval function
$body = ["cname"=>strval($cname),"uid" =>strval($uid),"clientRequest" => ["resourceExpiredHour" => 24,"scene" => 1]];
I hope you solve your issue

Related

Accessing secured FeatureLayer on ArcGIS online with JavaScript API

I am building a web app in a low code platform (Mendix). I am connecting the web app with ArcGIS online resources via the ArcGIS JavaScript API v4.19, which all goes pretty smoothely.
The challenge arises when I want to load specific secured ArcGIS online content via the ArcGIS JavaScript API, specifically from some FeatureLayers which are secured. I looked into the documentation and it seems the best way forward would be a so-called 'application login'. For this I want to setup an OAuth application login based on CLient ID and Client Secret. With these two I can get a valid token via AOuth and use that token to access the content by feeding the token to the IdentityManager via the JavaScript API.
This is were it goes wrong currently, I can't seem to figure out where to make it explicit on the ArcGIS online side that this specific secured FeatureLayer can be accessed via this application login, hence currently I am getting errors that the valid token and app id don't have access to the resource, being the end-point of the secured FeatureLayer.
Does anybody know how to associate a secured FeatureLayer in ArcGIS online to a application login?
EDIT 10-6-2021: Added code sample
After succesfully retrieving a valid token on the server side based on client id and client secret I use the client ID (=AppID) and token in the ArcGIS JavaScript API like below:
const token = {
server: "http://www.arcgis.com",
userId: <AppID>,
token:
<valid token retrieved via OAuth generateToken request,
ssl: true,
expires: 7200
};
IdentityManager.registerToken(token);
Only implementing this gives me an error whilst trying to access the secured feature layer:
identity-manager:not-authorized. "You are currently signed in as:
AppID. You do not have access to this resource:
https://server/someid/arcgis/rest/services/somefeatureserver/FeatureServer/0
I also read that sometimes below could be needed so added as well:
const idString = JSON.stringify(IdentityManager.toJSON());
console.debug("idString: " + idString);
IdentityManager.initialize(idString);
This resolves the error but makes a login popup appear again.
The layer is afterwards declared like below:
const layer = new FeatureLayer({
// URL to the service
url: layerObj.layerURLStatic
definitionExpression: queryDefinition,
featureReduction: clusterConfig && { type: "cluster" },
popupTemplate: {
title: "{" + inAttributeTitle + "}",
content: [
{
type: "fields", // FieldsContentElement
fieldInfos
}
],
actions: [
{
title: props.intButtonLabel,
id: btnId,
className: props.intButtonClass + intButtonIconClass,
type: "button"
}
]
},
outFields: ["*"]
});
webMap.add(layer);
Here is a snippet to generate the token and then register it with IdentityManager:
IdentityManager = require('esri/identity/IdentityManager')
function login(user, password){
var serverInfo = {
"server": "https://www.arcgis.com",
"tokenServiceUrl" : "https://www.arcgis.com/sharing/generateToken"
};
var userInfo = {
username : user,
password : password
}
IdentityManager.generateToken(serverInfo, userInfo).then(function (response){
response.server = serverInfo.server;
response.userId = user;
IdentityManager.registerToken(response);
});
}
I'm not sure how you are going to fit this in you app, but the sample should work if you paste it in your developer tools console when the app is running.
Also, it seems to me that userId property is for arcgis online username, not for appId.
As pointed out by Shaked, if you append '?token=[token_value]' int the layer URL you probably don't even need to register the token to query the layer.

Trying to log in to gmail while using TestCafe

I am learning TestCafe and am trying to create an account on a website and then logging in to Gmail to find the activation link. When I try to do this I just get a browser isn't secure message when I get to the part to enter a password. How do I get Gmail to trust TestCafe?
While you might succeed in doing so, this is not a good approach because:
it's slow doing this via GUI
it's britle because selectors will likely change, and you have no control over Google email selectors, so you won't even know if they change them
A better approach wuld be to use a service like Mailosaur where you can create an account and receive emails that you can later query via an API. Instead of doing a whole e2e flow over GUI, you request an email on Mailosaur's API, and if such an email exists, you'll receive a response you can parse and check for various things.
I've done this in the past, you can see my post here: https://sqa.stackexchange.com/questions/40427/automating-verification-of-sent-email-sms-messages/45721#45721 It's exactly Mailosaur and Testcafe (plus it requires axios as a package), so it seems to be what you're looking for.
To add the same code here:
import config from '../config';
import { customAlphabet } from 'nanoid';
import axios from 'axios';
import Newsletter from '../Objects/newsletter';
async function request (reqObject) {
try {
return await axios(reqObject);
} catch (error) {
console.error(error);
}
}
function serverId () {
return process.env.MAILOSAUR_SERVER_ID;
}
function mailosaurFullEmail (id) {
return (id ? id : nanoid()) + '.' + serverId()
+ '#' + config.mailosaurDomain;
}
fixture `Newsletter`
.page(baseUrl);
test
('Sign Up For Newsletter', async t => {
const id = (customAlphabet('1234567890', 10))();
await t
.typeText(Newsletter.newsEmailInput, mailosaurFullEmail(id))
.click(Newsletter.consent)
.click(Newsletter.sendButton);
let res = await request({
method: 'POST',
url: config.mailosaurUrlEmail + serverId(),
headers: {
'Authorization': 'Basic '
+ Buffer.from(process.env.MAILOSAUR_API_KEY)
.toString('base64'),
'Content-Type': 'application/json'
},
data: {
sentTo: mailosaurFullEmail(id)
}
});
await t
.expect(res.status).eql(200);
});
and it requires some config values:
{
"mailosaurUrlEmail": "https://mailosaur.com/api/messages/await?server=",
"mailosaurDomain": "mailosaur.io"
}
This is definitely much better, but it still has some limitations:
Mailosaur's API can still change, so it won't be exactly without any maintenance
it assumes that an email is sent immediately after a user action (newsletter in my case), but that might be far from reality in many situations such as when emails are sent to a queue where it can easily take several minutes to send an email
If you absolutely have to do it via Gmail, you will still be better off looking at their API that should allow you to search and query email messages as well.
There is an issue related to the Google login. You can try turning on the "Allow less secure apps" Google account setting to workaround this issue. Please note that this setting is available for the disabled 2-Step Verification.

AWS Error: Proxy integrations cannot be configured to transform responses

I'm a beginner in Amazon's Lambda-API implementations.
I'm just deploying a very simple API: a very simple lambda function with Python 2.7 printing "Hello World" that I trigger with API Gateway. However, when I click on the Invoke URL link, it tells me "{"message": "Internal server error"}".
Thus, I'm trying to see what is wrong here, so I click on the API itself and I can see the following being grey in my Method Execution: "Integration Response: Proxy integrations cannot be configured to transform responses."
I have tested many different configurations but I still face the same error. I have no idea why this step is grey.
I had the same problem when trying to integrate API gateway and lambda function. Basically, after spending a couple of hours, I figure out.
So when you were creating a new resource or method the Use Lambda Proxy integration was set by default.
So you need to remove this. Follow to Integration Request and untick the Use Lambda Proxy integration
you will see the following picture
Then in you Resources, Atction tab, choose Enable CORS
Once this done Deploy your API once again and test function. Also, this topic will explain what's happening under the hood.
Good luck...
The Lambda response should be in a specific format for API gateway to process. You could find details in the post. https://aws.amazon.com/premiumsupport/knowledge-center/malformed-502-api-gateway/
exports.handler = (event, context, callback) => {
var responseBody = {
"key3": "value3",
"key2": "value2",
"key1": "value1"
};
var response = {
"statusCode": 200,
"headers": {
"my_header": "my_value"
},
"body": JSON.stringify(responseBody),
"isBase64Encoded": false
};
callback(null, response);
My API was working in Postman but not locally when I was developing the front end. I was getting the same errors when trying to enable CORS on my resources for GET, POST and OPTIONS and after searching all over #aditya answer got me on the right track but I had to tweak my code slightly.
I needed to add the res.statusCodeand the two headers and it started working.
// GET
// get all myModel
app.get('/models/', (req, res) => {
const query = 'SELECT * FROM MyTable'
pool.query(query, (err, results, fields) => {
//...
const models = [...results]
const response = {
data: models,
message: 'All models successfully retrieved.',
}
//****** needed to add the next 3 lines
res.statusCode = 200;
res.setHeader('content-type', 'application/json');
res.setHeader('Access-Control-Allow-Origin', '*');
res.send(response)
})
})
If you re using terraform for aws resource provision you can set the
"aws_api_gateway_integration" type = "AWS" instead of "AWS_PROXY" and that should resolve your problem.

Using the Rally API to pull user profile

I am trying to use the Rally web service API to get some data. Code as blow. On IE it will pop out a login window, after entry login name and password, I am about to get some data. But when I use chrome, it response 401, not sure what I missing. I know there is SDK available, but due to some limitation, not able to use it. Any suggestions please?
var url = https://rally1.rallydev.com/slm/webservice/v2.0/users;
$.ajax({
url: url,
type: 'GET',
heards: { zsessionid: apiKey },
success: function(json) {
console.log(JSON.stringify(json));
}
},
error: function( req, status, err ) { console.log( 'something went wrong', status, err );
}
});
I'd love to know more about why you can't use the SDK. Anyway, in this case your config likely needs headers instead of heards to pass the api key.

Watson TTS doesn't allow to choose voice

Created a Bluemix app to get the proper credentials and using Fiddler Text to Speech(TTS) to record prompts. Recordings use the default "Michael" voice. I want Allison.
If I try passing in "voice", I get the following error, even when I specify "Michael" as my choice:
{
"code_description": "Bad request",
"code": 400,
"error": "The argument(s) [u'voice'} are not allowed."
}
This is my payload:
{
"text": "Hello,, this is Dora. How are you today?",
"voice": "en-US_AllisonVoice"
}
I have a developer account, do I need to sign up to use "voice"? Even if I pass in the default "Michael"?
I think your problem is in the way you are specifing the voice parameter.
The voice and text parameters can be send as query parameters in a GET.
Examples
1. Curl
curl -u "{username}":"{password}" "https://stream.watsonplatform.net/text-to-speech/api/v1/synthesize?voice=en-US_AllisonVoice&text=Hello%2C%20this%20is%20Dora.%20How%20are%20you%20today%3F"
Node
var watson = require('watson-developer-cloud');
var fs = require('fs');
var text_to_speech = watson.text_to_speech({
username: '<username>',
password: '<password>',
version: 'v1'
});
var params = {
text: 'Hello, this is Dora. How are you today?',
voice: 'en-US_AllisonVoice',
accept: 'audio/wav'
};
// Pipe the synthesized text to a file
text_to_speech.synthesize(params).pipe(fs.createWriteStream('output.wav'));
See the Text to Speech API Reference for more examples on how to call the service.
Try the example above here:
https://text-to-speech-demo.mybluemix.net/api/synthesize?voice=en-US_AllisonVoice&text=Hello%2C%20this%20is%20Dora.%20How%20are%20you%20today%3F
Powered by the demo app: https://text-to-speech-demo.mybluemix.net