### Setup Webhook HTTP Server with Ktor (Kotlin) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Sets up an embedded Netty HTTP server using Ktor to receive requests from the Yandex Alice platform. It maps the root path to the AliceChannel adapter, which processes incoming interactions. Configuration, including the port and OAuth token, is handled via environment variables for portability. ```kotlin package com.justai.jaicf.template import com.justai.jaicf.channel.http.httpBotRouting import com.justai.jaicf.channel.yandexalice.AliceChannel import io.ktor.routing.routing import io.ktor.server.engine.embeddedServer import io.ktor.server.netty.Netty fun main() { // Start Ktor server on specified port (defaults to 8080) embeddedServer(Netty, System.getenv("PORT")?.toInt() ?: 8080) { routing { // Map root path to Alice channel with OAuth token httpBotRouting("/" to AliceChannel( skill, System.getenv("OAUTH_TOKEN") ?: "OR PLACE YOUR OAUTH TOKEN HERE" )) } }.start(wait = true) } // Usage: Set environment variables and run // PORT=8080 OAUTH_TOKEN=your_token_here ./gradlew run // Expected output: Server starts and listens on specified port // Webhook endpoint available at: http://localhost:8080/ ``` -------------------------------- ### Initialize BotEngine with Context Management (Kotlin) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Initializes the JAICF BotEngine with pluggable context managers and activators. It prioritizes MongoDB for persistence if the MONGODB_URI environment variable is set, otherwise, it defaults to in-memory storage for local development. This setup orchestrates conversation flows using multiple activation strategies. ```kotlin package com.justai.jaicf.template import com.justai.jaicf.BotEngine import com.justai.jaicf.activator.catchall.CatchAllActivator import com.justai.jaicf.activator.event.BaseEventActivator import com.justai.jaicf.activator.regex.RegexActivator import com.justai.jaicf.context.manager.InMemoryBotContextManager import com.justai.jaicf.context.manager.mongo.MongoBotContextManager import com.justai.jaicf.template.scenario.MainScenario import com.mongodb.client.MongoClients // Initialize context manager with MongoDB if MONGODB_URI is set, otherwise use in-memory private val contextManager = System.getenv("MONGODB_URI")?.let { url -> val client = MongoClients.create(url) MongoBotContextManager(client.getDatabase("jaicf").getCollection("contexts")) } ?: InMemoryBotContextManager // Create bot engine with scenario and activators val skill = BotEngine( scenario = MainScenario, defaultContextManager = contextManager, activators = arrayOf( RegexActivator, // Matches user input against regex patterns BaseEventActivator, // Handles platform events (START, etc.) CatchAllActivator // Fallback for unmatched input ) ) // Expected output: BotEngine instance ready to process Alice requests // Context persisted in MongoDB if URL provided, otherwise in-memory ``` -------------------------------- ### Local Development Setup (Bash) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Provides bash commands for setting up a local development environment using Heroku CLI and ngrok. This includes cloning the Heroku app, pulling template updates, setting environment variables, running the Gradle application, and exposing the local server via ngrok for live testing with Yandex Alice. ```bash # Clone your Heroku app heroku login heroku git:clone -a my-alice-skill cd my-alice-skill # Add template as remote and pull latest git remote add origin https://github.com/just-ai/alice-jaicf-template git pull origin master # Set up environment variables for local development export OAUTH_TOKEN=your_oauth_token_here export PORT=8080 # Run locally (opens port 8080) ./gradlew run # In another terminal, expose local server via ngrok ngrok http 8080 # Output from ngrok: # Forwarding https://abc123.ngrok.io -> http://localhost:8080 # Update webhook URL in Yandex Dialogs to: https://abc123.ngrok.io/ # Now all Alice requests route to your local machine for debugging # Deploy updates to Heroku: git add . git commit -am "Updated conversation flow" git push heroku master # Heroku automatically rebuilds and deploys ``` -------------------------------- ### Main Conversation Scenario with State Management (Kotlin) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Defines the main conversation flow using a state machine pattern for the Alice skill. It handles skill start, user responses, multi-turn dialogs, and rich responses like buttons and images. Includes session management and a fallback for unrecognized input. ```kotlin package com.justai.jaicf.template.scenario import com.justai.jaicf.builder.Scenario import com.justai.jaicf.channel.yandexalice.model.AliceEvent import com.justai.jaicf.channel.yandexalice.alice val MainScenario = Scenario { append(RecordScenario) // Include modal record scenario // Initial state triggered when skill starts state("main") { activators { event(AliceEvent.START) } action { reactions.run { say("Управдом слушает. Вы хотите сообщить ваши показания счетчиков?") buttons("Да", "Нет") alice?.image( "https://i.imgur.com/SUSGpqG.jpg", "Управдом слушает", "Хотите сообщить ваши показания счетчиков?" ) } } } // User confirms they want to report readings state("yes") { activators { regex("да|хочу") // Matches "yes" or "want" in Russian } action { record("Сколько вы потратили холодной воды?", "warm") } // Nested state for hot water reading state("warm") { action { record("Сколько ушло горячей?", "done") } // Final state after both readings collected state("done") { action { reactions.say("Записала ваши показания. Ждите квитанцию на оплату.") reactions.alice?.endSession() // Close Alice session } } } } // User declines to report readings state("no") { activators { regex("нет|не хочу") // Matches "no" or "don't want" in Russian } action { reactions.say("Тогда не отвлекайте меня от работы. До свидания!") reactions.alice?.endSession() } } // Fallback for unrecognized input fallback { reactions.say("Не тратьте мое время зря. Вы хотите сообщить показания счетчиков?") reactions.buttons("Да", "Нет") } } // Example conversation flow: // User: "Алиса, запусти управдома" // Alice: "Управдом слушает. Вы хотите сообщить ваши показания счетчиков?" [Shows image and buttons] // User: "Да" // Alice: "Сколько вы потратили холодной воды?" // User: "50 кубометров" // Alice: "Сколько ушло горячей?" // User: "30" // Alice: "Записала ваши показания. Ждите квитанцию на оплату." [Session ends] ``` -------------------------------- ### Gradle Build Configuration (Kotlin DSL) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Configures the JAICF framework, Ktor server, MongoDB, and logging using Kotlin DSL for Gradle. It includes the Shadow plugin to create a fat JAR with all dependencies, suitable for deployment. The output is a self-contained JAR file. ```kotlin // build.gradle.kts plugins { application kotlin("jvm") version "1.3.61" id("com.github.johnrengelman.shadow") version "5.0.0" } group = "com.justai.jaicf" version = "1.0.0" val jaicf = "1.2.0" val slf4j = "1.7.30" val ktor = "1.5.1" application { mainClassName = "com.justai.jaicf.template.WebhookKt" } repositories { mavenLocal() mavenCentral() jcenter() } dependencies { implementation(kotlin("stdlib-jdk8")) // Logging implementation("org.slf4j:slf4j-simple:$slf4j") implementation("org.slf4j:slf4j-log4j12:$slf4j") // JAICF framework with Alice channel and MongoDB support implementation("com.just-ai.jaicf:core:$jaicf") implementation("com.just-ai.jaicf:yandex-alice:$jaicf") implementation("com.just-ai.jaicf:mongo:$jaicf") // Ktor HTTP server implementation("io.ktor:ktor-server-netty:$ktor") } tasks { compileKotlin { kotlinOptions.jvmTarget = "1.8" } compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } } tasks.withType { manifest { attributes( mapOf("Main-Class" to application.mainClassName) ) } } // Heroku deployment task tasks.create("stage") { dependsOn("shadowJar") } // Build commands: // ./gradlew build # Compile and build project // ./gradlew shadowJar # Create fat JAR with dependencies // ./gradlew run # Run locally // // Output: build/libs/alice-jaicf-template-1.0.0-all.jar ``` -------------------------------- ### Heroku Deployment Manifest (JSON) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Defines the Heroku deployment configuration for one-click deployment. It specifies the application name, description, repository, logo, buildpack, addons (like mongolab:sandbox), and environment variables such as OAUTH_TOKEN. ```json { "name": "Шаблон навыка Алисы на JAICF", "description": "Вебхук навыка для Яндекс Алисы, разработанный на фреймворке JAICF", "repository": "https://github.com/just-ai/alice-jaicf-template", "logo": "https://framework.just-ai.com/images/favicons/mstile-150x150.png", "image": "heroku/java", "addons": ["mongolab:sandbox"], "env": { "OAUTH_TOKEN": { "description": "Ваш OAuth токен, необходим для автоматической загрузки картинок" } } } ``` -------------------------------- ### Modal Record Scenario with Input Validation (Kotlin) Source: https://context7.com/just-ai/alice-jaicf-template/llms.txt Implements a reusable modal dialog for collecting numeric data with input validation. It uses regex to check input and handles errors with randomized prompts. Designed to be invoked from other states and automatically returns to the calling context. ```kotlin package com.justai.jaicf.template.scenario import com.justai.jaicf.builder.Scenario import com.justai.jaicf.context.ActionContext import com.justai.jaicf.context.DefaultActionContext import com.justai.jaicf.model.scenario.Scenario val RecordScenario = Scenario { // Modal state that intercepts all input until completed state("record", modal = true) { // Validates numeric input state("data") { activators { regex("\\d+.*") // Matches any string starting with digits } action { reactions.goBack() // Return to calling state } } // Handles invalid input fallback { reactions.sayRandom("Сколько-сколько?", "Повторите еще раз") } } } // Extension function to invoke record dialog from any context fun DefaultActionContext.record(message: String, callback: String) { reactions.say(message) // Ask the question reactions.changeState("/record", callback) // Enter modal, return to callback } // Usage example from MainScenario: // record("Сколько вы потратили холодной воды?", "warm") // // Flow: // 1. Asks question: "Сколько вы потратили холодной воды?" // 2. Enters modal /record state // 3. User input "abc" -> "Сколько-сколько?" (fallback) // 4. User input "50" -> Matches regex, returns to "warm" state ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.