diff --git a/READMEs/Configure-Alexa-to-Email-User.md b/READMEs/Configure-Alexa-to-Email-User.md index dea93de..7a34bf6 100644 --- a/READMEs/Configure-Alexa-to-Email-User.md +++ b/READMEs/Configure-Alexa-to-Email-User.md @@ -1,39 +1,101 @@ +# Configure Alexa to send emails + ## [Back to Table of Contents](./Table-of-Contents.md) -sendSolutionToChallenegeEmail Feature +### User Story - Purpose of Component + +- As a user I would like to recieve emails from Alexa with solutions to the code challenge I am working on. +- As a user I would like to recieve emails from Alexa with a list of daily job postings. -### +### Resources used in building this -[To link external services to the alexa skill you must first follow this guide to setup IAM permissions](https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-personal-aws.html) +When you are creating your Alexa skill you can choose to self host or to have it "Alexa Hosted". In this application we selected "Alexa Hosted", which means she provisions certain resources that are managed by default. These services are: + - S3 + - DynamoDB + - Lambda + - Cloudwatch + +![Console](../img/alexa-hosted-resources.png) -[etting up the email params:](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/) +When you go to the "Code" section in your Alexa developer console these skills will be listed at the top. All of these are available to you without any setup, with the caviat that you are granted a static role that has limited permissions. That is why to setup SES (or any other service), we need to do some setup. Check out the resource links below for the steps to allow Alexa to connect with your AWS account. -[API reference for sending the email.](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/) +- [Linking other AWS resources](https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-personal-aws.html) -[Document 2:](https://pamphl3t.medium.com/send-a-email-from-your-alexa-with-aws-ses-176a81515680) +You will also need to configure your SES to verify an email for sending. -# Component Name +- [Setting up SES](https://docs.aws.amazon.com/ses/latest/dg/Welcome.html) -### User Story - Purpose of Component +- [A basic walkthrough for sending emails](https://pamphl3t.medium.com/send-a-email-from-your-alexa-with-aws-ses-176a81515680) -### Resources used in building this: -Main Resources -Additional Resources +And you will need to enable permissions in the build tab of your developer console. + +![Permissions](../img/alexa-permissions.png) ### Dependencies -### Intents Utterances +All you need is the AWS-SDK (which Alexa should have installed by default) + +## Relevant Code Snippets + +You need to grant alexa permissions to read the user email. We did this by putting the string in an array, so more permissions could be added if needed. + +```js + const PERMISSIONS = ['alexa::profile:email:read'] + ``` + +This is how you grab a user's email from the account. Keep in mind they must enable it in the alexa app in the skill settings. [Here is an article that walks you through how to do this](https://www.c-sharpcorner.com/article/getting-an-email-address-in-an-alexa-skill2/). + +```js + + const { serviceClientFactory, responseBuilder } = handlerInput + + try { + //* fetching the user's email from the account + const upsServiceClient = serviceClientFactory.getUpsServiceClient() + const profileEmail = await upsServiceClient.getProfileEmail() + //* if there is no profile with the associated account. + if (!profileEmail) { + const noEmailResponse = `It looks like you do not have an email set. You can set your email from the alexa companion app.` + return responseBuilder.speak(noEmailResponse).getResponse() + } +``` + +This is how Alexa assumes a temporary role that you set up in your IAMS following the "Linking other AWS resources" link. You will need this to utilize SES in any way. + +```js +const sts = new aws.STS({ apiVersion: '2011-06-15' }) -### Notable Code Block w/Code Description. -Link to .js file with comments for each section + const credentials = await sts + .assumeRole( + { + RoleArn: '', + RoleSessionName: 'SendEmailRoleSession' + }, + (err, res) => { + if (err) { + console.log('AssumeRole FAILED: ', err) + throw new Error('Error while assuming role') + } + return res + } + ) + .promise() +``` -screenshot of the code: +Once you have permissions, you can use SES to send an email with the credentials you just made. +```js + const ses = new aws.SES({ + apiVersion: '2010-12-01', + region: 'us-east-2', + accessKeyId: credentials.Credentials.AccessKeyId, + secretAccessKey: credentials.Credentials.SecretAccessKey, + sessionToken: credentials.Credentials.SessionToken + }) +``` -### Notable Bugs and Issues that occurred. -- Problem -- Solution +___ -### Testing +### Known bugs/issues -### Known bugs/issues \ No newline at end of file +None are known at the time of writing this. Make sure permissions are granted in your developer console. diff --git a/READMEs/Feature-Email-Code-Challenge-Solution.md b/READMEs/Feature-Email-Code-Challenge-Solution.md index 55fe67e..58c8cbb 100644 --- a/READMEs/Feature-Email-Code-Challenge-Solution.md +++ b/READMEs/Feature-Email-Code-Challenge-Solution.md @@ -1,27 +1,125 @@ -# Email Code Challenge Solution to User +# Email Code Challenge Solution ## [Back to Table of Contents](./Table-of-Contents.md) ### User Story - Purpose of Component -### Resources used in building this: +As a user I would like Alexa to give me the solution to the code challenge I completed. + +### Resources used in building this + Main Resources -Additional Resources + +[MAKE SURE YOU CONFIGURE YOUR ALEXA FIRST](./Configure-Alexa-to-Email-User.md) + +- [Linking other AWS resources](https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-personal-aws.html) +- [Setting up the email params](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/) +- [API reference for sending the email](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/) + +Additional Resources: ### Dependencies +- No dependencies required. + ### Intents Utterances -### Notable Code Block w/Code Description. -Link to .js file with comments for each section +- See: [Get a code challenge](./Feature-Get-Code-Challange.md) + +### Notable Code Block w/Code Description + +Most of this is the same as the [Email Job report](./Feature-Email-Jobs-Report.md). Modify it to your needs. The source code may look confusing because it is built around the functionality of the timer feature. + +```js +//* making the request to send an email with Alexa credentials + // 1. Assume the AWS resource role using STS AssumeRole Action + + const sts = new aws.STS({ apiVersion: '2011-06-15' }) + + const credentials = await sts + .assumeRole( + { + RoleArn: 'ALEXA ROLE ARN', + RoleSessionName: 'SendEmailRoleSession' + }, + (err, res) => { + if (err) { + console.log('AssumeRole FAILED: ', err) + throw new Error('Error while assuming role') + } + return res + } + ) + .promise() + + //* 2. Make a new SES object with the assumed role credentials + + //* create a new SES instance + const ses = new aws.SES({ + apiVersion: '2010-12-01', + region: 'us-east-1', + accessKeyId: credentials.Credentials.AccessKeyId, + secretAccessKey: credentials.Credentials.SecretAccessKey, + sessionToken: credentials.Credentials.SessionToken + }) + + //* async function to send the email and wait for a promise to be returned + /** + * + * @param {string} reciever The email address you want to recieve the data at + * @param {string} body The email body, the actual text inside the email. NOT HTML. //! Will be an object once feature is implemented. + * @param {string} subject The subject line of the email. + * @returns + */ + const sendEmail = async (reciever, body, subject) => { + let params = { + Destination: { + ToAddresses: [reciever] + }, + Message: { + Body: { + Html: { + Charset: 'UTF-8', + Data: `

Tech Prep!

+

Thank you for using our Alexa Skill!

+

Here is the code challenge that you attempted:

+ +
+

${body.chosenChallenge.description}

+ You can view the solution here +
` + } + }, + + Subject: { Data: subject } + }, + Source: 'YOUR SES VERIFIED EMAIL HERE' + } + + + return await ses.sendEmail(params).promise() + } + + //* send the email with the specified parameters + sendEmail(sessionAttributes.profileEmail, sessionAttributes, 'TechPrep Solution Code') + + return handlerInput.responseBuilder + .getResponse(); + + //! if there are improper permissions. Sometimes they can be switched off if the skill is rebuilt/redeployed. +``` -screenshot of the code: +### Notable Bugs and Issues that occurred +- Problem: Emails being recieved as undefined +- Solution: Make sure your data is passed into the sendEmail function correctly. -### Notable Bugs and Issues that occurred. -- Problem -- Solution +- Problem: Permissions issues +- Solution: + - 1. Make sure your ARN's are correct + - 2. Make sure your role is configured properly + - 3. Make sure your SES verified email is EXACTLY the same as it is in AWS. Even a capital letter will break it. -### Testing +### Known bugs/issues -### Known bugs/issues \ No newline at end of file +No known bugs at the time of writing this. Sometimes emails are sent to spam or junk. diff --git a/READMEs/Feature-Email-Jobs-Report b/READMEs/Feature-Email-Jobs-Report deleted file mode 100644 index b2575fe..0000000 --- a/READMEs/Feature-Email-Jobs-Report +++ /dev/null @@ -1,29 +0,0 @@ -# Component Name - -## [Back to Table of Contents](./Table-of-Contents.md) - -### User Story - Purpose of Component - -As a user I would like Alexa to give me a list of current jobs and email them to me. - -### Resources used in building this: -Main Resources -Additional Resources - -### Dependencies - -### Intents Utterances - -### Notable Code Block w/Code Description. -Link to .js file with comments for each section - -screenshot of the code: - - -### Notable Bugs and Issues that occurred. -- Problem -- Solution - -### Testing - -### Known bugs/issues \ No newline at end of file diff --git a/READMEs/Feature-Email-Jobs-Report.md b/READMEs/Feature-Email-Jobs-Report.md new file mode 100644 index 0000000..3467fcd --- /dev/null +++ b/READMEs/Feature-Email-Jobs-Report.md @@ -0,0 +1,165 @@ +# Email Jobs Report + +## [Back to Table of Contents](./Table-of-Contents.md) + +### User Story - Purpose of Component + +As a user I would like Alexa to give me a list of current jobs and email them to me. + +### Resources used in building this + +Main Resources + +[MAKE SURE YOU CONFIGURE YOUR ALEXA FIRST](./Configure-Alexa-to-Email-User.md) + +- [Linking other AWS resources](https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-personal-aws.html) +- [Setting up the email params](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/) +- [API reference for sending the email](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-send-email-ses/) + +Additional Resources + +### Dependencies + +- No dependencies required. + +### Intents Utterances + +- See: [Configuring the API for jobs](./Configure-API-for-Jobs.md) + +### Notable Code Block w/Code Description + +```js +// 1. Assume the role with STS +const sts = new aws.STS({ apiVersion: '2011-06-15' }) + const credentials = await sts + .assumeRole( + { + RoleArn: 'YOUR ALEXA ROLE ARN', + RoleSessionName: 'SendEmailRoleSession' + }, + (err, res) => { + if (err) { + console.log('AssumeRole FAILED: ', err) + throw new Error('Error while assuming role') + } + return res + } + ) + .promise() + // 2. Jobs are fetched + let response = await logic.fetchJobsApi() + addS3Object('dailyJobsReports', response.data) + let strings = '' + response.data.map((job, index) => { + if (index < 3) { + return (strings += `${job.employer_name} as a ${job.job_title}, `) + } + }) + // 3. Grabbing session storage to remember what jobs were fetched + const sessionAttributes = handlerInput.attributesManager.getSessionAttributes() + + // 4. Grabbing email from Alexa users account + const { serviceClientFactory, responseBuilder } = handlerInput + + + try { + //* fetching the user's email from the account + const upsServiceClient = serviceClientFactory.getUpsServiceClient() + const profileEmail = await upsServiceClient.getProfileEmail() + //* if there is no profile with the associated account. + if (!profileEmail) { + const noEmailResponse = `It looks like you do not have an email set. You can set your email from the alexa companion app.` + return responseBuilder.speak(noEmailResponse).getResponse() + } + + //* 5. Make a new SES object with the assumed role credentials + + //* create a new SES instance + const ses = new aws.SES({ + apiVersion: '2010-12-01', + region: 'us-east-2', + accessKeyId: credentials.Credentials.AccessKeyId, + secretAccessKey: credentials.Credentials.SecretAccessKey, + sessionToken: credentials.Credentials.SessionToken + }) + + //* async function to send the email and wait for a promise to be returned + /** + * @param {string} reciever The email address you want to recieve the data at + * @param {string} body The email body, the actual text inside the email. NOT HTML. //! Will be an object once feature is implemented. + * @param {string} subject The subject line of the email. + * @returns + */ + const sendEmail = async (reciever, body, subject) => { + let params = { + Destination: { + ToAddresses: [reciever] + }, + Message: { + Body: { + Html: { + Charset: 'UTF-8', + Data: `

Tech Prep!

+

Thank you for using our Alexa Skill!

+

Here are the job postings that you requested:

+ ${body.map(job => { + return `` + })} + ` + } + }, + + Subject: { Data: subject } + }, + Source: 'YOUR SES VERIFIED EMAIL' + } + + return await ses.sendEmail(params).promise() + } + + //* send the email with the specified parameters + sendEmail(profileEmail, response.data, 'Job Listings from TechPrep') + + //! if there are improper permissions. Sometimes they can be switched off if the skill is rebuilt/redeployed. + } catch (error) { + console.log( + JSON.stringify('403 *******************************************', error) + ) + if (error.statusCode === 403) { + return responseBuilder + .speak(messages.NOTIFY_MISSING_PERMISSIONS) + .withAskForPermissionsConsentCard(PERMISSIONS) + .getResponse() + } + console.log(JSON.stringify(error)) + const response = responseBuilder.speak(messages.ERROR).getResponse() + return response + } + + let speakOutput = ` I found a list of jobs for you, here are the first three, ${strings} I emailed you the full list of jobs. ` + + return handlerInput.responseBuilder + .speak(speakOutput) + .reprompt() + .getResponse() +``` + +### Notable Bugs and Issues that occurred + +- Problem: Emails being recieved as undefined +- Solution: Make sure your job data is passed into the sendEmail function correctly. + +- Problem: Permissions issues +- Solution: + - 1. Make sure your ARN's are correct + - 2. Make sure your role is configured properly + - 3. Make sure your SES verified email is EXACTLY the same as it is in AWS. Even a capital letter will break it. + +### Known bugs/issues + +No known bugs at the time of writing this. Sometimes emails are sent to spam or junk. \ No newline at end of file diff --git a/Tech-Prep-Skill/interactionModels/custom/en-US.json b/Tech-Prep-Skill/interactionModels/custom/en-US.json new file mode 100644 index 0000000..1beba7c --- /dev/null +++ b/Tech-Prep-Skill/interactionModels/custom/en-US.json @@ -0,0 +1,141 @@ +{ + "interactionModel": { + "languageModel": { + "invocationName": "tech prep", + "intents": [ + { + "name": "AMAZON.CancelIntent", + "samples": [] + }, + { + "name": "AMAZON.HelpIntent", + "samples": [] + }, + { + "name": "AMAZON.StopIntent", + "samples": [] + }, + { + "name": "GetChallengeIntent", + "slots": [], + "samples": [ + "code problem", + "coding problem", + "code challenge", + "coding challenge", + "code", + "coding", + "code practice", + "coding practice", + "a challenge", + "technical question", + "let\u0027s do a code challenge", + "give me a code challenge", + "skip", + "skip challenge", + "next code challenge", + "next challenge" + ] + }, + { + "name": "AMAZON.NavigateHomeIntent", + "samples": [] + }, + { + "name": "AMAZON.FallbackIntent", + "samples": [] + }, + { + "name": "AMAZON.RepeatIntent", + "samples": [ + "repeat code problem", + "tell me the code problem", + "what was that code problem", + "give me the code problem again", + "repeat the code problem", + "repeat problem", + "code challenge again", + "tell me the code challenge", + "what was that code challenge", + "give me the code challenge again", + "repeat code challenge", + "repeat that", + "tell me again", + "what", + "repeat challenge", + "I didn\u0027t hear that", + "I did not get that", + "I did not hear that", + "i didn\u0027t get that", + "what was that", + "say that again", + "repeat" + ] + }, + { + "name": "GetHintIntent", + "slots": [], + "samples": [ + "hint me", + "give a hint", + "tell me a hint", + "hints", + "any hints", + "Can I have a hint", + "hint please", + "hint", + "give me a hint" + ] + }, + { + "name": "GetQuestionIntent", + "slots": [], + "samples": [ + "next question", + "get interview question", + "give interview question", + "get interview", + "give interview", + "id like to be interviewed", + "ask me an interview question", + "interview", + "interview me" + ] + }, + { + "name": "AMAZON.YesIntent", + "samples": [ + "yes please", + "sure", + "yeah", + "yes" + ] + }, + { + "name": "AMAZON.NoIntent", + "samples": [ + "no way", + "nah", + "no thanks", + "no" + ] + }, + { + "name": "FetchJobsIntent", + "slots": [], + "samples": [ + "positions", + "jobs", + "search job postings", + "search job listings", + "job", + "find me a job", + "find job listings" + ] + } + ], + "types": [] + } + }, + "version": "9" +} \ No newline at end of file diff --git a/ConnectionsResponseHandler.js b/Tech-Prep-Skill/lambda/ConnectionsResponseHandler.js similarity index 98% rename from ConnectionsResponseHandler.js rename to Tech-Prep-Skill/lambda/ConnectionsResponseHandler.js index a56be47..b1066a0 100644 --- a/ConnectionsResponseHandler.js +++ b/Tech-Prep-Skill/lambda/ConnectionsResponseHandler.js @@ -48,4 +48,4 @@ const ConnectionsResponseHandler = { } }; -module.exports = ConnectionsResponseHandler; +module.exports = ConnectionsResponseHandler; \ No newline at end of file diff --git a/challenges.json b/Tech-Prep-Skill/lambda/challenges.json similarity index 99% rename from challenges.json rename to Tech-Prep-Skill/lambda/challenges.json index f0794a9..2dd52ad 100644 --- a/challenges.json +++ b/Tech-Prep-Skill/lambda/challenges.json @@ -39,4 +39,4 @@ "hints": ["You can take an iterative approach or a recursive approach.", "Consider a counter variable to help you keep count."], "solution": "https://www.geeksforgeeks.org/find-length-of-a-linked-list-iterative-and-recursive/?ref=lbp" } -] +] \ No newline at end of file diff --git a/base.index.js b/Tech-Prep-Skill/lambda/index.js similarity index 99% rename from base.index.js rename to Tech-Prep-Skill/lambda/index.js index cff78e0..0f73372 100644 --- a/base.index.js +++ b/Tech-Prep-Skill/lambda/index.js @@ -90,7 +90,7 @@ const FetchJobsIntentHandler = { const credentials = await sts .assumeRole( { - RoleArn: 'arn:aws:iam::948331367146:role/AlexaX', + RoleArn: 'YOUR ARN', RoleSessionName: 'SendEmailRoleSession' }, (err, res) => { @@ -247,7 +247,7 @@ const EmailIntentHandler = { const credentials = await sts .assumeRole( { - RoleArn: 'arn:aws:iam::948331367146:role/Alexa', + RoleArn: 'YOUR ARN', RoleSessionName: 'SendEmailRoleSession' }, (err, res) => { @@ -490,7 +490,7 @@ const GetChallengeIntentHandler = { const credentials = await sts .assumeRole( { - RoleArn: 'arn:aws:iam::143451010179:role/Alexa', + RoleArn: 'YOUR ARN', RoleSessionName: 'SendEmailRoleSession' }, (err, res) => { @@ -799,4 +799,4 @@ exports.handler = Alexa.SkillBuilders.custom() ) .addErrorHandlers(ErrorHandler) .withApiClient(new Alexa.DefaultApiClient()) - .lambda() \ No newline at end of file + .lambda() diff --git a/Tech-Prep-Skill/lambda/local-debugger.js b/Tech-Prep-Skill/lambda/local-debugger.js new file mode 100644 index 0000000..005d3de --- /dev/null +++ b/Tech-Prep-Skill/lambda/local-debugger.js @@ -0,0 +1,135 @@ +/* + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +/* ## DEPRECATION NOTICE + +This script has been deprecated and is no longer supported. +Please use the [ASK Toolkit for VS Code] +(https://marketplace.visualstudio.com/items?itemName=ask-toolkit.alexa-skills-kit-toolkit), +which provides a more end-to-end integration with Visual Studio Code. If you +use another editor/IDE, please check out the [ASK SDK Local Debug package at npm] +(https://www.npmjs.com/package/ask-sdk-local-debug). + +*/ + +const net = require('net'); +const fs = require('fs'); + +const localDebugger = net.createServer(); + +const httpHeaderDelimeter = '\r\n'; +const httpBodyDelimeter = '\r\n\r\n'; +const defaultHandlerName = 'handler'; +const host = 'localhost'; +const defaultPort = 0; + +/** + * Resolves the skill invoker class dependency from the user provided + * skill entry file. + */ + +// eslint-disable-next-line import/no-dynamic-require +const skillInvoker = require(getAndValidateSkillInvokerFile()); +const portNumber = getAndValidatePortNumber(); +const lambdaHandlerName = getLambdaHandlerName(); + +/** + * Starts listening on the port for incoming skill requests. + */ + +localDebugger.listen(portNumber, host, () => { + console.log(`Starting server on port: ${localDebugger.address().port}.`); +}); + +/** + * For a new incoming skill request a new socket connection is established. + * From the data received on the socket the request body is extracted, parsed into + * JSON and passed to the skill invoker's lambda handler. + * The response from the lambda handler is parsed as a HTTP 200 message format as specified + * here - https://developer.amazon.com/docs/custom-skills/request-and-response-json-reference.html#http-header-1 + * The response is written onto the socket connection. + */ + +localDebugger.on('connection', (socket) => { + console.log(`Connection from: ${socket.remoteAddress}:${socket.remotePort}`); + socket.on('data', (data) => { + const body = JSON.parse(data.toString().split(httpBodyDelimeter).pop()); + console.log(`Request envelope: ${JSON.stringify(body)}`); + skillInvoker[lambdaHandlerName](body, null, (_invokeErr, response) => { + response = JSON.stringify(response); + console.log(`Response envelope: ${response}`); + socket.write(`HTTP/1.1 200 OK${httpHeaderDelimeter}Content-Type: application/json;charset=UTF-8${httpHeaderDelimeter}Content-Length: ${response.length}${httpBodyDelimeter}${response}`); + }); + }); +}); + +/** + * Validates user specified port number is in legal range [0, 65535]. + * Defaults to 0. + */ + +function getAndValidatePortNumber() { + const portNumberArgument = Number(getArgument('portNumber', defaultPort)); + if (!Number.isInteger(portNumberArgument)) { + throw new Error(`Port number has to be an integer - ${portNumberArgument}.`); + } + if (portNumberArgument < 0 || portNumberArgument > 65535) { + throw new Error(`Port out of legal range: ${portNumberArgument}. The port number should be in the range [0, 65535]`); + } + if (portNumberArgument === 0) { + console.log('The TCP server will listen on a port that is free.' + + 'Check logs to find out what port number is being used'); + } + return portNumberArgument; +} + +/** + * Gets the lambda handler name. + * Defaults to "handler". + */ + +function getLambdaHandlerName() { + return getArgument('lambdaHandler', defaultHandlerName); +} + +/** + * Validates that the skill entry file exists on the path specified. + * This is a required field. + */ + +// eslint-disable-next-line consistent-return +function getAndValidateSkillInvokerFile() { + const fileNameArgument = getArgument('skillEntryFile'); + if (!fs.existsSync(fileNameArgument)) { + throw new Error(`File not found: ${fileNameArgument}`); + } + return fileNameArgument; +} + +/** + * Helper function to fetch the value for a given argument + * @param {argumentName} argumentName name of the argument for which the value needs to be fetched + * @param {defaultValue} defaultValue default value of the argument that is returned if the value doesn't exist + */ + +function getArgument(argumentName, defaultValue) { + const index = process.argv.indexOf(`--${argumentName}`); + if (index === -1 || typeof process.argv[index + 1] === 'undefined') { + if (defaultValue === undefined) { + throw new Error(`Required argument - ${argumentName} not provided.`); + } else { + return defaultValue; + } + } + return process.argv[index + 1]; +} diff --git a/logic.js b/Tech-Prep-Skill/lambda/logic.js similarity index 93% rename from logic.js rename to Tech-Prep-Skill/lambda/logic.js index ef007b4..b4fb857 100644 --- a/logic.js +++ b/Tech-Prep-Skill/lambda/logic.js @@ -12,7 +12,7 @@ const options = { num_pages: '1' }, headers: { - 'X-RapidAPI-Key': '', + 'X-RapidAPI-Key': 'YOUR API KEY', 'X-RapidAPI-Host': 'jsearch.p.rapidapi.com' } }; diff --git a/package.json b/Tech-Prep-Skill/lambda/package.json similarity index 81% rename from package.json rename to Tech-Prep-Skill/lambda/package.json index df7445e..9e259ca 100644 --- a/package.json +++ b/Tech-Prep-Skill/lambda/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "author": "KC Hofstetter, Stephen Clemmer, Brandon Pitts, Jack Stubblefield and Xavier Hillman", + "author": "Amazon Alexa", "license": "Apache License", "dependencies": { "ask-sdk-core": "^2.7.0", @@ -16,4 +16,4 @@ "node-fetch": "2.6.7", "axios": "^1.1.3" } -} +} \ No newline at end of file diff --git a/Tech-Prep-Skill/lambda/questions.json b/Tech-Prep-Skill/lambda/questions.json new file mode 100644 index 0000000..6c96202 --- /dev/null +++ b/Tech-Prep-Skill/lambda/questions.json @@ -0,0 +1,13 @@ +["Tell me about a time when you had to work closely with someone whose personality was very different from yours.", + "Give me an example of a time you faced a conflict with a coworker. How did you handle that?", + "Describe a time when you had to step up and demonstrate leadership skills.", + "Give me an example of a time when you didn’t meet a client’s expectation. What happened, and how did you attempt to rectify the situation?", + "When you’re working with a large number of customers, it’s tricky to deliver excellent service to them all. How do you go about prioritizing your customers’ needs?", + "Tell me about settling into your last job. What did you do to learn the ropes?", + "Tell me about a time you failed. How did you deal with the situation?", + "Tell me about a time you set a goal for yourself. How did you go about ensuring that you would meet your objective?", + "Describe a long-term project that you kept on track. How did you keep everything moving?", + "Give me an example of a time when you were able to successfully persuade someone at work to see things your way.", + "Tell me about a successful presentation you gave and why you think it was a hit.", + "Describe a time when you saw a problem and took the initiative to correct it.", + "Tell me about a time you were dissatisfied in your role. What could have been done to make it better?"] \ No newline at end of file diff --git a/s3.js b/Tech-Prep-Skill/lambda/s3.js similarity index 100% rename from s3.js rename to Tech-Prep-Skill/lambda/s3.js diff --git a/timerPayload.js b/Tech-Prep-Skill/lambda/timerPayload.js similarity index 100% rename from timerPayload.js rename to Tech-Prep-Skill/lambda/timerPayload.js diff --git a/util.js b/Tech-Prep-Skill/lambda/util.js similarity index 100% rename from util.js rename to Tech-Prep-Skill/lambda/util.js diff --git a/Tech-Prep-Skill/skill.json b/Tech-Prep-Skill/skill.json new file mode 100644 index 0000000..3549bbd --- /dev/null +++ b/Tech-Prep-Skill/skill.json @@ -0,0 +1,56 @@ +{ + "manifest": { + "apis": { + "custom": { + "endpoint": { + "uri": "arn:aws:lambda:us-east-1:884399042415:function:14e99778-a6d9-4635-ba05-223cb8536b8f:Release_0" + }, + "interfaces": [], + "regions": { + "EU": { + "endpoint": { + "uri": "arn:aws:lambda:eu-west-1:884399042415:function:14e99778-a6d9-4635-ba05-223cb8536b8f:Release_0" + } + }, + "NA": { + "endpoint": { + "uri": "arn:aws:lambda:us-east-1:884399042415:function:14e99778-a6d9-4635-ba05-223cb8536b8f:Release_0" + } + }, + "FE": { + "endpoint": { + "uri": "arn:aws:lambda:us-west-2:884399042415:function:14e99778-a6d9-4635-ba05-223cb8536b8f:Release_0" + } + } + } + } + }, + "manifestVersion": "1.0", + "permissions": [ + { + "name": "alexa::profile:email:read" + }, + { + "name": "alexa::alerts:timers:skill:readwrite" + } + ], + "publishingInformation": { + "distributionCountries": [], + "isAvailableWorldwide": true, + "locales": { + "en-US": { + "description": "Sample Full Description", + "examplePhrases": [ + "Alexa open hello world", + "hello", + "help" + ], + "keywords": [], + "name": "TechPrep", + "summary": "Sample Short Description" + } + }, + "testingInstructions": "Sample Testing Instructions." + } + } +} \ No newline at end of file diff --git a/img/alexa-hosted-resources.png b/img/alexa-hosted-resources.png new file mode 100644 index 0000000..ac7eb5c Binary files /dev/null and b/img/alexa-hosted-resources.png differ diff --git a/img/alexa-permissions.png b/img/alexa-permissions.png new file mode 100644 index 0000000..336e207 Binary files /dev/null and b/img/alexa-permissions.png differ diff --git a/questions.json b/questions.json deleted file mode 100644 index 8f75524..0000000 --- a/questions.json +++ /dev/null @@ -1,13 +0,0 @@ -["Tell me about a time when you had to work closely with someone whose personality was very different from yours.", - "Give me an example of a time you faced a conflict with a coworker. How did you handle that?", - "Describe a time when you had to step up and demonstrate leadership skills.", - "Give me an example of a time when you didn’t meet a client’s expectation. What happened, and how did you attempt to rectify the situation?", - "When you’re working with a large number of customers, it’s tricky to deliver excellent service to them all. How do you go about prioritizing your customers’ needs?", - "Tell me about settling into your last job. What did you do to learn the ropes?", - "Tell me about a time you failed. How did you deal with the situation?", - "Tell me about a time you set a goal for yourself. How did you go about ensuring that you would meet your objective?", - "Describe a long-term project that you kept on track. How did you keep everything moving?", - "Give me an example of a time when you were able to successfully persuade someone at work to see things your way.", - "Tell me about a successful presentation you gave and why you think it was a hit.", - "Describe a time when you saw a problem and took the initiative to correct it.", - "Tell me about a time you were dissatisfied in your role. What could have been done to make it better?"] \ No newline at end of file