HackMD
  • Prime
    Prime  Full-text search on all paid plans
    Search anywhere and reach everything in a Workspace with Prime plan.
    Got it
      • Create new note
      • Create a note from template
    • Prime  Full-text search on all paid plans
      Prime  Full-text search on all paid plans
      Search anywhere and reach everything in a Workspace with Prime plan.
      Got it
      • Sharing Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • More (Comment, Invitee)
      • Publishing
        Everyone on the web can find and read all notes of this public team.
        After the note is published, everyone on the web can find and read this note.
        See all published notes on profile page.
      • Commenting Enable
        Disabled Forbidden Owners Signed-in users Everyone
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Invitee
      • No invitee
      • Options
      • Versions and GitHub Sync
      • Transfer ownership
      • Delete this note
      • Template
      • Save as template
      • Insert from template
      • Export
      • Dropbox
      • Google Drive
      • Gist
      • Import
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
      • Download
      • Markdown
      • HTML
      • Raw HTML
    Menu Sharing Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Versions and GitHub Sync Transfer ownership Delete this note
    Export
    Dropbox Google Drive Gist
    Import
    Dropbox Google Drive Gist Clipboard
    Download
    Markdown HTML Raw HTML
    Back
    Sharing
    Sharing Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    More (Comment, Invitee)
    Publishing
    Everyone on the web can find and read all notes of this public team.
    After the note is published, everyone on the web can find and read this note.
    See all published notes on profile page.
    More (Comment, Invitee)
    Commenting Enable
    Disabled Forbidden Owners Signed-in users Everyone
    Permission
    Owners
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Invitee
    No invitee
       owned this note    owned this note      
    Published Linked with GitHub
    Like BookmarkBookmarked
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # System overview This work was done by Mike (Kae-Jer) Cho and Eric (Yen-Hao) Chen as part of a project advised by Andrea Cuadra. ![](https://i.imgur.com/AA54hAC.jpg) Our system contains several components: Interaction with users, Data persistence and exchange, Data processing for eRFA report generation. For interaction with users, we develop the Alexa Skill and deploy it to Alexa devices to ask questions and receive answers from users of the health questionnaires. For data persistence and exchange, we utilize several AWS products to fulfill our needs: AWS DynamoDB as the database to store user response, AWS Lambda and AWS API Gateway to implement and deploy the data polling API. For the last component in the system, we use Python with ReportLab toolkit to process user responses and generate eRFA pdf reports. # AWS ## ASK The Alexa Skills Kit (ASK) is a software development framework that enables developers to create content, called skills. Skills are applications within Amazon Alexa. With an interactive voice interface, Alexa gives users a hands-free way to interact with your skill. Users can use their voice to perform everyday tasks like checking the news, listening to music, or playing a game. Users can also use their voice to control cloud-connected devices. For example, users can ask Alexa to turn on lights or change the thermostat. Skills are available on Alexa-enabled devices, such as Amazon Echo and Amazon Fire TV, and on Alexa-enabled devices built by other manufacturers. We continue the previous Alexa Skill: Health questionnaire to develop new features for the data pipeline. Since the skill already has the basic function to ask questions and store the user responses in that interaction session, we leverage it to store the user response to the AWS Dynamo database. We designed a JSON format dictionary to persist the user response. At the beginning of the interaction session, we create an answer dictionary to store users' answers. We will keep updating this dictionary when the user answers different questions and saves this answer dictionary to the database simultaneously. With this design, we do not need to wait until the user finishes all questions to save their answers to the database. ## AWS DynamoDB Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It's a fully managed, multi-region, multi-active, durable database with built-in security, backup and restore, and in-memory caching for internet-scale applications. DynamoDB can handle more than 10 trillion requests per day and can support peaks of more than 20 million requests per second. ## AWS Lambda AWS Lambda is a serverless compute service that lets developers run code without provisioning or managing servers, creating workload-aware cluster scaling logic, maintaining event integrations, or managing runtimes. With Lambda, developers can run code for virtually any type of application or backend service - all with zero administration. ## AWS API GATEWAY The second step we did was implementing a REST API to help us polling data from the database. A REST API (also known as RESTful API) is an application programming interface (API or web API) that conforms to the constraints of REST architectural style and allows for interaction with RESTful web services. We simplified the functionality of our API in the system, only implementing the data polling feature without other complicated operations to the database. In general, it makes sense for a big system to build an API with a 24/7 non-stop server to keep the stability and with powerful hardware to make sure the speed of calculation. However, it takes extra cost to maintain a virtual server and needs much more effort to set the environment for the API. Instead, we choose to use the solution with AWS Lambda and Amazon API Gateway. As we mentioned before, Lambda provides a serverless environment meaning that we can focus on the feature development of our service without not taking care of the runtime environment. The Amazon API Gateway is a fully managed service that makes it easy for developers to create, publish, maintain, monitor, and secure APIs at any scale. APIs act as the "front door" for applications to access data, business logic, or functionality from the backend services. API Gateway supports containerized and serverless workloads, as well as web applications. We utilize this combination to create our data polling API with stability and sustainability. # Step by step Tutorial ### ASK Set up detail It is advised that each developer sets up their own developer console so that they can freely test their changes. IMPORTANT: Set up ALL AWS resources in the North Virginia Region or errors will occur. - To create your own dev console, make sure that you set up your own Amazon account - Create a new skill in the developer console using the custom template: https://developer.amazon.com/alexa/console/ask - Import the JSON Editor file (this is located in the "build" tab): eRFA_Care_Questionnaire > JsonEditor.json - Click Build Model - Replace the index.js file with the file at (this is located in the "code" tab): eRFA_Care_Questionnaire > lambda > index.js - Add "ask-sdk-dynamodb-persistence-adapter" to package.json as shown below: - ![](https://i.imgur.com/MWh07Yz.png) - Within the lambda folder, create a folder called "languages" and in it create a new file called "en-US.json", then copy the content of the en-US.json in this repo into it: eRFA_Care_Questionnaire > lambda > languages > en-US.json - Click Save and then Deploy - Click the Test tab, and enable testing by selecting Development on the dropdown menu at the top - Don't test your code yet, it will not run until you finish the guide. ### AWS permission Set up detail #### Set up permissions To enable your Alexa-hosted skill to use resources in your personal AWS account, create an AWS Identity and Access Management (IAM) role to allow access to the resource from your Alexa-hosted skill. For details about creating AWS IAM roles, see the AWS Identity and Access Management User Guide. #### To get your Alexa skill ARN 1. Open the Alexa developer console and log in. 1. In the console, open your Alexa-hosted skill. 1. In the code editor, click the icon for Link your personal AWS resources. 1. Copy the ARN. ![](https://i.imgur.com/54CLsD6.jpg) #### To create an AWS IAM role 1. Open the AWS management console and log in. 1. In the console, open the Identity and Access Management (IAM) dashboard. 1. In the IAM dashboard, click Roles. 1. On the Roles page, click Create role. 1. On the Create role page, under Select type of trusted entity, select AWS service. 1. In the Choose a use case section, under Common use cases, select one of the common use cases. -Or- Under Or select a service to view its use cases, select one of the services from the list, and then under select your use case, select a use case. For example, select DynamoDB from the list of services, and then select Amazon DynamoDB Accelerator (DAX) - DynamoDB access from the list of use cases. 1. Click Next: Permissions. 1. Choose one or more policies to attach to your new role, and then click Next: Tags. For example, select the AmazonDynamoDBFullAccess policy for full access to your DynamoDB table. 3. Click Next: Review, and enter the name and description of your role. 4. Click Create role. #### To add your Alexa skill ARN to the role 1. In the IAM dashboard, click Roles. 1. On the Roles page, click the name of the role you just created, and then click the Trust relationships tab. 1. Click Edit trust relationship. 1. Add an entry for the AWS Lambda Role Execution ARN from your Alexa-hosted skill to the Statement property and include the sts:AssumeRole action as shown in the following example. Don't overwrite other existing entries in the Statement property. ```json= { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"AWS": "<Replace with AWS Lambda Execution Role ARN from Alexa-hosted skill>"}, "Action": "sts:AssumeRole" } ] } ``` 5. Click Update Trust Policy. 6. Go to the index.js file in your Alexa Skill and replace all RoleArn instances to be equal to the ARN of your IAM role ![](https://i.imgur.com/sLPid8w.png) https://youtu.be/yZDzxB4IT90 {%youtube yZDzxB4IT90 %} ### Use personal AWS resources with Node.js In the code for your Alexa-hosted skill, assume the role by using the AWS Security Token Service (STS) API. For example, the following code requests temporary credentials of a role with AWS DynamoDB access, and scans the DynamoDB table. ```javascript= const AWS = require("aws-sdk"); const ShowUserMessageHandler = { //... Your canHandle function for intent ... async handle(handlerInput) { // 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: '<Your AWS resource role ARN>', RoleSessionName: 'ExampleSkillRoleSession' // You can rename with any name }, (err, res) => { if (err) { console.log('AssumeRole FAILED: ', err); throw new Error('Error while assuming role'); } return res; }).promise(); // 2. Make a new DynamoDB instance with the assumed role credentials // and scan the DynamoDB table const dynamoDB = new AWS.DynamoDB({ apiVersion: '2012-08-10', accessKeyId: credentials.Credentials.AccessKeyId, secretAccessKey: credentials.Credentials.SecretAccessKey, sessionToken: credentials.Credentials.SessionToken }); const tableData = await dynamoDB.scan({ TableName: 'TestTable' }, (err, data) => { if (err) { console.log('Scan FAILED', err); throw new Error('Error while scanning table'); } return data; }).promise(); // ... Use table data as required ... } }; ``` *https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-personal-aws.html* ### AWS DynamoDB Set up detail 1. Create table![](https://i.imgur.com/PrNPyie.jpg) 2. Use "userId" as primary key ![](https://i.imgur.com/YqsuQEd.jpg) and finish create table 3. Go to index.js file of Alexa Skill and set all "TableName: " instances to the name of your own DynamoDB Table. 4. More specifically, wherever 'ct-voice-survey' is found, replace with your own DynamoDB table name. *https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStartedDynamoDB.html* *https://developer.amazon.com/en-US/docs/alexa/hosted-skills/alexa-hosted-skills-session-persistence.html* ### AWS Lambda / API Gateway Set up detail 1. Create function with python 3.6 ![](https://i.imgur.com/y7YcukH.jpg) 2. Download data pipeline script zip file 3. Find DynamoDB table names in lambda_python script and change the names to the name of your DynamoDB table 4. Find S3 bucket name in lambda_python script and change to your own S3 bucket name 5. Upload edited data pipeline script zip file to lambda function ![](https://i.imgur.com/G0axXhi.jpg) 3. Add trigger with API gateway![](https://i.imgur.com/jF7gJUo.jpg) ![](https://i.imgur.com/DPDzmyW.jpg) 4. Click on "configuration" and click on the API Gateway you created. It should open a new tab. On this screen, click the "Actions" dropdown and click "Deploy API" to activate this API. 5. Get the API endpoint ![](https://i.imgur.com/cWJijly.jpg) 6. In httpGet function (line 758) of index.js Alexa Skill code, set "host: " and "path: " variables to your API endpoint 7. Test it with Postman,make sure to choose "POST", Body with "raw", and the amazonId that exists in database ![](https://i.imgur.com/GvXY9w7.jpg) 8. Find IAM role of this lambda function and give the role S3 access to your S3 bucket (to be created in the next section of guide). ### AWS S3 Set up detail *https://docs.aws.amazon.com/lambda/latest/dg/services-apigateway.html* 1. Create an S3 bucket 2. Under object ownership, allow ACLs # Python Script The last step of the data pipeline system is to process the user data and generate eRFA report. We use Python with an open-sourced document creation engine ReportLab to help to generate the file in PDF format. We follow the format of the eRFA report provided by Dr. Shahrokni, which gives us the report creation and data processing standard. For the data processing, we would get the data from the database and calculate the score of each question. Different scores will apply to different answers to the question. For example, for the Activities of Daily Living questions (ADL), we will give 2 points to the answer "not limited 1," point to "limited a little," and 0 to "limited a lot." After calculating all the answers, we can create an "Impairment Summary" table based on these scores as shown in Table1. This summary table presents the assessment result of the health questionnaire. In the report, we also provide detailed answers from the user of each question. Also, the script will send the report with Gmail api and save report in the S3 after generate the report, and then return the report file URL as the response of the api Please check the script named "lambda_function.py" for the code

    Import from clipboard

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lost their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template is not available.


    Upgrade

    All
    • All
    • Team
    No template found.

    Create custom template


    Upgrade

    Delete template

    Do you really want to delete this template?

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Tutorials

    Book Mode Tutorial

    Slide Mode Tutorial

    YAML Metadata

    Contacts

    Facebook

    Twitter

    Feedback

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions

    Versions and GitHub Sync

    Sign in to link this note to GitHub Learn more
    This note is not linked with GitHub Learn more
     
    Add badge Pull Push GitHub Link Settings
    Upgrade now

    Version named by    

    More Less
    • Edit
    • Delete

    Note content is identical to the latest version.
    Compare with
      Choose a version
      No search result
      Version not found

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub

        Please sign in to GitHub and install the HackMD app on your GitHub repo. Learn more

         Sign in to GitHub

        HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Available push count

        Upgrade

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Upgrade

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully