在 Sling OSGi 容器中实施 Alexa Skills

Implement Alexa Skills in Sling OSGi container

我正在使用 Java Alexa Skills Kit SDK hosted on Apache Tomcat. However, I need to move the project to Apache Sling based server. It's based on OSGi container (Apache Felix 实现 Alexa Skills 逻辑(speechlets)。我发现 Sling DI 机制非常有用。然而,看起来 Java Alexa Skills Kit SDK 完全没有为这种用途做好准备。主要问题是 SDK servlet 是一个普通的 Java servlet,而 Sling 不支持它。此外,SDK 甚至不是 OSGi 包。以 Sling 风格使用它会很好,但我不想从头开始复制 SDK。

有人在 OSGi 容器中创建 Skills 作为 Sling 服务吗?我必须自己创建一个 SlingServlet 吗? Java Alexa Skills Kit SDK 可以与 Sling 服务一起使用吗?

您是对的,Java Alexa Skills Kit SDK 未启用 OSGi,并且 servlet 无法与 Sling 一起使用。但是,API 的其余部分(除了 servlet)由普通 Java 对象组成,因此可以将其与 Sling 一起使用。这就是我创建 alexa-skills-sling 库的原因,该库将 Java Alexa Skills Kit SDK 包装到 Sling 功能中,以便您可以使用服务和 DI 机制。

要使用它你需要添加一个依赖:

<dependency>
  <groupId>eu.zacheusz.sling.alexa</groupId>
  <artifactId>alexa-skills-sling</artifactId>
  <version>1.2.1</version>
</dependency>

并将其安装为 OSGi 包。例如:

<plugins>
   <plugin>
      <groupId>org.apache.sling</groupId>
      <artifactId>maven-sling-plugin</artifactId>
      <executions>
         <execution>
            <id>install-dependency</id>
            <goals>
               <goal>install-file</goal>
            </goals>
            <phase>install</phase>
            <configuration>
               <!-- install dependency to test AEM Server -->
               <slingUrl>http://${vm.host}:${vm.port}/apps/alexa/install</slingUrl>
               <deploymentMethod>WebDAV</deploymentMethod>
               <user>${vm.username}</user>
               <password>${vm.password}</password>
               <groupId>eu.zacheusz.sling.alexa</groupId>
               <artifactId>alexa-skills-sling</artifactId>
               <version>${alexa-skills-sling.version}</version>
               <packaging>jar</packaging>
            </configuration>
         </execution>
      </executions>
   </plugin>
</plugins>

然后,要实现单个意图逻辑,只需向实现中添加 sling 注释,它就会被库选中。

@Component
@Service(IntentHandler.class)

Here is a very basic example of Intent logic implementation and you can find more examples in this project:

@Component
@Service(IntentHandler.class)
public class ExampleSimpleIntentHandlerService implements IntentHandler {

    private static final String SLOT_NAME = "mySlot";
    private static final String INTENT_NAME = "myIntent";

    @Override
    public boolean supportsIntent(String intentName) {
        return INTENT_NAME.equals(intentName);
    }

    @Override
    public SpeechletResponse handleIntent(final SpeechletRequestEnvelope<IntentRequest> requestEnvelope) {

        final IntentRequest request = requestEnvelope.getRequest();
        final Intent intent = request.getIntent();
        final Slot slot = intent.getSlot(SLOT_NAME);

        final String responseMessage;
        if (slot == null) {
            responseMessage = format(
                    "I got your request, but there is no slot %",
                    SLOT_NAME);
        } else {
            responseMessage = format(
                    "I got your request. Slot value is %s. Thanks!",
                    slot.getValue());
        }
        return newTellResponse(responseMessage);
    }

    private SpeechletResponse newTellResponse(final String text) {
        return SpeechletResponse.newTellResponse(newPlainTextOutputSpeech(text));
    }

    private PlainTextOutputSpeech newPlainTextOutputSpeech(final String text) {
        final PlainTextOutputSpeech speech = new PlainTextOutputSpeech();
        speech.setText(text);
        return speech;
    }
}