diff --git a/.gitignore b/.gitignore index 736e20c..35ea3c2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ venv __pycache__ *.json data.db +signal-cli-config diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..26971da --- /dev/null +++ b/Dockerfile @@ -0,0 +1,17 @@ +# Basis-Image (kann je nach Python-Version angepasst werden) +FROM python:3.13-slim + +# Arbeitsverzeichnis erstellen +WORKDIR /app + +# Requirements in den Container kopieren +COPY requirements.txt requirements.txt + +# Abhängigkeiten installieren +RUN pip install --no-cache-dir -r requirements.txt + +# Quellcode in den Container kopieren +COPY . . + +# Flask Server starten +CMD ["python", "-u", "main.py"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..f9af7b5 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# Lab signal bot + +## Starting + +### Configuration + +Create a config: +``` +cp config.json.example config.json +vi config.json +``` + +(Inside the docker container, "http://signal-cli-rest-api:8080" can be resolved to the host of the other docker container. Outside not.) + +### Link the signal-cli bot + +Start containers: + +``` +docker compose up -d +``` + +In the beginning, this will only start the `signal-cli-rest-api` docker container. The other container will fail, since the `signal-cli` is not linked to the account. If you already activated the phone number with another signal device, you can register the new device. + +Join the docker do this: +``` +docker exec -it lab-signal-bot-signal-cli-rest-api-1 /bin/bash +``` + +Change user: +``` +su signal-api +``` + +Link the new device: +``` +signal-cli --config /home/.local/share/signal-cli link +``` + +Exit the docker shell. + +Restart docker container: +``` +docker restart lab-signal-bot-signal-cli-rest-api-1 +``` + +From host, list signal groups: +``` +python list_signal_groups.py --api-url http://localhost:8080/ -i +``` + +Now, you can set the identifier of the group you want in the config.json: +``` +vi config.json +``` + +Rebuild containers: +``` +docker compose up --build -d +``` \ No newline at end of file diff --git a/config.json.example b/config.json.example index 416e21b..2fd2785 100644 --- a/config.json.example +++ b/config.json.example @@ -1,5 +1,5 @@ { - "apiurl": "http://localhost:8080", + "apiurl": "http://signal-cli-rest-api:8080", "number": "+4900000000001", "lab_cleaning_signal_base_group": "group.00000000000000000000000000000000000000000000000000000000000=" } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..788d312 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + signal-cli-rest-api: + image: bbernhard/signal-cli-rest-api:latest-dev + environment: + - MODE=json-rpc #supported modes: json-rpc, native, normal + #- AUTO_RECEIVE_SCHEDULE=0 22 * * * #enable this parameter on demand (see description below) + ports: + - "8080:8080" #map docker port 8080 to host port 8080. + volumes: + - "./signal-cli-config:/home/.local/share/signal-cli" + lab-bot: + build: . + volumes: + - "./config.json:/app/config.json" + - "./data.db:/app/data.db" diff --git a/list_signal_groups.py b/list_signal_groups.py index 6e5183d..ed34b85 100644 --- a/list_signal_groups.py +++ b/list_signal_groups.py @@ -5,13 +5,18 @@ from result import is_err import argparse if __name__ == "__main__": - api = SignalAPI(config.apiurl, config.number) parser = argparse.ArgumentParser(description='List all groups') parser.add_argument('-i', "--show-group-ids", action='store_true', help='show group ids') + parser.add_argument('--api-url', type=str, default=None, help='API URL') args = parser.parse_args() + if args.api_url is not None: + config.apiurl = args.api_url + + api = SignalAPI(config.apiurl, config.number) + groups_result = api.get_groups() if is_err(groups_result): diff --git a/main.py b/main.py index b0aedde..c665fec 100644 --- a/main.py +++ b/main.py @@ -536,6 +536,8 @@ async def main(config: Config, session: Session): bot = LabCleaningBot(api, config.lab_cleaning_signal_base_group) bot.assert_is_base_group_admin() + print("Bot started.") + await asyncio.gather( bot.receiver(session), bot.sync_members_and_tasks(session)