Skip to content

Instantly share code, notes, and snippets.

@anton-dudarev
Forked from JaldeepAsodariya/index.js
Created May 25, 2019 22:20
Show Gist options
  • Save anton-dudarev/9609883fecc3fa9309c202936f505e42 to your computer and use it in GitHub Desktop.
Save anton-dudarev/9609883fecc3fa9309c202936f505e42 to your computer and use it in GitHub Desktop.
HelloThings - A Firebase Cloud Function for manage webhook request from Dialogflow for Turn On/Off LED light.
'use strict';
process.env.DEBUG = 'actions-on-google:*';
// Create and Deploy Your First Cloud Functions
// https://firebase.google.com/docs/functions/write-firebase-functions
const functions = require('firebase-functions');
const Assistant = require('actions-on-google').ApiAiAssistant;
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const { sprintf } = require('sprintf-js');
// Firebase Realtime database reference
const widgetsDBRef = admin.database().ref('/widgets');
const jbsLedDBRef = widgetsDBRef.child('jbsled');
const strings = require('./strings') // Import strings.js for use constants value
// Local constants
const ON_SML = 'on';
const OFF_SML = 'off';
/**
* @template T
* @param {Array<T>} array The array to get a random value from
*/
const getRandomValue = array => array[Math.floor(Math.random() * array.length)];
exports.thingsExecute = functions.https.onRequest((req, res) => {
const assistant = new Assistant({request: req, response: res});
// The Entry point to all our actions
const actionMap = new Map();
actionMap.set(strings.apiaiConsole.action.thingsExecute, executeHandler);
assistant.handleRequest(actionMap);
// Fulfill things execute action business logic
function executeHandler (assistant) {
let fulfillmentMsg = strings.general.unhandled;
const screenOutput = assistant.hasSurfaceCapability(assistant.SurfaceCapabilities.SCREEN_OUTPUT);
const paramThingsName = assistant.getArgument(strings.apiaiConsole.parameter.thingsName);
const paramThingsStatus = assistant.getArgument(strings.apiaiConsole.parameter.thingsStatus);
let thingsStatusBool;
if(paramThingsStatus == ON_SML)
thingsStatusBool = true;
else if(paramThingsStatus == OFF_SML)
thingsStatusBool = false;
jbsLedDBRef.once('value', snapshot => {
const jbsLedSnapVal = snapshot.val();
console.log('LED current status is: ', jbsLedSnapVal.state);
if(jbsLedSnapVal.state != thingsStatusBool) {
const stateDBRef = jbsLedDBRef.child('state');
stateDBRef.set(thingsStatusBool).then(snapshot => {
console.log('LED status change to ', thingsStatusBool)
fulfillmentMsg = sprintf(getRandomValue(strings.richResponse.fulfillmentTurning), paramThingsName, paramThingsStatus);
if(screenOutput) {
let [imagePath, imageName] = ["", ""];
if(thingsStatusBool)
[imagePath, imageName] = strings.richResponse.images.lightOn;
else
[imagePath, imageName] = strings.richResponse.images.lightOff;
const card = assistant.buildBasicCard(sprintf(strings.general.cardTitleTurning, paramThingsStatus))
.setImage(imagePath, imageName);
const richResponseBuild = assistant.buildRichResponse()
.addSimpleResponse(fulfillmentMsg)
.addBasicCard(card)
.addSuggestions(thingsStatusBool ? strings.richResponse.suggestions.turnOffLed : strings.richResponse.suggestions.turnOnLed);
assistant.ask(richResponseBuild);
} else
assistant.ask(fulfillmentMsg);
});
} else {
console.log('LED status is already ', thingsStatusBool)
fulfillmentMsg = sprintf(getRandomValue(strings.richResponse.fulfillmentTurnAlready), paramThingsName, paramThingsStatus);
if(screenOutput) {
const richResponseBuild = assistant.buildRichResponse()
.addSimpleResponse(fulfillmentMsg)
.addSuggestions(thingsStatusBool ? strings.richResponse.suggestions.turnOffLed : strings.richResponse.suggestions.turnOnLed);
assistant.ask(richResponseBuild);
} else
assistant.ask(fulfillmentMsg);
}
});
}
});
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"dependencies": {
"actions-on-google": "^1.2.1",
"deep-freeze": "0.0.1",
"firebase-admin": "^5.2.1",
"firebase-functions": "^0.6.3",
"sprintf-js": "^1.1.1"
},
"private": true
}
// eslint-disable-next-line quotes
const deepFreeze = require('deep-freeze');
const apiaiConsole = {
"action": {
"thingsExecute":"things.execute"
},
"parameter": {
"thingsName":"things-name",
"thingsStatus":"things-status"
}
}
const richResponse = {
"images": {
"lightOn": [
"https://firebasestorage.googleapis.com/v0/b/hellothings-213b8.appspot.com/o/images%2Flight_bulb_on.png?alt=media&token=bb6d93b3-9e00-40ff-aea7-65fd81ff6a5f",
"Light On"
],
"lightOff": [
"https://firebasestorage.googleapis.com/v0/b/hellothings-213b8.appspot.com/o/images%2Flight_bulb_off.png?alt=media&token=427c2f79-a10f-4dc2-b7b7-d9b471ef442c",
"Light Off"
]
},
/** Used to give responses for turning on/off light */
"fulfillmentTurning" : [
"Sure, Turning the %1$s %2$s",
"You got it, Turning the %1$s %2$s",
"Here you go, Turning the %1$s %2$s"
],
/** Used to give responses for Already light is turn on/off */
"fulfillmentTurnAlready" : [
"The %1$s light is already %2$s",
"Ohh, The %1$s light is already %2$s. I'm smart but not more than you.",
"Sorry, but i'm not able to do this because the %1$s light is already %2$s"
],
"suggestions": {
"turnOnLed":"Turn on led",
"turnOffLed":"Turn off led"
}
}
const general = {
"unhandled" : "Sorry, I didn't understand. What you want to do? Like Turn on or off the Led light.",
"cardTitleTurning" : "Turning %s"
}
// Use deepFreeze to make the constant objects immutable so they are not unintentionally modified
module.exports = deepFreeze({
apiaiConsole,
richResponse,
general
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment