Skip to content

Commit

Permalink
馃攢 Merge pull request #1579 from jovotech/v4/dev
Browse files Browse the repository at this point in the history
馃敄 Prepare latest release
  • Loading branch information
jankoenig committed Aug 2, 2023
2 parents b7f56c5 + 8e7d8b1 commit c21991a
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 1 deletion.
44 changes: 44 additions & 0 deletions platforms/platform-alexa/docs/README.md
Expand Up @@ -631,6 +631,50 @@ This would result in the following output template:
}
```

### Custom Tasks

You can handle [custom tasks](https://developer.amazon.com/en-US/docs/alexa/custom-skills/understand-tasks.html) with the following features:

- `this.$alexa.task` property that offers helper methods and properties to access task related values
- `AlexaHandles.onTask()` for the [`@Handle` decorator](https://www.jovo.tech/docs/handle-decorators) to accept task requests

Here is an example:

```typescript
import { AlexaHandles } from '@jovotech/platform-alexa';
// ...

@Handle(AlexaHandles.onTask('Reminder', 1))
reminderTask(): Promise<void> {
const task = this.$alexa?.task.getTask();
const taskName = this.$alexa?.task.name;
const taskVersion = this.$alexa?.task.version;
const input = this.$alexa?.task.input;
console.log(task, taskName, taskVersion, input);

// ...
}
```

To learn more about all features of the `task` property, take a look at the [`AlexaTask.ts` file](https://github.com/jovotech/jovo-framework/blob/v4/latest/platforms/platform-alexa/src/AlexaTask.ts).


Under the hood, `onTask()` as part of [`AlexaHandles`](https://github.com/jovotech/jovo-framework/blob/v4/latest/platforms/platform-alexa/src/AlexaHandles.ts) looks like this with the parameters `taskName: string` and optional `taskVersion?: number | string`:

```typescript
{
types: [InputType.Launch],
if: (jovo: Jovo) => {
const task = jovo.$alexa?.task.getTask();
if (!task) return false;
if (!jovo.$alexa?.task.hasTaskName(taskName)) return false;
if (taskVersion && !jovo.$alexa.task.isVersion(taskVersion)) return false;
return true;
},
}
```


### Name-free Interaction

You can handle [name-free interactions](https://developer.amazon.com/docs/alexa/custom-skills/implement-canfulfillintentrequest-for-name-free-interaction.html) by responding to `CanFulfillIntentRequest` requests. To do this, you can use the following two helpers:
Expand Down
3 changes: 3 additions & 0 deletions platforms/platform-alexa/src/Alexa.ts
Expand Up @@ -7,6 +7,7 @@ import { AlexaUser } from './AlexaUser';
import { AlexaEntity } from './interfaces';
import { AlexaIsp } from './AlexaIsp';
import { AlexaAudioPlayer } from './AlexaAudioPlayer';
import { AlexaTask } from './AlexaTask';

export class Alexa extends Jovo<
AlexaRequest,
Expand All @@ -19,11 +20,13 @@ export class Alexa extends Jovo<
$entities!: EntityMap<AlexaEntity>;
isp: AlexaIsp;
audioPlayer: AlexaAudioPlayer;
task: AlexaTask;

constructor($app: App, $handleRequest: HandleRequest, $platform: AlexaPlatform) {
super($app, $handleRequest, $platform);
this.isp = new AlexaIsp(this);
this.audioPlayer = new AlexaAudioPlayer(this);
this.task = new AlexaTask(this);
}
getSkillId(): string | undefined {
return (
Expand Down
15 changes: 14 additions & 1 deletion platforms/platform-alexa/src/AlexaHandles.ts
@@ -1,4 +1,4 @@
import { EnumLike, HandleOptions, Jovo } from '@jovotech/framework';
import { EnumLike, HandleOptions, InputType, Jovo } from '@jovotech/framework';
import { AlexaRequest } from './AlexaRequest';
import { PermissionStatus, PurchaseResultLike } from './interfaces';

Expand Down Expand Up @@ -93,4 +93,17 @@ export class AlexaHandles {
platforms: ['alexa'],
};
}

static onTask(taskName: string, taskVersion?: number | string): HandleOptions {
return {
types: [InputType.Launch],
if: (jovo: Jovo) => {
const task = jovo.$alexa?.task.getTask();
if (!task) return false;
if (!jovo.$alexa?.task.hasTaskName(taskName)) return false;
if (taskVersion && !jovo.$alexa.task.isVersion(taskVersion)) return false;
return true;
},
};
}
}
41 changes: 41 additions & 0 deletions platforms/platform-alexa/src/AlexaTask.ts
@@ -0,0 +1,41 @@
import { Alexa } from './Alexa';
import { Request } from './interfaces';

export class AlexaTask {
constructor(private alexa: Alexa) {}

getTask(): Request['task'] {
return this.alexa.$request.request?.task;
}

get version(): string | undefined {
return this.getTask()?.version;
}

get name(): string | undefined {
return this.getTask()?.name;
}

get input(): Record<string, unknown> | undefined {
return this.getTask()?.input;
}

/**
* Looks at the task name and checks if it ends with the provided taskName. Ignores skillId prefix
* @param taskName Task name without skill id
* @returns true, if task name comes after the skill id
*/
hasTaskName(taskName: string): boolean {
if (!this.name) return false;
return this.name.endsWith(`.${taskName}`);
}

isVersion(version: number | string): boolean {
if (!this.version) return false;
return this.version === `${version}`;
}

toJSON(): AlexaTask {
return { ...this, alexa: undefined };
}
}
5 changes: 5 additions & 0 deletions platforms/platform-alexa/src/interfaces.ts
Expand Up @@ -222,6 +222,11 @@ export interface Request {
listId?: string;
listItemIds?: string[];
};
task?: {
name: string;
version: string;
input: Record<string, unknown>;
};
}

// Defines a target for Alexa Conversations
Expand Down

0 comments on commit c21991a

Please sign in to comment.