The concept is to make a modular ecosystem in a monorepo to dynamic add or remove difference instant messaging services with the goal to connect channels or groups together.
Important
This is a very WIP project. I (Phil) will focus first of implementing all existing features from I-SH1 Discord-Only implementation.
The current status is to get Discord running again on this new infrastructure with the existing features from I-SH v1
Task | Status | Note |
---|---|---|
Documentation | π§ | API Docs |
Legal | π§ | Includes proper notice to the user that messages sent need to obey the other platforms ToS |
Docker Setup | β | |
API | π§ | |
Discord | π§ | |
Telegram | β° | |
Spacebar | β | |
Guilded | β | |
Signal | β | |
β | No bot support, unless provided by WhatsApp. |
Before creating a bot for your favorite chat platform, make sure to suggest it first and it supports all the following features.
- Official Bot Support
- Send and view messages
- Get username and profile picture
The endpoint will be reachable on http://CONTAINERNAME:3000
. The API will try to get the hostname and post it into the logs.
It might be a little overkill, but it might be for the better with multiple services getting developed independently. So dynamic upgrades should be easier.
The API token is the same for all apps and just exists as a security measure. It needs to be send with every request in the Authorization
header.
A unique identifier name will be used, like discord
, signal
or telegram
and is needed to be passed along with each API request. This helps services and RabbitMQ to identify each other.
Every app that uses the DB needs to register so other apps know what features it supports and identify the Database entries belonging to that service.
As not all chat platforms are not created equally or are not done yet each app has to report what features they support. This will be also communicated to the user. For example no sticker support. A list of all the features currently possible, can be found in the app feature list
Get list of all registered apps.
Register or update app.
Validation:
name
- Lowercase
- Only letters and numbers
features
- Not all features need to be named. Defaults can be found here
Body:
{
"name": "APPNAME",
"features": {
"featureX": true,
"featureY": 0
}
}
Response:
{
"id": 0,
"name": "APPNAME",
"features": {
"featureX": true,
"featureY": 0
}
}
Get one app details and supported features.
Response:
{
[
{
"id": 0,
"name": "APPNAME",
"features": {
"featureX": true,
"featureY": 0
}
},
...
]
}
Remove service when it is no longer being used. For this to work, the delaunch
flag needs to be set to true.
Caution
This removes ALL entries in the Database that where connected to the Service!
Get a list of hubs a user owns.
Query parameters:
Parameters | Type | Optional | Default value | Description |
---|---|---|---|---|
identifier |
string | β | Identifier of the platform/app. | |
ownerId |
string | β | The user id of the list of hubs that is being requested. |
Response:
{
[
{
"id": 0,
"name": "HUBNAME",
},
...
]
}
Register or update app.
Validation:
name
- No spaces
- Needs to be unique
ownerAppIdentifier
- App needs to exist
Body:
{
"name": "HUBNAME",
"ownerID": "OWNERID",
"ownerAppIdentifier": "identifier",
"hubSettings": {
"allowInvites": true
}
}
Response:
{
"id": 0,
"name": "HUBNAME",
"ownerID": "OWNERID",
"ownerAppIdentifier": "identifier",
"hubSettings": {
"allowInvites": true
}
}
Get hub details and settings
Response:
{
"id": 0,
"name": "HUBNAME",
"ownerID": "OWNERID",
"ownerAppIdentifier": "identifier",
"hubSettings": {
"allowInvites": true
}
}
Set hub details and settings of existing hub.
Validation:
name
- No spaces
- Needs to be unique
ownerAppIdentifier
- App needs to exist
Body:
{
"name": "HUBNAME",
"ownerID": "OWNERID",
"ownerAppIdentifier": "identifier",
"hubSettings": {
"allowInvites": false
}
}
Response:
{
"id": 0,
"name": "HUBNAME",
"ownerID": "OWNERID",
"ownerAppIdentifier": "identifier",
"hubSettings": {
"allowInvites": false
}
}
Before I get any comments on how cursed this DB looks: Sequelize (and TS) is not exactly meant to dynamically create tables and columns. On top of that IDs and structure is different on every app. I could use a NoSQL DB like MongoDB, tho I am already inexperienced in TS. Thats one of the reasons for the CRUD API to exist: We should be able to migrate to a different DB later on without major changes to all the bot-services.
The list of features is hardcoded and needs to be extended, if new features get relevant.
Name | Type | Optional | Default value | Description |
---|---|---|---|---|
tos |
string | β | Link to the terms of service that gets sent to the end user. | |
privacyPolicy |
string | β | Link to the privacy policy that gets sent to the end user. | |
contentOffloading |
boolean | β | The platform allows user content to be shared to other platforms without breaching the ToS for both services. | |
textLength |
int | β | ||
trackMessage |
boolean | β | false |
If the original or imposter message gets deleted, the bot can track that and send it to other platforms. |
deleteMessage |
boolean | β | false |
Platform allows message deletion of other users. |
deleteMessageTime |
int | β | 0 |
Some platforms only allow deletion of messages for a certain time, before being locked for bots to delete them. The value is in days. |
inviteLinks |
boolean | β | false |
It is possible to invite someone through a link. (Links under each embedded message.) |
webhookSupport |
boolean | β | false |
Allows embedding of username and profile picture to "impersonate" a user. |
media |
boolean | β | false |
|
mediaStickers |
boolean | β | false |
|
mediaEmojis |
boolean | β | false |
|
delaunched |
boolean | β | false |
When a service gets delaunched from I-SH2. Can only be set to true, when the service doesn't have a queue open. |
%%{init: {"erDiagram": {"defaultRenderer": "elk"}} }%%
erDiagram
APP ||--o{ HUB-BRIDGE : uses
APP ||--o{ HUB : uses
APP ||--o{ USER-BLOCK : uses
APP ||--o{ USER-TOS-AGREE : uses
APP ||--o{ MESSAGE-LINKS : uses
APP {
int appID PK
tinytext name
tinytext featureX
datetime createdAt
datetime updatedAt
}
HUB-BRIDGE ||--o{ USER-BLOCK : gets
HUB-BRIDGE ||--o{ MESSAGE-LINKS : gets
HUB-BRIDGE {
varchar(255) channelID PK
longtext additionalData
int appID FK
int hubID FK
datetime createdAt
datetime updatedAt
}
HUB ||--||HUB-SETTING : sets
HUB ||--o{ USER-BLOCK : sets
HUB {
int id PK
tinytext name
tinytext ownerID
int appID FK
datetime createdAt
datetime updatedAt
}
HUB-SETTING {
int id PK
tinyint(1) allowInvites
}
MESSAGE-LINKS {
varchar(255) messageID PK, UK
varchar(255) channelID FK, UK
tinytext linkID
int appID FK
datetime createdAt
datetime updatedAt
}
USER-TOS-AGREE {
varchar(255) userID PK
int appID UK, FK
datetime createdAt
datetime updatedAt
}
USER-BLOCK {
int blockID PK
tinytext userID UK
int appID UK, FK
varchar(255) channelID UK, FK
int hubID UK, FK
tinytext reason
tinyint acknowledged
datetime createdAt
datetime updatedAt
}