/timer-for-google-assistant

Allows you to send commands to Google Assistant that will execute after a certain time interval. Built using NodeJS.

Primary LanguageTypeScriptMIT LicenseMIT

Timer for Google Assistant

Description

Wouldn't it be cool if you could say stuff like:

  • "Hey Google, turn off the lights after 10 minutes"
  • "Hey Google, turn on the fan for 25 minutes"
  • "Hey Google, turn off <device> after <x> minutes"

Well, this project makes it possible. Timer for Google Assistant allows you to send commands to Google Assistant that will execute after a certain time.

How does it work?

Timer for Google Assistant provides a simple API with which you can schedule commands. See API Reference below.

This application is built using NestJS - A progressive Node.js framework. It uses IFTTT to communicate with Google Assistant and your smart device.

There are 2 ways to set it up:

  1. Install using Docker (recommended)
  2. Manual installation without Docker

API Reference

Usage

POST /trigger

Request body

Content type: application/json

Name Type Required Default value Description
key string Yes - This key can be any value, however, it should the match the key specified while setting up the server.
durationInMinutes number Yes - Number of minutes after which the action should be triggered.
deviceName string Yes - Name of the target device.
targetState boolean No false What should the state of the device be after firing the event? true = ON; false = OFF

Example

Making a POST request with the parameters below will set the lights to OFF after 20 minutes.

{
  "key":"ChangeThisToSomethingSecure",
  "durationInMinutes":20,
  "deviceName":"lights",
  "targetState":false
}

A note on the targetState parameter

If targetState is set to false (i.e., OFF), the device will be first turned ON upon receiving this command. After the specified time has elapsed, the device will be turned OFF. This is an optional parameter and by default, targetState is false.

If targetState is set to true (i.e., ON), it will do the opposite. The device will be first turned OFF upon receiving this command. After the specified time has elapsed, the device will be turned ON.

Install using Docker

Timer for Google Assistant is available as a Docker image.

Prerequisites

  • An internet facing server (so that IFTTT can make requests to your server)
  • Docker installed on this server.

Running with docker

Run the following command on your server to get this application up and running. The application runs on port 3000 internally. The command below makes the API available externally on port 3020.

For information on what the environment variables mean, see this section below.

docker run \
  -e SECURITY_KEY="ChangeThisToSomethingSecure" \
  -e IFTTT_EVENT_OFF_SUFFIX="_off" \
  -e IFTTT_EVENT_ON_SUFFIX="_on" \
  -e IFTTT_EVENT_KEY="xxxxxxxxxxxxxxxxxxxxxx" \
-p 3020:3000 wiseindy/timer-for-google-assistant

You can also specify the environment variables in a separate file, for example, my_env_data.

SECURITY_KEY=ChangeThisToSomethingSecure
IFTTT_EVENT_OFF_SUFFIX=_off
IFTTT_EVENT_ON_SUFFIX=_on
IFTTT_EVENT_KEY=xxxxxxxxxxxxxxxxxxxxxx

Now you can use a simpler command:

docker run --env-file ./my_env_data -p 3020:3000 wiseindy/timer-for-google-assistant

Running with docker-compose

If using docker compose, download the sample docker-compose.yml in this project.

  • Add your keys to docker-compose.yml
    Create two files ifttt_event_key.secret and security_key.secret which contain your IFTTT event key and security key respectively.
    When deploying with docker, any environment variable can be prefixed with FILE__ (two underscores) to be used with docker secrets (recommended for SECURITY_KEY and IFTTT_EVENT_KEY).
    ...
    environment:
        FILE__SECURITY_KEY: /run/secrets/timer_security_key
        FILE__IFTTT_EVENT_KEY: /run/secrets/timer_ifttt_event_key
        IFTTT_EVENT_OFF_SUFFIX: _off
        IFTTT_EVENT_ON_SUFFIX: _on
        
  secrets:
    timer_security_key:
      file: ./security_key.secret
    timer_ifttt_event_key:
      file: ./ifttt_event_key.secret
  ...
  • [NOT RECOMMENDED] Another way to add your keys to docker-compose.yml
    An alternative to using Docker secrets is to directly include the keys in your docker-compose.yml file. The above technique of using secrets is more secure and recommended over this method.
    Instead of using secrets in separate files, you can directly set the environment variables under the environment section to appropriate values.
    ...
    environment:
        SECURITY_KEY: ChangeThisToSomethingSecure
        IFTTT_EVENT_KEY: xxxxxxxxxxxxxxxxxxxxxx
        IFTTT_EVENT_OFF_SUFFIX: _off
        IFTTT_EVENT_ON_SUFFIX: _on
    ...

For information on what the environment variables mean, see this section below.

To start the server, run:

docker-compose up -d

To stop, run:

docker-compose down

Next, you'll need to set up triggers and actions in IFTTT. Jump to section.

Manual installation without Docker

Prerequisites

  • An internet facing web server (so that IFTTT can make requests to your server)
  • NodeJS 12.18.3 or higher (lower versions may also work, but I haven't tested it)
  • An IFTTT account

Installation

Clone this repository

git clone https://github.com/wiseindy/timer-for-google-assistant.git

Enter the directory and run npm install

cd timer-for-google-assistant/app
npm install

Create a .env file in the /app directory. Sample values can be seen in /app/.env.example

PORT=3020
SECURITY_KEY=ChangeThisToSomethingSecure
IFTTT_EVENT_OFF_SUFFIX=_off
IFTTT_EVENT_ON_SUFFIX=_on
IFTTT_EVENT_KEY=xxxxxxxxxxxxxxxxxxxxxx
  • PORT : (DEFAULT: 3000, if not specified) This is the port number the application will use. You'll need to add this exception to your firewall rule. You can also use a reverse proxy. If you're using the docker image, this is the port used by the app, not the one exposed by the container; remember to change your port value accordingly in the docker command or your docker-compose.
  • SECURITY_KEY : (REQUIRED) Set this to a unique string and do not share it with anyone.
- IMPORTANT! Make sure you change your SECURITY KEY to something secure and DO NOT use the default value.
  • IFTTT_EVENT_OFF_SUFFIX : (REQUIRED) The suffix for the "off" action in IFTTT. For more details, please view Integrate with IFTTT section below.
  • IFTTT_EVENT_ON_SUFFIX : (REQUIRED) The suffix for the "on" action in IFTTT. For more details, please view Integrate with IFTTT section below.
  • IFTTT_EVENT_KEY : (REQUIRED) You can get your IFTTT key from https://ifttt.com/maker_webhooks. Click the Documentation button at the top to get your key.

    IFTTT Webhooks page screenshot
    IFTTT Webhooks key page screenshot

Build the application

npm run build

Start the application

npm run start:prod

For more options, view Running the app section.


Integrate with IFTTT

You will be creating two actions in IFTTT; one to turn off the device and another to turn it on.

Both these actions/applets will work by receiving a web request and triggering the device ON or OFF (using IFTTT's Webhooks feature).

Set up webhooks

  1. Login to your IFTTT and create a new applet. For the this trigger, choose Webhooks.

    IFTTT create a new applet

  2. Follow a consistent naming scheme for all events. Use the correct suffixes for your device events as specified in the IFTTT_EVENT_OFF_SUFFIX and IFTTT_EVENT_ON_SUFFIX parameters in the .env file above.

    For example, if the device is a smart light, use lights_off and lights_on as the event names to turn the light OFF and ON respectively. DO NOT use inconsistent names like lights_off and LIGHT_ON.

    Make sure you follow the SAME naming scheme for ALL events (they're case sensitive).

    IFTTT name your event

  3. Next, choose your smart device from the list and select the action you'd like to carry out.

    IFTTT set event target

  4. Repeat the above steps to create the ON trigger for your device.

Configure IFTTT to receive commands from Google Assistant and forward to your server

  1. Create a new applet/action in IFTTT. For the this trigger, choose Google Assistant.

    IFTTT create a new Google Assistant applet

  2. Select Say a phrase with a number

    IFTTT Google Assistant applet

  3. Set your trigger phrase and the response. In this example, I want Google Assistant to turn on the lights and then turn it off after X minutes. Use # to specify where you'll say the number of minutes.

    IFTTT Google Assistant number trigger

  4. For the that action in your applet, select Webhooks. This will be used to make a web request to your server.

    IFTTT set target to webhooks web request

  5. Fill the action fields with the following values. For more information, refer to the API Reference below.

    For the URL field, type in the domain/IP of your webserver running this application.
    The API endpoint that handles requests is /trigger.
    Set the web request method to POST.
    Select application/json as Content Type.
    For the Body parameter, specify the following values:

    IFTTT web request action

Sample request body:

{
  "key":"ChangeThisToSomethingSecure",
  "durationInMinutes":{{NumberField}},
  "deviceName":"lights"
}
  • Make sure to use the same key that you specified in the .env file.
  • The device name lights should match the name used to create OFF/ON events: lights_off and lights_on. These values are case-sensitive.

Running the app

# development
npm run start

# watch mode
npm run start:dev

# production mode
npm run start:prod

That's it! Try saying "Hey Google, turn on the lights for 2 minutes." and if everything is setup right, Google Assistant will turn ON your lights and after two minutes, it should turn them OFF.

Test

# unit tests
npm run test

# e2e tests
npm run test:e2e

# test coverage
npm run test:cov

Support

Buy Me A Coffee

Author

License

Timer for Google Assistant is MIT licensed.

All trademarks are the property of their respective owners.