## Twilio SMS Receiver Web App ##

This app is designed to receive SMS messages from Twilio.

This app in theory will run on basically any platform that .NET 6.0 (previously known as .NET Core) will target. We can run this inside a Raspberry Pi it's accessible from the public internet.

Currently the following SMS Message handlers are implemented:
* Microsoft Teams WebHook

The following message handlers will be implemented in a later release:
* SMTP Messages

## Requirements

* A Public IP - or - 
* A Reverse HTTP Proxy to direct traffic to if you don't want the code running without a reverse proxy. Kestrel is perfectly capable on serving HTTP requests without a reverse proxy in .NET 6.0
* **Strongly Recommended** - TLS Certificate - this can be automated with your reverse proxy via certbot if you want a set it and forget it solution
* A [system](https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md) that is supported by .NET 6.0

## Code Implementation
* C# 6.0
* .NET 6.0
* EntityFramework Core 6.0
* EF Core SQLite DB Provider 6.0 for data processing

## API Endpoints

``/api/SMSReceiver``

This endpoint only takes in a POST request in Production mode. In Development mode it will also accept a GET request returning all SMS messages stored in the database

``/api/MSTeamsWebHooks``

This endpoint takes a GET or POST request to add or remove Microsoft Teams webhook endpoints. **This endpoint will only respond to requests in Development mode.**

**Refer to ``/swagger/index.html`` endpoint in Development mode for the latest API updates**

## Twilio Configuration
### Webhook Configuration
1. Log into the Twilio account dashboard
2. On Phone Numbers -> Manage -> Active numbers, ensure a DID is there for this purpose. If not, purchase a DID from Twilio
3. In the DID, ensure the following is set on the Messaging section:
|Message Action|Handler Type|Web Endpoint|HTTP Verb|
|-|-|-|-|
| A MESSAGE COMES IN | Webhook | ``http://<Endpoint where the API is being hosted on>/api/SMSReceiver`` | POST |
| PRIMARY HANDLER FAILS | Webhook | ``http://<Endpoint where the API is being hosted on>/api/SMSReceiver`` | POST |

## Wishlist

* MMS Message handling and storage - currently the code obtains all MMS media URL's sent from Twilio, but does not actively process them
* Migrate away from SQLite to an actual multi-user SQL database - PGSql or MySQL will work as there are supported EF Core Providers for this
* Route DID's to specific destinations
* An actual admin UI with authentication provided by Azure AD
* Windows Service Capability

## Building

### Development Build or Debugging
1. Ensure you have the .NET 6.0 SDK installed on your development station
2. Clone the repository
3. Navigate to the TwilioSMSReceiver directory
4. Run ``dotnet run``

### Build for Production Deployments

**Refer to the [Microsoft RID Catalog](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog) for runtimes**

A generic Linux Intel 64-bit machine with the binarines being targed in Self-Contained Mode is being used for this example.

1. Ensure you have the .NET 6.0 SDK installed on your development station
2. Clone the repository
3. Navigate to the TwilioSMSReceiver directory
4. Run ``dotnet publish -r linux-x64 --self-contained``
5. On the output directory, copy all of the files to the target machine and deploy accordingly

## Installing
1. Ensure you have the .NET Entity Framework Core Tools installed on your development machine
2. Run the following command at the root of the source tree ``dotnet ef database update --project TwilioSMSReceiver.Data -s TwilioSMSReceiver``
3. Use a [SQLite DB Editor](https://sqlitebrowser.org/) and insert any Microsoft Teams WebHook links to the MSTeamsWebHooks table. An example would be:
```SQL
INSERT INTO MSTeamsWebHooks (WebHookUri) VALUES ("msteamswebhookurlhere");
```
3. Copy the ``smsdatabase.sqlite`` database file to the root of the directory where the app will run from
4. Start the TwilioSMSReceiver app up
    - On Linux this will be ``./TwilioSMSReceiver``
    - On Windows, this will simply mean executing the TwilioSMSReceiver.exe executable

The app can be daemonized on Linux as a systemd unit file if you wish to, an example is here:
```INI
[Unit]
Description=SMS Receiver

[Service]
WorkingDirectory=/opt/SMSReceiver
ExecStart=/opt/SMSReceiver/TwilioSMSReceiver
Restart=always
RestartSec=10
SyslogIdentifier=SMSReceiver
User=dotnet
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false
Environment=ASPNETCORE_URLS="http://localhost:9999"

[Install]
WantedBy=multi-user.target
```

This will run the Web App listening on localhost port 9999 with the HTTP protocol. In addition, this will place it in Production mode and will disable certain API endpoints listed above.

Windows service support will come in a later release