Swift library to develop custom Alexa Skills

Overview

Swift + Docker

AlexaSkillsKit

Build Status

AlexaSkillsKit is a Swift library that allows you to develop custom skills for Amazon Alexa, the voice service that powers Echo. It takes care of parsing JSON requests from Amazon, generating the proper responses and providing convenience methods to handle all other features that Alexa offers.

AlexaSkillsKit has been inspired by alexa-app, SwiftOnLambda and alexa-skills-kit-java.

A sample project using AlexaSkillsKit can be found in the swift-lambda-app repo. This project also comes with a detailed description on how to deploy your custom skill. The article Building Alexa Skills in Swift contains a step-by-step introduction on how to use AlexaSkillsKit and swift-lambda-app to publish your own Alexa Skill.

It's early days – expect API changes until we reach 1.0!

Published Skills using AlexaSkillsKit

Music Charts (DE: Musikcharts) is a skill to get to know the most popular songs on Spotify and is published in the US, UK and DE skill stores.

Implementing a Custom Alexa Skill

Start with implementing the RequestHandler protocol. AlexaSkillsKit parses requests from Alexa and passes the data on to methods required by this protocol. For example, a launch request would result in AlexaSkillsKit calling the handleLaunch() method.

import Foundation
import AlexaSkillsKit

public class AlexaSkillHandler : RequestHandler {
    public init() {}
    
    public func handleLaunch(request: LaunchRequest, session: Session, next: @escaping (StandardResult) -> ()) {
        let standardResponse = generateResponse(message: "Alexa Skill received launch request")
        next(.success(standardResponse: standardResponse, sessionAttributes: session.attributes))
    }
    
    public func handleIntent(request: IntentRequest, session: Session, next: @escaping (StandardResult) -> ()) {
        let standardResponse = generateResponse(message: "Alexa Skill received intent \(request.intent.name)")
        next(.success(standardResponse: standardResponse, sessionAttributes: session.attributes))
    }
    
    public func handleSessionEnded(request: SessionEndedRequest, session: Session, next: @escaping (VoidResult) -> ()) {
        next(.success())
    }
    
    func generateResponse(message: String) -> StandardResponse {
        let outputSpeech = OutputSpeech.plain(text: message)
        return StandardResponse(outputSpeech: outputSpeech)
    }
}

In the request handler, your custom skill can implement any logic your skill requires. To enable asynchronous code (for example calling another HTTP service), the result is passed on via the next callback. next takes a enum that's either .success and contains an Alexa response or .failure in case a problem occurred.

Deployment

You can run your custom skill on AWS Lambda using an Alexa Skills Kit trigger as well as on any other Swift server environment via Alexa's HTTPS API. You can use the same RequestHandler code in both cases.

Using Lambda, Amazon will take care of scaling and running your Swift code. Lambda, however, doesn't support Swift executables natively thus you have to package your Swift executable and its dependencies so it can be executed as a Node.js Lambda function.

A stand-alone server allows you to use alternate cloud providers and run multiple skills on the same server using any Swift web framework such as Kitura, Vapor or Perfect. Even if you use Lambda for execution, configuring a server allows you to easily run and debug your custom skill in Xcode on a local computer.

A sample for a custom skill using both deployment methods is provided in the swift-lambda-app project. Please have a look at this sample for step-by-step instructions on how to do this.

Lambda

For Lambda, you need to create an executable that takes input from stdin and writes output to stdout. This can be done with the following code:

import Foundation
import AlexaSkillsKit
import AlexaSkill

do {
    let data = FileHandle.standardInput.readDataToEndOfFile()
    let requestDispatcher = RequestDispatcher(requestHandler: AlexaSkillHandler())
    let responseData = try requestDispatcher.dispatch(data: data)
    FileHandle.standardOutput.write(responseData)
} catch let error as MessageError {
    let data = error.message.data(using: .utf8) ?? Data()
    FileHandle.standardOutput.write(data)
}

In combination with a Node.js wrapper script that calls your Swift executable, this code can be uploaded to Lambda. See the sample project for more details.

Stand-Alone Server

Invocation of a RequestHandler as part of a Swift server is done via Amazon's HTTPS API where the Alexa service calls your server with a POST request. In the following code, Kitura is used as a web framework but any other web framework would work equally well:

import Foundation
import AlexaSkillsKit
import AlexaSkill
import Kitura

router.all("/") { request, response, next in
    var data = Data()
    let _ = try? request.read(into: &data)

    let requestDispatcher = RequestDispatcher(requestHandler: AlexaSkillHandler())
    requestDispatcher.dispatch(data: data) { result in
        switch result {
        case .success(let data):
            response.send(data: data).status(.OK)
        case .failure(let error):
            response.send(error.message).status(.badRequest)
        }
        
        next()
    }
}

Kitura.addHTTPServer(onPort: 8090, with: router)
Kitura.run()

Again, the sample project contains a detailed description on how to use a local HTTP server for developing your Alexa skill.

Also, you can use the same Swift server on a remote machine as the backend for your custom skill. Please check Amazon's additional requirements for this type of deployment.

Supported Features

Request Envelope

Feature Supported
version yes
session yes
context
request partially, see below

Requests

Feature Supported
LaunchRequest yes
IntentRequest yes
SessionEndedRequest yes
AudioPlayer Requests
PlaybackController Requests

Response Envelope

Feature Supported
version yes
sessionAttributes yes
response partially, see below

Response

Feature Supported
outputSpeech partially (plain yes, SSML no)
card yes
reprompt yes
directives
shouldEndSession yes

Other

Feature Supported
Request handler yes
Account Linking
Multiple Languages partially (locale attribute supported)
Response validation
Request verification (stand-alone server)
You might also like...
A Swift micro library for generating Sunrise and Sunset times.

Solar A Swift helper for generating Sunrise and Sunset times. Solar performs its calculations locally using an algorithm from the United States Naval

Plugin and runtime library for using protobuf with Swift

Swift Protobuf Welcome to Swift Protobuf! Apple's Swift programming language is a perfect complement to Google's Protocol Buffer ("protobuf") serializ

A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.
A Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and other native frameworks.

ZamzamKit ZamzamKit is a Swift package for rapid development using a collection of micro utility extensions for Standard Library, Foundation, and othe

noppefoxwolf/notion is a notion.so API library written in swift.
noppefoxwolf/notion is a notion.so API library written in swift.

notion noppefoxwolf/notion is a notion.so API library written in swift. Installation Xcode Project Swift Packages [email protected]:noppefoxwolf/notion

This library project contains a few noise generators created in Swift.

SwiftNoiseGenerator This library project contains a few noise generators created in Swift. contains: Perlin Noise Simplex Noise How to use Edit your P

Angle is a simple Swift library that provides Angle structure representing angles.

Angle is a simple Swift library that provides Angle structure representing angles. It handles angles using circular measure by default but is al

A library to manage NVRAM Stuff in Swift

libNVRAMSwift A Library to manage NVRAM Stuff, written in Swift. CLI Example utility here Library Usage Declare a new instance of the NVRAM Struct, fo

Support library of BudouX.swift to handle HTML

HTMLBudouX.swift HTMLBudouX.swift is a support library of BudouX.swift to handle HTML. Detail about BudouX.swift is here Usage You can translate an HT

A parser combinator library written in the Swift programming language.

SwiftParsec SwiftParsec is a Swift port of the Parsec parser combinator library. It allows the creation of sophisticated parsers from a set of simple

Comments
  • SSML and Swift 4 support

    SSML and Swift 4 support

    • Support for SSML - thanks to @shamanskyh
    • Added SSML test cases
    • Support for Swift 4 - fix for Issue #1 by removing the use of templates (workaround)
    opened by dsperling 0
  • Swift 4.x support

    Swift 4.x support

    I was attempting to compile this with Swift 4.0.3 and got a strange compiler error. No code changes were identified by the Swift conversion tool. Here is the updated Package.swift for 4.x:

    // swift-tools-version:4.0
    import PackageDescription
    
    let package = Package(
        name: "AlexaSkillsKit",
        targets: [
            .target(name: "AlexaSkillsKit", exclude: ["Samples"]),
            .testTarget(name: "AlexaSkillsKitTests", dependencies: ["AlexaSkillsKit"])
        ]
    )
    

    The compile error is the following after setting .swift-version to 4.0.3:

    ./build-linux.sh 
    Compile Swift Module 'AlexaSkillsKit' (8 sources)
    Compile Swift Module 'AlexaSkillsKitTests' (6 sources)
    /app/Tests/AlexaSkillsKitTests/RequestDispatcherTests.swift:12:80: error: extra argument 'sessionAttributes' in call
            next(.success(standardResponse: StandardResponse(), sessionAttributes: [String: Any]()))
                                                                                   ^~~~~~~~~~~~~~~
    /app/Tests/AlexaSkillsKitTests/RequestDispatcherTests.swift:17:80: error: extra argument 'sessionAttributes' in call
            next(.success(standardResponse: StandardResponse(), sessionAttributes: [String: Any]()))
                                                                                   ^~~~~~~~~~~~~~~
    /app/Tests/AlexaSkillsKitTests/RequestDispatcherTests.swift:22:23: error: missing argument for parameter #1 in call
            next(.success())
                          ^
                          <#T#>
    AlexaSkillsKit.Result:2:10: note: 'success' declared here
        case success(T)
             ^
    /app/Tests/AlexaSkillsKitTests/RequestHandlerTests.swift:7:80: error: extra argument 'sessionAttributes' in call
            next(.success(standardResponse: StandardResponse(), sessionAttributes: [:]))
                                                                                   ^~~
    /app/Tests/AlexaSkillsKitTests/RequestHandlerTests.swift:11:80: error: extra argument 'sessionAttributes' in call
            next(.success(standardResponse: StandardResponse(), sessionAttributes: [:]))
                                                                                   ^~~
    /app/Tests/AlexaSkillsKitTests/RequestHandlerTests.swift:15:23: error: missing argument for parameter #1 in call
            next(.success())
                          ^
                          <#T#>
    AlexaSkillsKit.Result:2:10: note: 'success' declared here
        case success(T)
             ^
    

    I have seen similar errors in Swift 2->3 ports, but it was always a type mis-match in the code. The code looks correct in this case.

    opened by dsperling 0
Releases(0.7.0)
Owner
Claus Höfele
Claus Höfele
BFKit-Swift is a collection of useful classes, structs and extensions to develop Apps faster.

Features • Classes and Extensions Compatibility • Requirements • Communication • Contributing • Installing and Usage • Documentation • Changelog • Exa

Fabrizio Brancati 992 Dec 2, 2022
LifetimeTracker can surface retain cycle / memory issues right as you develop your application

LifetimeTracker Bar style Circular style LifetimeTracker can surface retain cycle / memory issues right as you develop your application, and it will s

Krzysztof Zabłocki 2.8k Jan 4, 2023
BFKit is a collection of useful classes and categories to develop Apps faster.

Swift Version • What does it do • Language support • Requirements • Communication • Contributing • Installing and Usage • Documentation • Changelog •

Fabrizio Brancati 806 Dec 2, 2022
This is a Swift package with support for macOS that allows to start Java Jar's with the default or a custom JVM.

Jar.swift jar runner for macos Jar.swift is created and maintaned with ❥ by Sascha Muellner. What? This is a Swift package with support for macOS that

Swift Package Repository 1 Nov 11, 2021
Software Dummy Display Adapter for Apple Silicon Macs to Have Custom HiDPI Resolutions.

BetterDummy Dummy Display for Apple Silicon Macs to achieve custom resolutions. About M1 macs tend to have issues with custom resolutions. Notoriously

Istvan T. 8k Jan 9, 2023
Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. (Pure Swift, Supports Linux)

SwiftFoundation Cross-Platform, Protocol-Oriented Programming base library to complement the Swift Standard Library. Goals Provide a cross-platform in

null 620 Oct 11, 2022
swift-highlight a pure-Swift data structure library designed for server applications that need to store a lot of styled text

swift-highlight is a pure-Swift data structure library designed for server applications that need to store a lot of styled text. The Highlight module is memory-efficient and uses slab allocations and small-string optimizations to pack large amounts of styled text into a small amount of memory, while still supporting efficient traversal through the Sequence protocol.

kelvin 4 Aug 14, 2022
macOS system library in Swift

SystemKit A macOS system library in Swift based off of libtop, from Apple's top implementation. For an example usage of this library, see dshb, a macO

null 323 Jan 5, 2023
🏹 Bow is a cross-platform library for Typed Functional Programming in Swift

Bow is a cross-platform library for Typed Functional Programming in Swift. Documentation All documentation and API reference is published in our websi

Bow 613 Dec 20, 2022
Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos)

Focus Focus is an Optics library for Swift (where Optics includes Lens, Prisms, and Isos) that is inspired by Haskell's Lens library. Introduction Foc

TypeLift 201 Dec 31, 2022