how to retrieve user first name in alexa - alexa

I am creating an alexa app and for that i have permission for the user's location and customer's firstname. My first question is if customer's first name is what is user's first name or it is something different. But if it is asking for the user's first name then to get that. For location info, we use ConsentToken, so is there any way to get the user name out of it?
I can ask for the user name and store it and then can greet the user. But i have to ask everytime user launches the app. I am using php.

First, the user has to link his account with your skill and accept the permission
(you need to set it in your skill configuration)
once the user is loged in, You will just be able to use a access/refresh token to get the user name from Alexa output
Check this, could be clearest: https://developer.amazon.com/fr/docs/custom-skills/request-customer-contact-information-for-use-in-your-skill.html

In addition to Neryuk's answer pointing correctly the documentation, I give some code sample in NodeJS.
Assuming you already gave all the permissions needed from Alexa Skill Developer Portal, you can ask for user information within your intent handler in this way:
const PERMISSIONS = ['alexa::profile:name:read', 'alexa::profile:email:read', 'alexa::profile:mobile_number:read'];
const MyIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
// checks request type
return request.type === 'LaunchRequest'
|| (request.type === 'IntentRequest'
&& request.intent.name === 'MyIntent');
},
async handle(handlerInput) {
const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
const requestAttributes = handlerInput.attributesManager.getRequestAttributes();
const consentToken = handlerInput.requestEnvelope.context.System.apiAccessToken;
if (!consentToken) {
return responseBuilder
.speak('Missing permissions')
.withAskForPermissionsConsentCard(PERMISSIONS)
.getResponse();
}
const client = serviceClientFactory.getUpsServiceClient();
const userName = await client.getProfileName();
const userEmail = await client.getProfileEmail();
const userMobileNumber = await client.getProfileMobileNumber();
console.log('Name successfully retrieved '+ userName);
console.log('Email successfully retrieved '+ userEmail);
console.log('PhoneNumber successfully retrieved '+ JSON.stringify(userMobileNumber));
const speakOutput = 'The username is '+userName;
return handlerInput.responseBuilder
.speak(speakOutput)
.withSimpleCard('MyFavSkill')
.getResponse();
},
};
Note that you must declare your handlerInput code as async because you are invoking an async request you must wait within your method.
Code is missing the "try-catch" block to simplify its reading, but you should manage unexpected errors.
Hope this may help.

Related

Save values to a .env variable in ReactJS

I've been trying to create a .env variable where initially it will be empty but after login process it will store the data to the .env variable for further work, but unfortunately, I am not able to do so.
Before I put my code example, I would like to have some suggestions!!
Yea, in the login process I'm using session storage to store the user token. So, will it be a good work to store the user data into a .env file and later access it for future use or should I just call getToken function every time I need the token to verify if the user is logged in.
login.js:
const getToken = () => {
const tokenString = sessionStorage.getItem('token');
const userToken = JSON.parse(tokenString);
return userToken?.token
}
const saveToken = (userData) => {
sessionStorage.setItem('token', JSON.stringify(userData));
setToken(userData)
}
Tried different techniques to make it work, but I just couldn't get the data from the .env file.
Watched many different YouTube videos and did exactly like them but it was all in vain.
I checked multiple timed if there is any type or bug in my code or not! There was no error. I was getting the token after successful login and by default it was returning null. I was storing the token only when the user login successfully so that no garbage value gets inserted into the value.
Here's my logic:
const handleSubmit = async function (e) {
e.preventDefault();
const response = await loginUser(user);
if (response.status === 200) {
setToken(response.data);
process.env.REACT_APP_USER_TOKEN=response.data;
navigate("/");
} else {
console.error(response)
}
}
ENV files are used to store sensitive Api keys or secrets. which can only be read by the code when needed.
Storing user data in .env file is not the right way. If your user data should not be available easily in frontend, try encryption and store the encryption key in .env file or backend.

Trying to use React-google-login just for accessing Google OAuth2 calendar API but giving errors - why?

I'm really new to OAuth2 so could really use some help. I have a site where users register and login via standard means. However, once they register, I want to connect their Google account so they can view/edit/modify their Google calendars. To this end, I installed react-google-login and have a component on the front-end that logs them into their account. That works fine (here's the code). Please note that the jsx is in styled components, which is why it has odd labels.
return (
<GoogleContainer>
<Logo src={GoogleLogo} />
<GoogleLogin
clientId = {process.env.REACT_APP_CLIENT_ID}
render={(renderProps) => (
<GoogleBtn
onClick={renderProps.onClick}
disabled={renderProps.disabled}
style={styleObj}
>
Connect to Google
</GoogleBtn>
)}
// buttonText='Sign in to Google Calendar'
onSuccess={responseGoogle}
isSignedIn={true}
onFailure={responseError}
cookiePolicy={"single_host_origin"}
responseType='code'
accessType='offline'
scope='openid email profile https://www.googleapis.com/auth/calendar '
/>{" "}
</GoogleContainer>
);
On the backend, I have code that grabs the refresh_token, stores it in a database and then I make a token object that I can send back to the frontend. Here is the code for that -
//This next fx will be used in the CreateTokens fx called by Google Login to identify user by the email captured in scope
const fetchInfo = async (accessToken) => {
const request = await axios.get(
`https://www.googleapis.com/oauth2/v2/userinfo?access_token=${accessToken}`
);
let response = await request;
let email = "";
if (response) {
email = response.data.email;
}
return email;
};
//Get authorization tokens from google calendar when signing into Google
const createTokens = async (req, res, next) => {
try {
const { code } = req.body;
const { tokens } = await oauth2Client.getToken(code);
accessToken = await tokens.access_token;
expiryDate = await tokens.expiry_date;
id_token = await tokens.id_token;
//Make an object with accessToken and expiry data and send to front end
const tokenObj = {
accessToken,
expiryDate,
id_token,
};
//Refresh Token goes to the database
const refreshToken = await tokens.refresh_token;
//We find user by using the scope variable from Google Login (frontend) - fx above
let email = await fetchInfo(accessToken);
if (refreshToken) {
//Parameters to update record by putting refreshToken in database
const filter = { email: email };
const update = { refreshToken: refreshToken };
let user = await User.findOneAndUpdate(filter, update, {
new: true,
});
}
res.send({ tokenObj });
} catch (error) {
next(error);
}
};
That also works fine as I get the refresh_token and store it in the database by user and the tokenObject with the access token gets sent back to the frontend. Here's where I'm confused and can use some help - first of all, I thought I needed to send the token to the frontend to store it but pretty much every time I refresh my page now, the frontend is sending a boatload of information to the console (with tons of information from Google - like the profile, tokens, etc). I don't know what code I wrote that is causing this or if it's a good thing or not. If it's automatically generated, do I even need to have backend code to get the token? Also, I'm getting another message that says " react_devtools_backend.js:3973 Your client application uses libraries for user authentication or authorization that will soon be deprecated. See the Migration Guide for more information." I thought this was up-to-date and not sure what part is deprecated. Ugh - sorry I'm so new to this and very confused. Any help would be much, much appreciated!!
Blockquote

Discord.JS - How to get user ID from username?

can someone please help me to retrieve username from user ID and send a message to the chat with that ID?
if (message.content.startsWith(prefix)) {
const [CMD_NAME, ...args] = message.content
.trim()
.substring(prefix.length)
.split(/\s+/);
if (CMD_NAME === "getid") {
const getid1 = new MessageEmbed()
.setDescription("❗️ | Please tag the member to retrieve the ID!")
.setColor(10181046);
if (args.length === 0) return message.reply(getid1);
const username = client.guilds.cache.get('<GUILD ID>');
const userid = client.users.cache.find(username => username.tag === 'Someone#1234').id
message.channel.send(`${username} id is ${userid}`);
}
}
});
When I type the command "d!getid #Username", it shows me this error:
C:\Users\USER\Desktop\DiscordBotas\index.js:152 const userid = client.users.cache.find(username => username.tag === 'Someone#1234').id TypeError: Cannot read property 'id' of undefined at Client. (C:\Users\USER\Desktop\DiscordBotas\index.js:152:90)
You are creating a lambda of a variable that you just defined above the actual lambda, this could probably mess with your code.
The const username = client.guilds.cache.get('<GUILD ID>'); is wrong.
The fetching of the userId should probably work if you fix the line above it.
You are trying to get the user the wrong way. Firstly, why are you trying to match a user's tag with a guild? Maybe you think guild.cache has users? Well actually, this is client.guilds.cache, which only has guilds in it, and it returns a guild, not a user. Secondly, to get a user, you can try this method:
const user = client.users.cache.find(u => u.tag === 'SomeUser#0000')
console.log(user.id);
Below is code to get user by ID, but it probably won’t help with this, considering you would already have access to the ID
const user = client.users.cache.get("<UserID>");
console.log(user);
Also, you should add code to see if user isn’t found (client can’t find user with the condition). Here is some code to check that:
//... the find user code I put
if(!user) return message.reply('User could not be found');
message.channel.send(user.id);

AWS Cognito Authentication in Reactjs

I have built applications using Firebase and React, and the procedure is pretty seamless.
Lately I have been required to use AWS Cognito, and it seems a bit of a pain to set up as the docs are not clear.
Firstly, how can I do user authentication using Cognito? I set up a user pool, with the following app client settings:
Now, I add the authorizer to my API as follows:
Now my question is, how do I use this with my frontend to sign in a user and make authenticated API calls?
There seem to be two different toolkits available:
https://github.com/aws/aws-sdk-js
https://github.com/aws-amplify/amplify-js
It is not clear at all for a beginner what to use, and how to get authentication working. Ideally I would use it like I do for firebase, and just have my frontend make an authentication call using the email and password, and in turn receiving a token of some sort (on success only) that can then be used to then make signed API calls.
Can someone please help with code examples?
sorry for the confusion.
AWS Cognito Userpools act as an Identity Provider. It supports all User management (Sign Up, Sign In, Password reset, User deletion, etc). Cognito also supports Federated Identity (E.g., A User who already has an Google/Facebook account can sign in). In this case, Cognito talks to Google/Facebook using OAuth.
When I was learning about Cognito/JWT tokens, I created a simple JS/HTML to understand how it works. Since you asked for code, you can refer it - https://github.com/ryandam9/Cognito-tokens.
As per your screen shot, you already configured a Userpool - sls-notes-backend. Say, you configured the mandatory attribute as Email.
Step 0 - Initialize
You get both userPoolId and appId when you create the user pool.
poolData = {
UserPoolId: userPoolId,
ClientId: appId
};
userPool = new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(poolData);
Step 1 - Signup a User using Email and Password - Say your UI already captured these details from the User and user clicked on 'Sign Up' button.
/**
* Signup a User
* #param e
*/
function addUser(e) {
signupMessage.style.display = 'none';
signupMessage.className = '';
e.preventDefault();
let name = document.getElementById('name').value.trim();
let email = document.getElementById('signup-email').value.trim();
let password = document.getElementById('signup-password').value.trim();
if (name.length === 0 || email === 0 || password === 0) {
return;
}
let attributeList = [
new AWSCognito.CognitoIdentityServiceProvider.CognitoUserAttribute({
Name: 'given_name', Value: name
}),
];
userPool.signUp(email, password, attributeList, null, function (err, result) {
if (err) {
signupMessage.innerText = err;
signupMessage.style.display = 'block';
signupMessage.className = 'alert alert-danger';
return;
}
cognitoUser = result.user;
console.log('user name is ' + cognitoUser.getUsername());
// Show a text box to enter Confirmation code
document.getElementById('signup-btn').style.display = 'none';
document.getElementById('code-block').style.display = 'block';
document.getElementById('confirm-user-btn').style.display = 'inline-block';
});
}
If the signup is successful (It is valid Email and the Email does not yet exist in Userpools, a Confirmation code is sent to the Email provided. Next step is to, allow the user to enter the code and confirm his identity.
Step 3 - Confirm User
/**
* Confirm the user by taking the Confirmation code.
* #param e
*/
function confirmUser(e) {
e.preventDefault();
let verificationCode = document.getElementById('code').value;
cognitoUser.confirmRegistration(verificationCode, true, function (err, result) {
if (err) {
signupMessage.innerText = err;
signupMessage.style.display = 'block';
signupMessage.className = 'alert alert-danger';
return;
}
signupMessage.innerText = result;
signupMessage.style.display = 'block';
signupMessage.className = 'alert alert-success';
});
}
If the User enters correct code, his identity is confirmed. At this point, An entry is made to the Userpool for this user. It looks like this.
Step 4 - Authentication (Sign In)
At this point, User registration is done. Its time to allow him to login. Please ignore the unnecessary code in the code below (the code that fetches and prints credentials, decoding part). If the authentication is successful, Cognito returns two types of Tokens to the application - ID Token and Access Token. These are valid only for this session and for this user only. More details here - https://ryandam.net/aws/19-cognito-userpools/index.html#0
/**
* Signin user with Email and Password
* #param e
*/
function authenticateUser(e) {
e.preventDefault();
let email = document.getElementById('signin-email').value;
let password = document.getElementById('signin-password').value;
if (email.length === 0 || password === 0 || userPool === null || userPool === undefined) {
signinMessage.innerText = 'Fill in all fields!';
signinMessage.style.display = 'block';
signinMessage.className = 'alert alert-danger';
return;
}
let authenticationData = {
Username: email,
Password: password,
};
let authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);
let userData = {
Username: email,
Pool: userPool
};
let cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: function (result) {
signinMessage.innerText = 'Authentication Success!';
signinMessage.style.display = 'block';
signinMessage.className = 'alert alert-success';
document.getElementById('token-section').style.display = 'block';
document.getElementById('signin-btn').style.display = 'none';
// Decode ID Token
let idToken = result.idToken.jwtToken;
document.getElementById('id-token').innerText = idToken;
document.getElementById('decoded-id-token').appendChild(parseIdToken(idToken));
// Decode Access Token
let accessToken = result.getAccessToken().getJwtToken();
document.getElementById('access-token').innerText = accessToken;
document.getElementById('decoded-access-token').appendChild(parseAccessToken(accessToken));
let cognitoUser = userPool.getCurrentUser();
if (cognitoUser != null) {
cognitoUser.getSession(function (err, result) {
if (result) {
// Set the region where your identity pool exists (us-east-1, eu-west-1)
AWS.config.region = region;
AWS.config.update({region: region});
logins = {};
let key = 'cognito-idp.us-east-2.amazonaws.com/' + userPoolId;
logins[key] = result.getIdToken().getJwtToken();
// Add the User's Id Token to the Cognito credentials login map.
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: identityPoolId,
Logins: logins,
});
// Make the call to obtain credentials
AWS.config.credentials.get(function () {
// Credentials will be available when this function is called.
var accessKeyId = AWS.config.credentials.accessKeyId;
var secretAccessKey = AWS.config.credentials.secretAccessKey;
var sessionToken = AWS.config.credentials.sessionToken;
});
if (s3BucketName.length > 0)
listS3Bucket(s3BucketName);
}
});
}
},
onFailure: function (err) {
signinMessage.innerText = err;
signinMessage.style.display = 'block';
signinMessage.className = 'alert alert-danger';
}
}
);
}
Step 5 - Invoking the API Endpoint you already created - Since you've already created an Authorizer using the Userpool and you're using Authorization as the header, you can invoke the End point from JS by passing the ID token as Authorization header. What happens is that, the token is validated by the authorizer. Since it is valid the user is able to invoke the API.**
I do not have JS code, you can test your API from CLI/Postman something like this:
Note
AWS Amplify seems to be a wrapper for Cognito and other services. For instance, Amplify sets up User pool for you when you invoke its CLI commands. You can refer this code if you want to see how Amplify works with Flutter - https://github.com/ryandam9/Auth-flutter-aws-amplify.
I am still learning. I tried to be as accurate as possible.

Discord.js - How do you move a user that reacts to an embed?

I am new to Discord js and I am trying to make my bot move all users that react to an embed into a certain voice channel. Currently, it takes whoever wrote the message and moves them to the specified voice channel.I tried many combinations of user.id, guild.member, etc. What would I put before the .setVoiceChannel? I am confused as to what message.member is other than the person that wrote the message. Thank you!
collector.on('collect', (reaction, user) => {
if (reaction.emoji.name == reactionControls.VOID) {
const channel = message.guild.channels.find('name', 'Void 1');
message.member.setVoiceChannel(channel);
}
});
message.member does refer to the user who execute the command, if you want the member who reacted you will have to convert user using <GuildMember>.fetchMember, the only issue now is that the collect event doesn't give the parameter of user in v11.5.1 so you will need to just use collector.users.last() to get the last reactor
collector.on('collect', async (reaction) => {
if (reaction.emoji.name == reactionControls.VOID) {
const channel = message.guild.channels.find('name', 'Void 1');
const user = collector.users.last();
const member = await message.guild.fetchMember(user);
member.setVoiceChannel(channel);
}
});

Resources