Alexa Audio Player Directive - node.js

I'm trying to build an Alexa skill that can play an audio file. I'm trying to send an Audio Player Play directive in the Launch Request, but when I use this code, I get no response back from my Alexa. Does it look correct?
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
console.log('IN LAUNCHREQUEST');
return handlerInput.responseBuilder
.addDirective({
type: 'AudioPlayer.Play',
playBehavior: 'REPLACE_ALL',
audioItem: {
stream: {
token: "0",
url: "myurlhere",
offsetInMilliseconds: 0
}
}
})
}
};

You must return a "built" response, in the handler. So in you case the code would be:
const LaunchRequestHandler = {
canHandle(handlerInput) {
return handlerInput.requestEnvelope.request.type === 'LaunchRequest';
},
handle(handlerInput) {
console.log('IN LAUNCHREQUEST');
return handlerInput.responseBuilder
.addDirective({
type: 'AudioPlayer.Play',
playBehavior: 'REPLACE_ALL',
audioItem: {
stream: {
token: "0",
url: "myurlhere",
offsetInMilliseconds: 0
}
}
})
.getResponse();
// ^^^ add this line
}
};

If you are using alexa sdk v2 (https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs) then you can use inbuilt methods to play audio. Following methods are available to play long form audio.
addAudioPlayerPlayDirective(playBehavior: interfaces.audioplayer.PlayBehavior, url: string, token: string, offsetInMilliseconds: number, expectedPreviousToken?: string, audioItemMetadata? : AudioItemMetadata): this;
addAudioPlayerStopDirective(): this;
addAudioPlayerClearQueueDirective(clearBehavior: interfaces.audioplayer.ClearBehavior): this;
More information can be found on https://ask-sdk-for-nodejs.readthedocs.io/en/latest/Building-Response.html
Following is a code snippet that I use in my lambda to play audio.
//Create Image to be displayed with song
const metadata = {
title: 'Stopwatch Audio',
art: {
sources: [{
url: imageUrl
}]
}
};
handlerInput.responseBuilder.speak(speechText).addAudioPlayerPlayDirective("REPLACE_ALL", audiofile, audiofile, 0, null, metadata).withShouldEndSession(true).getResponse();

Related

createAysncThunk in Redux Toolkit catching error when making fetch request

I'm working on the user registration functionality of an application using Typescript and Redux Toolkit. When I make the fetch request to the signup endpoint, a new user is saved to the database I've connected, but I keep entering the catch error block.
export const registerUser = createAsyncThunk(
"user/registerUser",
async (form: { username:string, password:string }, thunkAPI) => {
try {
const response = await fetch('/api/auth/signup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userInfo: {
username: form.username,
password: form.password
}
}),
});
if (response.status === 200) return 200;
else return 400;
} catch (e) {
console.log('Error')
}
}
);
I've tried logging the response to the console a number of ways
const data = await response.json() console.log(data)
But have had no luck. I think this is an error with how I've done my fetch request using createAsyncThunk but haven't been able to figure out what I've missed.
This is the code for the initial state and slice:
interface UserState {
userProfile: {
id: number | null;
},
registration: {
status: 'loaded' | 'loading'
}
}
const initialState : UserState = {
userProfile: {
id: null,
},
registration: {
status: 'loaded'
}
};
export const userSlice = createSlice({
name: 'user',
initialState,
reducers: {
},
extraReducers: (builder) => {
builder.addCase(registerUser.fulfilled, (state) => { state.registration.status = 'loaded' }),
builder.addCase(registerUser.rejected, (state) => { state.registration.status = 'loaded' }),
builder.addCase(registerUser.pending, (state) => { state.registration.status = 'loading' })
}
})
And here is the code for the function where the action is dispatched on the UI
const handleRegister= async () => {
if (!username) return alert('Username field was left empty');
if (!password) return alert('Password field was left empty');
const {payload} : any = await dispatch(registerUser({ username: username, password: password}));
if (payload === 200) {
alert('Successfully registered. Redirecting to dashboard');
return navigate('/dashboard');
} else { return alert('User creation unsuccessful'); }
}
Appreciate any help as I've looked through many other posts but haven't been able to resolve my issue.

AWS Lambda not calling third party api in loop

i am using aws lambda and i am calling third party server using request library. this library on outside the loop but on loop its not hitting even i am not getting any error or result. and i also checked on server there is no hitting
below is my code with console
exports.handler = async (event) => {
try {
let transactionList = [];
// event.body is json form object with keys and values that we send
userBrokers.forEach(async (brokers) => {
const userStocks = 50;
const qty = (qtyPercentage * userStocks) / 100;
console.log("function before api call")
request.post({
headers: {
'content-type': 'application/x-www-form-urlencoded',
"Apca-Api-Key-Id": brokers.api_key,
"Apca-Api-Secret-Key": brokers.secret_key
},
url: 'https://paper-api.alpaca.markets/v2/orders',
json: {
symbol,
qty,
side: orderType,
type: marketType,
time_in_force
}
}, function (error, response, body) {
if (error) {
console.log("api call error")
transactionList.push({
transactionSuccess: false,
reason: error,
userId: brokers.user_id,
documentId: brokers._id
})
}
else {
console.log("api response")
if (response.statusCode == 200) {
transactionList.push({
brokerOrderId: body.id,
symbol: body.symbol,
orderType: body.order_type,
marketType: body.side,
transactionSuccess: true,
userId: brokers.user_id,
documentId: brokers._id
})
}
else {
transactionList.push({
transactionSuccess: false,
reason: body.message,
userId: brokers.user_id,
documentId: brokers._id
})
}
}
});
})
console.log("function before response")
return {
statusCode: 200,
body: JSON.stringify(transactionList),
};
} catch (error) {
console.log("function catch block")
return {
statusCode: 200,
body: JSON.stringify(error.message),
};
}};
and i get below console.
function before api call
function before response
and response from lambda
status: 200 and message: []
The problem is that you're trying to execute an async method in a forEach but you have no way of enforcing Lambda to wait for the loop to finish. You should switch your forEach to a map and await all the promises:
Bad:
arr.forEach(async (val) => {})
Good:
const arrOfResults = await Promise.all(arr.map(async (val) => {}))

uploading video to Youtube with API Processing abandoned The video could not be processed error

I want to upload a video to YouTube. So my code snipped like that:
var request: any = await Youtube.videos.insert({
resource: {
snippet: {
title: title
, description: description
}
, status: {
privacyStatus: "private"
}
}
, part: "snippet,status"
, media: {
body: fs.createReadStream(file)
}
}, (err: any, data: any) => {
if (err) {
console.log(err.response.data.error)
}
console.log("Video upload to youtube Successfull.");
});
But When I checked My YouTube channel I getting an error as
Processing abandoned The video could not be processed
Why Im getting this error? How can I solve this problem? Please Help!
Looks to me like it might not be uploading the video itself just the metadata. Try this.
const youtube = google.youtube({version: 'v3', auth});
var fileMetadata = {
'title': title
};
var media = {
body: fs.createReadStream(file)
};
youtube.videos.insert({
resource: fileMetadata,
media: media,
fields: 'id'
}, function (err, file) {
if (err) {
// Handle error
console.error(err);
} else {
console.log("Video upload to YouTube Successful.");;
}
});

How to set signed key for /api/v3/order and order/test in Binance API?

I'm using NestJs as backend to send and get requests from Binance api, but I'm getting a { code: -1022, msg: 'Signature for this request is not valid.' } when I want to post a new order (buy/sell).
This is how the body of postman looks like:
{
"symbol": "BTCUSDT",
"side": "BUY",
"type": "LIMIT",
"timeInForce": "GTC",
"quantity": "1",
"price": "59806.23000000"
}
This is my method for creating the signed key:
async testTrading(trade: ITradeReqOrderDto)
{
const serverTime = Date.now();
const extraQuery = "symbol="+trade.symbol+"&side="+trade.side+
"&type="+trade.type+"&timeInForce="+trade.timeInForce+"&quantity="+
trade.quantity+"&price="+trade.price+"&recvWindow=5000";
const signature = await this.createSignature(serverTime,extraQuery);
const response = await this.wsService.orderTest(trade, serverTime, this.apiKey, signature);
}
async createSignature(serverTime: number, extraQuery: string): Promise<string>
{
if (extraQuery != null)
{
return await this.cypherService.createSignature(this.secretKey, extraQuery+"&timestamp="+serverTime);
}
return await this.cypherService.createSignature(this.secretKey, "timestamp="+serverTime);
}
Here is where the signed key is created:
async createSignature(secret: string, queryString: string)
{
return await crypto.createHmac('sha256', secret).update(queryString).digest('hex');
}
This is how I'm sending the data to test it:
async orderTest(trade: ITradeReqOrderDto, timestamp: number, apiKey: string, signature: string): Promise<ITradeOrderResDto>
{
try
{
trade.timestamp = timestamp;
trade.signature = signature;
const response = await this.httpService.post("https://api.binance.com/api/v3/order/test", null,
{
params: trade,
headers: { "X-MBX-APIKEY": apiKey, "Content-Type": "application/json"}
}).toPromise();
} catch(error) {
console.log(error);
return { errors: [error]};
}
}
This is the path that is sended to the Binance API /api/v3/order/test:
path: '/api/v3/order/test?symbol=BTCUSDT&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=59806.23000000&timestamp=1618610661033&signature=6f739d53c9cc24b9c489e1d8b4b2577b05b1530806ded7ba8932339fd87243a
NEVERMIND. I just realize that I had an extra parameter which was recvWindow=5000";. Stuck with this for 2 hours but finally got it.

GraphQL with RESTful returning empty response

I am connecting GraphQL with REST endpoints, I confirmed that whenever I am calling http://localhost:3001/graphql it is hitting REST endpoint and it is returning JSON response to GraphQL server, but I am getting an empty response from GraphQL server to GUI as follows:
{
"data": {
"merchant": {
"id": null
}
}
}
Query (decoded manually):
http://localhost:3001/graphql?query={
merchant(id: 1) {
id
}
}
Below is how my GraphQLObjectType looks like:
const MerchantType = new GraphQLObjectType({
name: 'Merchant',
description: 'Merchant details',
fields : () => ({
id : {
type: GraphQLString // ,
// resolve: merchant => merchant.id
},
email: {type: GraphQLString}, // same name as field in REST response, so resolver is not requested
mobile: {type: GraphQLString}
})
});
const QueryType = new GraphQLObjectType({
name: 'Query',
description: 'The root of all... queries',
fields: () => ({
merchant: {
type: merchant.MerchantType,
args: {
id: {type: new GraphQLNonNull(GraphQLID)},
},
resolve: (root, args) => rest.fetchResponseByURL(`merchant/${args.id}/`)
},
}),
});
Response from REST endpoint (I also tried with single object in JSON instead of JSON array):
[
{
"merchant": {
"id": "1",
"email": "a#b.com",
"mobile": "1234567890"
}
}
]
REST call using node-fetch
function fetchResponseByURL(relativeURL) {
return fetch(`${config.BASE_URL}${relativeURL}`, {
method: 'GET',
headers: {
Accept: 'application/json',
}
})
.then(response => {
if (response.ok) {
return response.json();
}
})
.catch(error => { console.log('request failed', error); });
}
const rest = {
fetchResponseByURL
}
export default rest
GitHub: https://github.com/vishrantgupta/graphql
JSON endpoint (dummy): https://api.myjson.com/bins/8lwqk
Edit: Adding node.js tag, may be issue with promise object.
Your fetchResponseByURL function get empty string.
I think the main problem is that you are using wrong function to get the your JSON string, please try to install request-promise and use it to get your JSON string.
https://github.com/request/request-promise#readme
something like
var rp = require('request-promise');
function fetchResponseByURL(relativeURL) {
return rp('https://api.myjson.com/bins/8lwqk')
.then((html) => {
const data = JSON.parse(html)
return data.merchant
})
.catch((err) => console.error(err));
// .catch(error => { console.log('request failed', error); });
}
In this case using data.merchant solved my problem. But the above suggested solution i.e., use of JSON.parse(...) might not be the best practice because if there are no object in JSON, then expected response might be as follows:
{
"data": {
"merchant": null
}
}
Instead of fields to be null.
{
"data": {
"merchant": {
"id": null // even though merchant is null in JSON,
// I am getting a merchant object in response from GraphQL
}
}
}
I have updated my GitHub: https://github.com/vishrantgupta/graphql with working code.

Resources