Gischat API backend for chatting with your tribe in GIS tools like QGIS (using QTribu plugin available from official plugin repository), GIS mobile apps and other to come
No database : messages are not stored. Just stateless websockets.
Following instances are up and running :
URL | Description | Location |
---|---|---|
https://gischat.geotribu.net | "official" international instance | Germany |
https://gischat.geotribu.fr | "official" french-speaking instance | Germany |
- Rooms can be fetched using the
/rooms
endpoint - Rules can be fetched using the
/rules
endpoint - Number of connected users can be fetched using the
/status
endpoint - List of connected and registered users can be fetched using the
/room/{room}/users
endpoint - New users must connect a websocket to the
/room/{room_name}/ws
endpoint - After connecting to the websocket, it is possible to register the user in the room by sending a
newcomer
message (see below) - Messages passing through the websocket are strings with a JSON structure, they have a
type
key which represent which kind of message it is
Those are the messages that might transit through the websocket.
Each of them has a "type"
key based on which it is possible to parse them :
-
"text"
: basic text message send by someone in the room, e.g.:{ "type": "text", "author": "jane_doe", "avatar": "mGeoPackage.svg", "text": "Hi @all how are you doing ?" }
"author"
value must be alphanumeric (or_
or-
) and have min / max length set byMIN_AUTHOR_LENGTH
/MAX_AUTHOR_LENGTH
environment variables
avatar
value is optional and usually points to a QGIS resource icon (see the ones available in the QChat/QTribu plugin)
"text"
value must have max length set byMAX_MESSAGE_LENGTH
environment variable -
"image"
: image message send by someone in the room, e.g.:{ "type": "image", "author": "jane_doe", "avatar": "mIconPostgis.svg", "image_data": "utf-8 string of the image encoded in base64" }
The image will be resized by the backend before broadcast, using the
MAX_IMAGE_SIZE
environment variable value -
"nb_users"
: notifies about the number of users connected to the room, e.g.:{ "type": "nb_users", "nb_users": 36 }
-
"newcomer"
: someone has just registered in the room, e.g.:{ "type": "newcomer", "newcomer": "jane_doe" }
After having connected to the websocket, it is possible to register a user by sending a
newcomer
message -
"exiter"
: someone registered has left the room, e.g.:{ "type": "exiter", "exiter": "jane_doe" }
-
"like"
: someone has liked a message, e.g.:{ "type": "like", "liker_author": "john_doe", "liked_author": "jane_doe", "message": "Hi @john_doe how are you doing ?" }
means that
john_doe
likedjane_doe
's message ("Hi @john_doe how are you doing ?"
)The messages of the
like
type are sent only to the liked author, if this user is registered. If this user is not registered, it won't be notified -
"geojson"
: someone shared a geojson layer, e.g.:{ "type": "geojson", "author": "jane_doe", "avatar": "mIconPostgis.svg", "layer_name": "my_geojson_layer", "crs_wkt": 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', "crs_authid": "EPSG:4326", "geojson": { "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "attribute_1": "something" }, "geometry": { "type": "Point", "coordinates": [ 1, 2 ] } }, ... ] } }
The coordinates of the
geojson
features must be expressed using the providedcrs_wkt
andcrs_authid
-
"crs"
: someone shared a CRS, e.g.:{ "type": "geojson", "author": "jane_doe", "avatar": "mIconPostgis.svg", "crs_wkt": 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', "crs_authid": "EPSG:4326", }
-
"bbox"
: someone shared a bbox, e.g.:{ "type": "bbox", "author": "jane_doe", "avatar": "mIconPostgis.svg", "crs_wkt": 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', "crs_authid": "EPSG:4326", "xmin": -1.1, "xmax": 1.1, "ymin": -1.1, "ymax": 1.1 }
-
"uncompliant"
: someone sent an uncompliant message and the server answers with such a message, e.g.:{ "type": "uncompliant", "reason": "Too many geojson features : 600 vs max 500 allowed" }
This example is the server response if sending a
ŋeojson
message with too many features
Note
ROOMS
environment variable is a comma-separated list of strings which represent the available chat rooms.
RULES
environment variable describes the instance's rules. Useful information that users should know, even when skimming content.
MAX_IMAGE_SIZE
environment variable describes the max size of image in pixels. The server will resize images based on this value.
MAX_GEOJSON_FEATURES
environment variable describes the max number of features allowed in a geojson
message. If there is more feature, the message will not be considered and the server will respond with a uncompliant
message.
-
Install
docker
using the official documentation -
Create a
docker-compose.yaml
file on your server:services: api: image: gounux/gischat:latest container_name: gischat-app environment: - ROOMS=QGIS,Field and mobile,GIS tribe, Living room,Kitchen,Garden - RULES=Be kind and nice to this wonderful world - MAIN_LANGUAGE=en - ENVIRONMENT=production - MIN_AUTHOR_LENGTH=3 - MAX_AUTHOR_LENGTH=32 - MAX_MESSAGE_LENGTH=255 - MAX_IMAGE_SIZE=800 - MAX_GEOJSON_FEATURES=500 ports: - 8000:8000 restart: unless-stopped
-
Launch the app using
compose
:docker compose up -d
-
Have a look at the logs:
docker compose logs -f
-
Install nginx and certbot:
apt install nginx certbot
-
Get a Let's Encrypt SSL certificate for your domain:
# stop nginx service systemctl stop nginx # get the certificate certbot certonly --standalone -d DOMAIN # restart nginx service systemctl start nginx
The Let's Encrypt SSL certificate should be saved to
/etc/letsencrypt/live/DOMAIN
-
Create a nginx config file:
touch /etc/nginx/sites-available/gischat.conf
-
Edit the file and add the following content (using your domain):
upstream gischat_upstream { server 127.0.0.1:8000; } server { listen 80; server_name <DOMAIN>; return 301 https://$host$request_uri; } server { listen 443 ssl; server_name <DOMAIN>; ssl_certificate /etc/letsencrypt/live/<DOMAIN>/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/<DOMAIN>/privkey.pem; location / { proxy_pass http://gischat_upstream; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 86400; } }
-
Create a symlink to enable the nginx config file :
ln -s /etc/nginx/sites-available/gischat.conf /etc/nginx/sites-enabled/gischat.conf
-
Check that the nginx config file is okey :
nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
-
Reload nginx configuration
systemctl reload nginx
That's it, you should be able to chat now with your fellow GIS mates !
- Install poetry:
python -m pip install poetry
- Install project's dependencies using poetry:
poetry install
- Install pre-commit tools:
poetry run pre-commit install
- Create local environment file and edit it:
cp .env.example .env
- Launch API:
poetry run uvicorn gischat.app:app --reload --env-file .env --log-config=log_config.yaml
- Build docker image:
docker build . --tag geotribu/gischat:latest
- Run docker image:
docker run geotribu/gischat:latest --env ROOMS=QGIS,QField,Geotribu --env RULES="Those are the rules: ..."