What I am trying to do: I am trying to practice MERN structure, so I wanted to set up a node.js server and react front-end first.
However, what happened is that when the server gets fired, the entire DOM got overwrite, why is that?
server.js is a simple node.js
const express = require('express');
const app = express();
// console.log that your server is up and running
app.listen(3000, () => console.log(`Listening on port 3000`));
// create a GET route
app.get('/test', (req, res) => {
res.send({ express: 'I MADE IT' });
});
React.js is my front-end:
import React from 'react';
import logo from './img/nav-logo.png';
import Product1 from './img/manage.png';
import Product2 from './img/deliver.png';
import Product3 from './img/market.png';
import Service from './service.js'
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';
class App extends React.Component {
constructor(props){
super(props)
this.state={
items: [{
desc:"Manage",
price: 5000,
purchased: false,
},
{
desc:"Deliver",
price: 2000,
purchased: false,
},
{
desc:"Market",
price: 4000,
purchased: false,
}
],
data:null,
}
}
componentDidMount() {
console.log("here")
this.callApi()
.then(res => this.setState({ data: res.express }))
.catch(err => console.log(err));
}
callApi = async () => {
const response = await fetch('/test');
const body = await response.json();
if (response.status !== 200) throw Error(body.message);
return body;
};
handleClick(desc){
const newItems = this.state.items.slice()
this.printItems(newItems)
for(var item of newItems){
if(item.desc === desc){
item.purchased = !item.purchased
}
}
this.printItems(newItems)
this.setState({
items: newItems
})
}
printItems(items){
console.log(items[0].purchased + " " + items[1].purchased + " " + items[2].purchased)
}
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to Shopping Center</h1>
</header>
<div>
<div>
{this.state.data} //<------------trying to render the data here
</div>
<Service url={Product1} desc="Manage" alt="MA" purchased={this.state.items[0].purchased} thisClick={ (desc) => this.handleClick("Manage")} />
<Service url={Product2} desc="Deliver" alt="DE" purchased={this.state.items[1].purchased} thisClick={ (desc) => this.handleClick("Deliver")}/>
<Service url={Product3} desc="Market" alt="MR" purchased={this.state.items[2].purchased} thisClick={ (desc) => this.handleClick("Market")}/>
</div>
</div>
);
}
}
export default App;
Without my node.js running, i can render my react just fine.
However, once I do npm server.js. localhost:3000 will no longer work. So i treid localhost:3000/test, and the entire HTML became the string "{ express: 'I MADE IT' }"
My index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
I want to render the message as part of my regular React DOM, but somehow the node server overwritten my entire front-end.
Additionally, i got an error message in console state the following:
SyntaxError: Unexpected token < in JSON at position 0
at App._callee$ (App.js:42)
at tryCatch (runtime.js:62)
at Generator.invoke [as _invoke] (runtime.js:296)
at Generator.prototype.(:3000/anonymous function) [as next] (http://localhost:3000/static/js/bundle.js:31252:21)
at step (App.css?9a66:26)
at App.css?9a66:26
The line of code that I located is the componentDidMount() method
My package.json file:
{
"name": "my-app",
"version": "0.1.0",
"private": true,
"dependencies": {
"bootstrap": "^4.1.3",
"express": "^4.16.3",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-scripts": "1.1.5",
"reactstrap": "^6.4.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:3001"
}
For development, given you are using create-react-app for your React application, you can use a development proxy to run both Express and React on separate ports. Any fetch() requests will be redirected to the specified proxy path/port in package.json. This will allow you take advantage of development tools for each platform.
Change the Express server port to anything other than 3000. For example app.listen(3001, () => console.log('Listening on port 3001')); This is so create-react-app can run on 3000 and Express can run on 3001.
Added the following line to the React application's package.json to enable a proxy, "proxy": "http://localhost:3001". A fetch request to /api/test will be redirect to http://localhost:3001/api/test.
For production, given you would want both applications to run on the same port:
Set up static resource loading for the server using static() method.
Added logic to server to redirect all requests that do not match you "API" paths, to load the index.html of the production built npm run build React application using sendFile(). This will allow to use routing within the React application.
Here is what that could look like at a basic level, with the create-react-app build folder generated from npm run build command is placed into path /public/build:
app.use(express.static(path.join(__dirname, 'public', 'build')));
// API route
app.get('/api/test', (req, res) => {
res.send({ express: 'I MADE IT' });
});
// catch-all route
app.use('*', function (request, response) {
response.sendFile(path.join(__dirname, 'public', 'build', 'index.html'));
});
React fetch():
// ...
const response = await fetch('/api/test'); // this matches the path specified on server, before the catch all route
const body = await response.json();
// ...
Check out this answer as it was a similar issue.
Update: - Steps to create simple Express + React development environment:
Create Express application using express-generator. Run command npx express-generator react-express
Navigate into created project. Run command cd react-express.
Run command npm install. Then delete directory public.
Create React application using create-react-app. Run command npx create-react-app public.
Install concurrently. Run command npm install concurrently --save-dev.
Edit app.js at the base of project created by express-generator. Add the following lines starting at line 25. This is to expose and endpoint at /api/test and provide a "catch-all" route to load index.html generated by npm run build.
```
app.get('/api/test', (req, res) => {
res.send({ express: 'I MADE IT' });
});
app.use('*', function (request, response) {
response.sendFile(path.join(__dirname, 'public', 'build', 'index.html'));
});
```
Edit /bin/www line 15 to change port from 3000 to 3001. var port = normalizePort(process.env.PORT || '3001');
Edit package.json created by create-react-app at /build/package.json. Add the following line "proxy": "http://localhost:3001".
At the base package.json located at the root of the project, created by express-generator, add the following line to srcipts: "dev": "concurrently \"node ./bin/www\" \"cd public && npm start\""
Run command npm run dev from the base of the project. This will load both the server (Express) and client (React) and will proxy calls, in this example /api/test on port 3000 will be directed to the server port running at 3001.
Hopefully that helps!
Related
I have a project which uses express to receive webhooks which are sent to a specific url. The project contains also a index.html which implements (via tag) the script game.js with a simple tic tac toe game. To this point everything works fine: the webapp is displaying, the tic tac toe game is working and if a webhook is received console.log(req.body); is getting executed.
Now to my question:
I want that when server.js is receiving a webhook that in the game.js the function webhookEvent() gets called. But I have no idea how to achieve this as I am pretty new to javascript/node js. I don't understand how I can call a function in game.js from server.js. I would be pleased if somebody can help me with that.
The project has following folder structure and file contents:
project
│ server.js
│ package.json
│
└───src
│ │ index.html
│ │ game.js
server.js (start script):
const express = require("express");
var app = express()
const path = require('path');
app.use(express.static(path.join(__dirname, 'src')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'src', 'index.html'));
});
app.use(express.urlencoded({ extended: false }));
app.post("/webhook", (req, res) => {
console.log(req.body);
res.sendStatus(200);
});
var listener = app.listen(process.env.PORT, function () {
console.log("Your bot is running on port " + listener.address().port);
});
package.json (sets server.js to start script):
{
"name": "project",
...
"main": "server.js",
"scripts": {
"start": "node server.js"
},
...
}
src/index.html (implements game.js at the bottom):
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<script type="module" src="game.js"></script>
</body>
</html>
src/game.js (here I want to do something if server.js receives a webhook)
if (document.querySelector) {
document.documentElement.classList.add("js");
var ticTacToeElement = document.querySelector("#tic-tac-toe");
...
}
function webhookEvent() {
// do something when webhook is received
}
What I have already tried:
export app from server.js module.exports = app; --> issue when I try to import this in game.js with var app = require("../server.js"); the script game.js is not working anymore.
export webhookEvent from game.js with export {webhookEvent}; and import it in server.js --> I think this does not work because server.js is called before game.js and therefore can't import functions from game.js
You can use Websockets which allow you to communicate back-and-forth between the server & client. I put together a very simple Websockets sandbox for you to understand and try implementing in your code.
There are many Websocket libraries to choose from, such as Socket.io, ws, etc. The example I provided has a React frontend and Express + Node backend. Even if you don't use React, the concepts are the same.
index.js
import express from "express";
import WebSocket, { WebSocketServer } from "ws";
import http from "http";
const heartbeat = (ws) => {
ws.isAlive = true;
};
const app = express();
const server = http.createServer(app);
const wss = new WebSocketServer({ port: 4443 });
wss.on("close", function close() {
console.log("closed");
});
wss.on("open", function connection(client) {
console.log('sent "open" to client');
client.send("open");
});
// USER CONNECTED (onload events)
wss.on("connection", async function connection(client, request) {
console.log("user connected", Date.now());
client.send(JSON.stringify({ ready: true }));
// CLIENT ALIVE-CHECK
client.isAlive = true;
client.on("pong", () => heartbeat(client));
// message all clients in the ui
client.on("message", async function message(d, isBinary) {
if (client.readyState === WebSocket.OPEN) {
const data = JSON.parse(d.toString());
console.log("client message", { data });
client.send(
JSON.stringify({
score: Math.random(),
session: Math.random(),
...data,
})
);
}
});
});
server.listen(process.env.port || 4444, () => {
console.log(`*~~% wesley's server %~~*`);
});
In your frontend you then make a connection to the Websocket server and setup your listeners. These allow your frontend to know when your backend sent it a message. Likewise, on the server there are listeners that let it know when the client emit or sent a message.
websocket.addEventListener("message", (e) => {});
I'm trying to generate a dynamic QRCode image using a AWS Lambda HTTP GET endpoint.
The lambda function is built with Serverless and Express and uses npm node-qrcode lib to generate a QR Code PNG file from a String from another external service.
All works fine from localhost, using serverless-offline plugin.
But, when I deploy to AWS production and try to access from browser, I only see a broken image and a HTTP 403 on Dev Tools console.
Despite the broken image, the function is being invoked successfully as I am able to see the log generated on the server.
Any ideas?
package.json
{
"name": "md-pix-transaction-qrcode",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"dependencies": {
"#vendia/serverless-express": "^4.10.1",
"axios": "^0.27.2",
"express": "^4.18.1",
"qrcode": "^1.5.1"
},
"devDependencies": {
"serverless-offline": "^9.2.5"
}
}
serveless.yml
plugins:
- serverless-offline
org: xxxxxx
service: md-pix-transaction-qrcode
frameworkVersion: '3'
useDotenv: true
provider:
name: aws
runtime: nodejs14.x
deploymentMethod: direct
environment:
api_key: ${env:API_KEY}
functions:
qrcode:
handler: lambda.handler
events:
- http:
method: get
path: /qrcode/{transactionId}
cors: true
request:
parameters:
paths:
transactionId: true
lambda.js
const serverlessExpress = require('#vendia/serverless-express')
const app = require('./server')
exports.handler = serverlessExpress({ app })
server.js
const QRCode = require('qrcode');
const express = require('express')
const app = express()
const axios = require('axios');
const api = axios.create({
baseURL: "https://api.xxxxx.com/1",
});
app.get('/qrcode/:transactionId', (req, res) => {
const transactionId = req.params.transactionId;
if (!transactionId) throw new Error('Transaction ID is required!');
console.log(transactionId);
const response = api.get(`transactions/${transactionId}?api_key=${process.env.api_key}`)
.then(response => {
console.log(response.data.pix_qr_code);
console.log(response.data.status);
res.setHeader('content-type','image/png');
return QRCode.toFileStream(res, response.data.pix_qr_code);
});
})
app.listen(() => {
console.log(`Express server started.`);
})
module.exports = app;
.env
API_KEY=xxxxxxxxx
For my internship I am making a chatbot. I created a bot using botkit framework (yo botkit) and got as far as using it in the ms Teams client. But only using my localhost + ngrok setup. when I want to use https://{myproject}.azurewebsites.net/api/messages after deployment I get a 502 error message.
To try if I actually did my deployment okay, I made another project using "yo botbuilder" without botkit framework. Following the same steps I deployed it to a fresh Group. This time using the https://{myproject}.azurewebsites.net/api/messages url worked. (standard echo bot)
After that, I copied my bot files from my first project into my new one and replaced my index.js from my standard botbuilder project with my bot.js file from my botkit framework project.
I just used the standard botbuilder -> index.js file and botkit -> bot.js file +
in my package.json I changed the main and the scripts to point to bot.js instead of index.js.
After deploying, it just gave me my 502 again.
index.js
const dotenv = require('dotenv');
const path = require('path');
const restify = require('restify');
// Import required bot services.
// See https://aka.ms/bot-services to learn more about the different parts of a bot.
const { BotFrameworkAdapter } = require('botbuilder');
// This bot's main dialog.
const { EchoBot } = require('./bot');
// Import required bot configuration.
const ENV_FILE = path.join(__dirname, '.env');
dotenv.config({ path: ENV_FILE });
// Create HTTP server
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`\n${ server.name } listening to ${ server.url }`);
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});
// Create adapter.
// See https://aka.ms/about-bot-adapter to learn more about how bots work.
const adapter = new BotFrameworkAdapter({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword
});
// Catch-all for errors.
const onTurnErrorHandler = async (context, error) => {
// This check writes out errors to console log .vs. app insights.
// NOTE: In production environment, you should consider logging this to Azure
// application insights.
console.error(`\n [onTurnError] unhandled error: ${ error }`);
// Send a trace activity, which will be displayed in Bot Framework Emulator
await context.sendTraceActivity(
'OnTurnError Trace',
`${ error }`,
'https://www.botframework.com/schemas/error',
'TurnError'
);
// Send a message to the user
await context.sendActivity('The bot encountered an error or bug.');
await context.sendActivity('To continue to run this bot, please fix the bot source code.');
};
// Set the onTurnError for the singleton BotFrameworkAdapter.
adapter.onTurnError = onTurnErrorHandler;
// Create the main dialog.
const myBot = new EchoBot();
// Listen for incoming requests.
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
// Route to main dialog.
await myBot.run(context);
});
});
// Listen for Upgrade requests for Streaming.
server.on('upgrade', (req, socket, head) => {
// Create an adapter scoped to this WebSocket connection to allow storing session data.
const streamingAdapter = new BotFrameworkAdapter({
appId: process.env.MicrosoftAppId,
appPassword: process.env.MicrosoftAppPassword
});
// Set onTurnError for the BotFrameworkAdapter created for each connection.
streamingAdapter.onTurnError = onTurnErrorHandler;
streamingAdapter.useWebSocket(req, socket, head, async (context) => {
// After connecting via WebSocket, run this logic for every request sent over
// the WebSocket connection.
await myBot.run(context);
});
});
bot.js
const { Botkit } = require('botkit');
const { BotkitCMSHelper } = require('botkit-plugin-cms');
// Import a platform-specific adapter for botframework.
const { MongoDbStorage } = require('botbuilder-storage-mongodb');
// Load process.env values from .env file
require('dotenv').config();
let storage = null;
if (process.env.MONGO_URI) {
storage = mongoStorage = new MongoDbStorage({
url : process.env.MONGO_URI,
});
}
const controller = new Botkit({
webhook_uri: '/api/messages',
adapterConfig: {
appId: process.env.APP_ID,
appPassword: process.env.APP_PASSWORD,
},
storage
});
if (process.env.CMS_URI) {
controller.usePlugin(new BotkitCMSHelper({
uri: process.env.CMS_URI,
token: process.env.CMS_TOKEN,
}));
}
// Once the bot has booted up its internal services, you can use them to do stuff.
controller.ready(() => {
// load traditional developer-created local custom feature modules
controller.loadModules(__dirname + '/features');
/* catch-all that uses the CMS to trigger dialogs */
if (controller.plugins.cms) {
controller.on('message,direct_message', async (bot, message) => {
let results = false;
results = await controller.plugins.cms.testTrigger(bot, message);
if (results !== false) {
// do not continue middleware!
return false;
}
});
}
});
controller.webserver.get('/', (req, res) => {
res.send(`This app is running Botkit ${ controller.version }.`);
});
package.json
{
"name": "my-chat-bot",
"version": "1.0.0",
"description": "Demonstrate the core capabilities of the Microsoft Bot Framework",
"author": "Generated using Microsoft Bot Builder Yeoman generator v4.7.0",
"license": "MIT",
"main": "bot.js",
"scripts": {
"start": "node ./bot.js",
"watch": "nodemon ./bot.js",
"lint": "eslint .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com"
},
"dependencies": {
"botbuilder": "~4.7.0",
"dotenv": "^8.2.0",
"restify": "~8.4.0",
"botbuilder-storage-mongodb": "^0.9.5",
"botkit": "^4.6.2",
"botkit-plugin-cms": "^1.0.3",
"firebase-admin": "^8.9.2",
"jira-client": "^6.15.0",
"request": "^2.88.2"
},
"devDependencies": {
"eslint": "^6.6.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-node": "^10.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
"nodemon": "~1.19.4"
}
}
I deployed my react app to /public directory in strapi, everything work's correctly but, when I refreshed page, strapi override my react-router routs.
So... how can I redirect strapi to open public directory when i use specific routs?
e.g redirect /posts to public directory?
Strapi /public folder is here to server public assets and not to host your front end application. And it's not a good practice to do that.
I had to write that before answering your question.
Here is how static files are served.
https://github.com/strapi/strapi/blob/master/packages/strapi/lib/middlewares/public/index.js
It uses the public middleware.
So you will have to create your own middleware by following this documentation.
https://strapi.io/documentation/3.x.x/advanced/middlewares.html#custom-middlewares
So in ./middelwares/custom/index.js add the following code:
const path = require('path');
module.exports = strapi => {
return {
initialize: function(cb) {
strapi.router.route({
method: 'GET',
path: '/post',
handler: [
async (ctx, next) => {
ctx.url = path.basename(`${ctx.url}/index.html`);
await next();
},
strapi.koaMiddlewares.static(strapi.config.middleware.settings.public.path || strapi.config.paths.static, {
maxage: strapi.config.middleware.settings.public.maxAge,
defer: true
})
]
});
cb();
}
};
};
Then you will have to enable your middleware.
You will have to update the ./config/custom.json file with the following code:
{
"myCustomConfiguration": "This configuration is accessible through strapi.config.myCustomConfiguration",
"custom": {
"enabled": true
}
}
That's it!
I build my Strapi and CRA (create-react-app) at the build time, and says I want to mount my react app under /dashboard path.
and the file structure is:
yourapp/
└── apps/
├── frontend (react app)
└── backend (strapi)
add a homepage property in frontend's package.json if you are using CRA, this will tell Webpack to add a prefix to your static assets, e.g
// in frontend's package.json
{
...
"homepage": "/dashboard"
}
move your built react app to a subfolder /dashboard of backend project, by modifying the yarn build script, I'm doing like this, be careful before copy/paste my code, there is a rm -rf cmd.
// package.json in root path
{
...
"scripts": {
"build": "yarn build:front && yarn build:back && rm -rf apps/backend/dashboard && mv apps/frontend/build apps/backend/dashboard",
...
}
}
add a custom middleware in Strapi to be your "view router", that will handle all requests to /dashboard/* to serve the react app assets under apps/backend/dashboard
create a file under <strapiapp>/middlewares/viewRouter/index.js
const path = require("path");
const koaStatic = require("koa-static");
const fs = require("fs");
module.exports = strapi => {
return {
async initialize() {
const { maxAge } = strapi.config.middleware.settings.public;
const basename = "/dashboard";
const dashboardDir = path.resolve(strapi.dir, "dashboard");
// Serve dashboard assets.
strapi.router.get(
`${basename}/*`,
async (ctx, next) => {
ctx.url = ctx.url.replace(/^\/dashboard/, "");
if (!ctx.url) ctx.url = basename;
await next();
},
koaStatic(dashboardDir, {
index: "index.html",
maxage: maxAge,
defer: false
})
);
const validRoutes = [
"/dashboard",
"/subpath1",
"/subpath2"
];
// server dashboard assets and all routers
strapi.router.get(`${basename}*`, ctx => {
const routePath = ctx.url.split("?")[0];
let fileName = ctx.url;
if (validRoutes.includes(routePath)) fileName = "index.html";
ctx.type = "html";
ctx.body = fs.createReadStream(
path.join(dashboardDir + `/${fileName}`)
);
});
}
};
};
enable the custom middleware in <strapiapp>/config/custom.json
{
"myCustomConfiguration": "This configuration is accessible through strapi.config.myCustomConfiguration",
"viewRouter": { // use the middleware name
"enabled": true
}
}
and visit http://localhost:1337/dashboard you'll see the react page.
The actual answer for strapi#4.3.2 is here
I faced the same problem. All you need to do are these two steps:
Create a custom middleware. I named it spa.js and put it in the folder /src/middlewares/spa.js (I am not sure about naming). I didn't have this folder before. I created it by myself. The file spa.js should contain a code like this:
module.exports = () => {
return async (ctx, next) => {
const url = ctx.url;
// Here you should process your redirects on index.html always,
// except URLs like `admin`, `content-manager`, `i18n`, `static`, `api`, `graphql`, `uploads` etc.
// These settings should be completely the same as in your Nginx config
// for SPA (Single Page Application). Usually, we set up `Location` in Nginx
if (!url.match(/\/admin|\/content-manager\/|\/i18n\/|\/static|\/graphql|\/uploads\/|\.json/)) {
ctx.url = '/';
}
// let strapi go further
await next();
};
};
Register your new middleware in /config/middlewares.js. I had this file and it contained only strings ('strapi::errors', 'strapi::security', 'strapi::cors',). I added an object with a resolve field with a relative path to my new middleware spa.js. There are different options for how you can set up this path, you can also use just a name.
My /config/middleware.js looks like this now:
module.exports = [
{
resolve: './src/middlewares/spa.js',
},
'strapi::errors',
'strapi::security',
'strapi::cors',
'strapi::poweredBy',
'strapi::logger',
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
];
Relaunch your server by strapi start. It should work. Routes after reloading any page that was reached by React-router before will work as they should work in SPA. All routes go to / (index.html)
UPD: Please, be careful. I see many routes for "internal use". For example, /content-manager/ and /i18n/. My admin panel didn't work unless I add the content-manager route. I suppose there may be many new routes in the future and we should mark in our middleware only allowed routes that are redirected and don't change behavior for other routes.
I try to get my feet wet implementing a simply webhook for Google's NLP API.AI interface. I want to use Heroku as the server using node.js. The problem is that I can build and deploy the code on Heroku but the execution fails immediately.
Extract from the build log (note that the "real name" app is not test, I just changed it for this post)
[...]
2017-07-21T13:28:57.000000+00:00 app[api]: Build succeeded
2017-07-21T13:29:07.012028+00:00 heroku[web.1]: Starting process with command `npm start`
2017-07-21T13:29:10.516218+00:00 app[web.1]:
2017-07-21T13:29:10.516234+00:00 app[web.1]: > test#0.0.3 start /app
2017-07-21T13:29:10.516235+00:00 app[web.1]: > node app.js
2017-07-21T13:29:10.516236+00:00 app[web.1]:
2017-07-21T13:29:11.076809+00:00 heroku[web.1]: State changed from starting to crashed
I have tried many different versions of code but even this code which is reduced to pretty much nothing fails to execute.
Here is my app.js:
'use strict';
process.env.DEBUG = 'actions-on-google:*';
const ApiAiApp = require('actions-on-google').ApiAiApp;
const test = function(request, response) {
// todo
};
module.exports = {
test
};
And this is the package.json file:
{
"name": "test",
"description": "virtual scrum master",
"version": "0.0.3",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"scripts": {
"lint": "semistandard --fix \"**/*.js\"",
"start": "node app.js",
"monitor": "nodemon app.js",
"deploy": "gcloud app deploy"
},
"engines": {
"node": "6.11.1"
},
"dependencies": {
"actions-on-google": "^1.0.0"
},
"devDependencies": {
"semistandard": "^9.1.0"
}
}
After a log of searching I found the correct setup.
Here is the correct app.js code:
'use strict';
process.env.DEBUG = 'actions-on-google:*';
let Assistant = require('actions-on-google').ApiAiAssistant;
let bodyParser = require('body-parser');
let app = express();
app.use(bodyParser.json({type: 'application/json'}));
app.post('/', function (req, res) {
// Todo
});
if (module === require.main) {
// Start the server
let server = app.listen(process.env.PORT || 8080, function () {
let port = server.address().port;
console.log('App listening on port %s', port);
});
}
module.exports = app;