I am trying to run multiple NodeJs server for (official) Kik Chatbots with different webhooks from one Subdomain on my webserver.
However, I am not able to do that. For one bot it works just fine. This is my setup for one working NodeJs server only:
Lets assume all webhooks are located at https://bots.mydomain.com
app.js:
'use strict';
let util = require('util');
let http = require('http');
let request = require('request');
let Bot = require('@kikinteractive/kik');
let bot = new Bot({
username: "foo",
apiKey: "bar",
baseUrl: "https://bots.mydomain.com"
});
bot.updateBotConfiguration();
// ... code ...
let server = http.createServer(bot.incoming()).listen(process.env.PORT || 8080);
So this Nodejs server is basically listening on port 8080
. Therefore, my nginx config for the site https://bots.mydomain.com
looks like this:
server {
root /var/www/bots.mydomain.com/public_html;
index index.php index.html index.htm;
server_name bots.mydomain.com;
location / { proxy_pass http://localhost:8080/; } # Port 8080
}
So far so good. This works perfectly fine! But here comes the issue:
If I try to run multiple NodeJs server, by making directories in the public_html
folder, lets say /bot1
and /bot2
and adapt my nginx config like that:
server {
root /var/www/bots.mydomain.com/public_html;
index index.php index.html index.htm;
server_name bots.mydomain.com;
location /bot1 { proxy_pass http://localhost:8080/; } # Port 8080
location /bot2 { proxy_pass http://localhost:8090/; } # Port 8090
}
and finally setting the second server to listen on port 8090
instead of 8080
and of course setting the base URL to https://bots.mydomain.com/bot1
or https://bots.mydomain.com/bot2
, nothing works anymore. And by that I mean the webhooks do not pass any data to the NodeJs server. They are, however running! I know this because if I navigate to (for example) https://bots.mydomain.com
while the bot is offline, I obviously receive the error 502 Bad Gateway
but if the bot is online I get a timeout (which means the server is indeed listening).
Am I missing something or does Nginx just not allow multiple webhooks or proxy_passes for directories?
A workaround would be to make a subdomain for each bot, which would work (I tried). But I'd like to use sub directories rather than subdomains for the bots.
EDIT:
I noticed a strange behavior: If I set a proxy_pass for /
like: location / { proxy_pass http://localhost:8080; }
to port 8080 and set the baseurl in the bot1 script to bots.mydomain.com/bot1
, Bot-1 works.
But I obviously still can't get other bots to work as well because I'm using the root (/).
Does that mean it's a problem with Kik-API's way of listening?
EDIT 2:
I checked the Nginx Log now and it seems like the Kik Wrapper tries to listen on a directory which doesn't exists. I did the following: Start the bot on port 8080
& message it. This is the log output:
2017/04/13 09:07:05 [error] 15614#15614: *1 open() "/var/www/bots.mydomain.com/public_html/incoming" failed (2: No such file or directory), client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "POST /incoming HTTP/1.1", host: "bots.mydomain.com"
2017/04/13 09:07:13 [error] 15614#15614: *1 open() "/var/www/bots.mydomain.com/public_html/incoming" failed (2: No such file or directory), client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "POST /incoming HTTP/1.1", host: "bots.mydomain.com"
But I still don't know how to fix this. As a test I created the directory incoming
in public_html
. This returned the following in the log:
2017/04/13 09:32:41 [error] 15614#15614: *10 directory index of "/var/www/bots.mydomain.com/public_html/incoming/" is forbidden, client: 107.XXX.XXX.XXX, server: bots.mydomain.com, request: "GET /incoming/ HTTP/1.1", host: "bots.mydomain.com"
Does anyone have an idea on how to fix it?
In case anyone comes across this question:
It's just not possible by Kik's API design.
When you initialize your bot with
let bot = new Bot({
username: "foo",
apiKey: "bar",
baseUrl: "https://bots.mydomain.com"
});
this baseUrl
is essentially a webhook and cannot be re-used. It has to be somewhat unique.
A possible work-around would be specifying a port directly in the base-url.