Skip to content

Beigoo/TheWeb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

# The Web — Neighborhood Pager (SMS LLM Incident Broadcast)

A single phone number + a local language model = a neighborhood emergency broadcast.

People text reports, the model fills in missing details, and when a report is complete, the system broadcasts an alert to everyone subscribed to that postcode (zip). No apps, no logins — just SMS.


## Features

* **Two run modes**

  * **Demo** (default): no real SMS; you type simulated messages in the console.

  * **Twilio**: real SMS via a Twilio number (A2P‑10DLC ready) as the terminal.

* **Join/leave with one text**

  * Strict opt‑in pledge to join; STOP to leave.

* **LLM‑powered parsing (optional)**

  * Asks for missing pieces (what / location / time / postcode), composes a concise public alert.

  * Works without an LLM (fallback question flow).

* **Safety & sanity**

  * 30‑min reporter cooldown after a successful broadcast.

  * Minimal data stored locally in SQLite.


## Repository Layout

* Program.cs — app entry, mode selection (Demo/Twilio), config & wiring

* TwilioSender.cs — outbound SMS

* SmsInboxPoller.cs — inbound SMS polling (Twilio) or demo input

* MessageRouter.cs — command parsing (JOIN/STOP) and incident flow

* PledgeParser.cs — strict pledge text parsing

* SubscriberStore.cs — SQLite storage


## Requirements

* **.NET 8 SDK** (Windows/macOS/Linux)

* SQLite is bundled via Microsoft.Data.Sqlite (no separate install required)

* (Optional) **OpenAI‑compatible local model** server (e.g., LM Studio)

* (Optional for real SMS) **Twilio account** with an **SMS‑capable number**

  * For US 10DLC messaging to arbitrary numbers, complete **A2P brand + campaign** registration and link your number to that campaign in Twilio.

Note: I can’t fetch the latest Twilio UI steps here; follow Twilio’s current docs for buying a number and A2P registration if needed.


## Quick Start — Demo Mode (no SMS)

Demo mode lets you simulate SMS by typing +E164> message lines directly in the console.

1. **Restore & run**

  ```bash

  dotnet run

  ```

2. **Choose** 1) Demo (no SMS, type messages here) in the startup wizard.

3. **(Optional) LLM**

  * If you have LM Studio (or similar) running, point to it when asked (see **Local LLM** below). Otherwise choose fallback.

4. **Try it**

  ```

  +15550000001> I, Alex Doe, join the Web for 95129. I will receive alerts nearby and stand by the truth of what I report to the Web.

  +15550000001> Fire near King's Street

  +15550000001> Around 6pm

  ```

  You’ll see the composed alert and simulated outbound sends in the console.

### Scripted demo (optional)

Create a file demo.txt:


\# demo.txt

+15550000001> I, Alex Doe, join the Web for 95129. I will receive alerts nearby and stand by the truth of what I report to the Web.

+15550000001> Garden Gate, smoke near the supermarket, 95129

+15550000001> Around 6pm

Run with an env var:

* **Windows (PowerShell)**

  ```powershell

  setx DEMO_REPLAY "C:\path\to\demo.txt"

  dotnet run

  ```

* **macOS/Linux (bash)**

  ```bash

  export DEMO_REPLAY="/path/to/demo.txt"

  dotnet run

  ```

In demo mode you always type with the +E164> prefix so the app knows which “sender” is speaking.


## Quick Start — Real SMS (Twilio)

### 1) Twilio prerequisites

* **Account SID** and **Auth Token**

* An **SMS‑capable number** you own (format: +15551234567)

* Trial accounts can only text **verified** numbers and may hit daily limits. For production 10DLC, complete **A2P** steps in Twilio.

### 2) Configure environment variables

Set **both** TWILIO\_FROM and HUB\_NUMBER to the **same** Twilio number you own. The app polls Twilio and filters inbound by HUB\_NUMBER.

**Windows (PowerShell)**

setx SMS\_PROVIDER "twilio"

setx TWILIO\_SID "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

setx TWILIO\_TOKEN "your\_auth\_token"

setx TWILIO\_FROM "+15551234567"

setx HUB\_NUMBER "+15551234567"

\# Optional local LLM

setx LLM\_BASE\_URL "http://127.0.0.1:1234"   # root only; no /v1 here

setx LLM\_MODEL "qwen2.5-7b-instruct"

**macOS/Linux (bash)**

export SMS\_PROVIDER=twilio

export TWILIO\_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

export TWILIO\_TOKEN=your\_auth\_token

export TWILIO\_FROM=+15551234567

export HUB\_NUMBER=+15551234567

\# Optional local LLM

export LLM\_BASE\_URL=http://127.0.0.1:1234    # root only; no /v1 here

export LLM\_MODEL=qwen2.5-7b-instruct

### 3) Run & select Twilio mode

dotnet run

Pick 2) Twilio SMS in the wizard (it will use your env vars or prompt for them).

### 4) Use from your phone

1. **Join** by texting this exact pledge (replace \[ ]) to your Twilio number:

  ```

  I, [First Name] [Last Name], join the Web for [POSTCODE]. I will receive alerts nearby and stand by the truth of what I report to the Web.

  ```

2. **Report** freely (e.g., “crash near X at \~5pm 95129”). If anything’s missing, the bot asks **only** for the missing piece(s).

3. On completion, an \[ALERT] ... goes to everyone subscribed to that postcode (except the reporter).

4. **STOP** to leave.


## Local LLM (optional but recommended)

You can run fully without an LLM (fallback prompts), but a local model improves parsing and tone.

1. Start an OpenAI‑compatible server (e.g., LM Studio). Its root is usually http://127.0.0.1:1234. **Do not** include /v1 in the env var.

2. Set:

  * LLM\_BASE\_URLhttp://127.0.0.1:1234

  * LLM\_MODEL → the model name LM Studio shows (e.g., qwen2.5-7b-instruct)

3. Logs:

  * **Demo mode** hides raw JSON by default; set LOG\_LLM\_JSON=1 to show it.

  * **Twilio mode** prints model JSON by default.


## How It Behaves

* **Join**

  * If a number isn’t subscribed, the system expects the exact pledge below and will reply with instructions until it matches.

  * On success: “Welcome to the Web for {postcode} …” and the number is stored in SQLite.

* **STOP**

  * Unsubscribes immediately and replies with the join instructions again.

* **Reporting**

  * The last 10 messages within 30 minutes from a reporter form the thread sent to the LLM.

  * Missing fields → one concise follow‑up (what/location/time/postcode).

  * Complete → broadcast a one‑line alert and start a 30‑min cooldown for that reporter.

**Alert style**


\[ALERT] {What} near {Location} at {Time}. (Report via The Web; call 911 for emergencies.)


## Environment Variables (reference)

| Name | Required | Mode | Description |

| -------------- | -------- | ------ | -------------------------------------------------- |

| SMS\_PROVIDER | yes | both | demo (default) or twilio |

| TWILIO\_SID | yes | twilio | Twilio Account SID |

| TWILIO\_TOKEN | yes | twilio | Twilio Auth Token |

| TWILIO\_FROM | yes | twilio | Your Twilio number in E.164 (e.g., +15551234567) |

| HUB\_NUMBER | yes | twilio | Same as TWILIO\_FROM; used to filter inbound |

| LLM\_BASE\_URL | no | both | OpenAI‑compatible base URL **without** /v1 |

| LLM\_MODEL | no | both | Model name as shown by your server |

| DEMO\_REPLAY | no | demo | Path to a demo.txt script of lines to replay |

| LOG\_LLM\_JSON | no | both | 1 to log raw model JSON in demo mode |

| NO\_WIZARD | no | both | 1 to skip startup wizard and use env vars only |


## Build a Stand‑Alone Executable (Yes, you can ship an .exe)

You can publish a single‑file, self‑contained binary for your target OS.

### Windows (x64)

dotnet publish -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:IncludeAllContentForSelfExtract=true

Output will land under:


./bin/Release/net8.0/win-x64/publish/TheWeb.exe

### macOS (Apple Silicon)

dotnet publish -c Release -r osx-arm64 --self-contained true -p:PublishSingleFile=true

Output:


./bin/Release/net8.0/osx-arm64/publish/TheWeb

### Linux (x64)

dotnet publish -c Release -r linux-x64 --self-contained true -p:PublishSingleFile=true

Output:


./bin/Release/net8.0/linux-x64/publish/TheWeb

**Tip:** For smallest size, you can add -p:PublishTrimmed=true, but only after you’ve verified runtime paths (SQLite & reflection) keep working.

Run the binary with your environment variables set (same as dotnet run).


## Data Storage

* SQLite file web.db is created alongside the executable and contains:

  * subscribers(phone\_e164, first\_name, last\_name, postcode)

  * processed\_inbound(sid, from\_e164, to\_e164, received\_utc) (prevents reprocessing the same Twilio message ID)

* No personal data beyond name/number/postcode is stored.


## Troubleshooting

* **Twilio trial or undelivered**

  * Trial: messages only to verified numbers; strict limits apply.

  * For broad US messaging: complete A2P 10DLC (brand + campaign) and link your number.

* **No inbound appears**

  * Ensure HUB\_NUMBER equals your Twilio number in E.164 and matches TWILIO\_FROM.

  * Check that your number is SMS‑capable and SID/token are correct.

* **LLM ignored**

  * LLM\_BASE\_URL must be the **root** (no /v1). Ensure your server is running.

* **Never broadcasts**

  * Provide clear what/location/time. If postcode is omitted in the report, the system falls back to the reporter’s subscribed postcode.


## Exact Texts (copy/paste)

**Join instructions (auto‑sent on mismatch or after STOP):**


To join the Web, copy this exactly and replace the \[ ]:



I, \[First Name] \[Last Name], join the Web for \[POSTCODE]. I will receive alerts nearby and stand by the truth of what I report to the Web.

**Leave:**


STOP


## License

Add a license file (MIT/Apache‑2.0/etc.).


## Acknowledgements

* **LM Studio** for an easy OpenAI‑compatible local server.

* **Twilio** for SMS APIs.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors