config changes
This commit is contained in:
parent
04a21c4f08
commit
49a493fd32
47
README.md
47
README.md
@ -1,7 +1,5 @@
|
||||
# Messagearr
|
||||
## Add movies to your Radarr library and check their download status through text messages
|
||||
|
||||
## Installation
|
||||
### Add movies to your Radarr library and check their download status through text messages
|
||||
|
||||
### 1. Docker Compose
|
||||
```
|
||||
@ -12,36 +10,39 @@ services:
|
||||
- '4545:4545'
|
||||
environment:
|
||||
- TZ=America/Chicago # OPTIONAL: Default is UTC
|
||||
- RADARR_HOST=http://127.0.0.1:7878 # Change to your radarr host
|
||||
- RADARR_API_KEY=apikeyhere
|
||||
- HOME_DOMAIN=https://pkrm.dev # OPTIONAL: Redirects 405 and 404 errors, defaults to return status code
|
||||
- API_NUMBER=+18005632548 # International format
|
||||
- VALID_SENDERS=+18005242256, +18002153256 # International format, comma-space separated
|
||||
- QUALITY_PROFILE_ID=7
|
||||
- ROOT_FOLDER_PATH=/data/media/movies
|
||||
- SMS_SERVICE=telnyx
|
||||
- SMS_API_KEY=apikeyhere
|
||||
- RADARR_HOST_URL=http://127.0.0.1:7878 # Change to your radarr host
|
||||
- RADARR_API_KEY=apikeyhere # Found by navigating to Settings > General
|
||||
- SMS_SERVICE=servicename # Currently only supporting Telnyx
|
||||
volumes:
|
||||
- /local/file/path:/data
|
||||
image: messagearr
|
||||
image: packetparker/messagearr:latest
|
||||
```
|
||||
### 2. Before Running Compose
|
||||
#### Before the container will start and work properly a `quality_profile_id` will need to be defined (not in the compose file). First run the container, not in daemon mode, and it will quit with an error stating that the value has not been set. This will create a file in `/data/quality_profile_id.yaml` - within this file there will be comments that list all of the quality profiles defined on your radarr server. Under the `quality_profile_id` value enter one of the integers that corresponds to the quality profile that you want movies to be added under.
|
||||
### 2. Run the Container
|
||||
#### Run the container in non-daemon mode, you will get an error stating that there are variables that need to be set within the `config.yaml` file, this file is in the internal path of `/data/config.yaml`. Go into that file and being setting the variables that appear for you within that file. Note that every single entry must have a value, the only optional value is `home_domain` but requires `null` at the very least (this is also the default).
|
||||
|
||||
### 3. Important Notes
|
||||
### 3. What Does Every Value in config.yaml Mean?
|
||||
- #### `quality_profile_id` There is a commented list of profiles that exist within your Radarr server. The list contains the profile id followed by the profile name. This value should be the single integer id of the quality profile that you would like movies to be added under.
|
||||
|
||||
- #### `RADARR_HOST` needs to be entered as a full URL, a host:port configuration will result the container not working.
|
||||
- #### `home_domain` Defaults to null meaning 404/405 errors will just return the error to the browser. Replace this will a full URL if you would like those errors to be redirected to your website (e.g. https://pkrm.dev)
|
||||
|
||||
- #### All phone numbers must be entered in their international format (e.g. +18005263258)
|
||||
- #### `api_number` The number given to you by your SMS service, in international format, and in ' ' (e.g. '+18005282589')
|
||||
|
||||
- #### Currently only Telnyx is supported as an SMS client, however, I wanting to support a much larger amount of services. Please submit a pull request if you already have some code (message creation for different services is under `app/create_message.py`).
|
||||
- #### `valid_senders` Comma-space separated list of numbers that are allowed to send commands, this stops random numbers from being allowed to add movies to Radarr. This also must be in international format (e.g. +18005269856, +18005247852, +18002365874). If you have only 1 sender here, that must be put within ' '.
|
||||
|
||||
- #### The `ROOT_FOLDER_PATH` can be found under the UI of your Radarr serve by navigating to Settings > Media Management then scroll to the very bottom of the file. There you will find a file path, this FULL path should be entered as the environment variable value for `ROOT_FOLDER_PATH`.
|
||||
- #### `root_folder_path` The folder path defined in your Radarr server. Find this value by logging into your Radarr server and navigate to Settings > Media Management, at the bottom of this page will be your root folder path (copy the full path!)
|
||||
|
||||
- #### The `VALID_SENDERS` environment variable defines the list of numbers that have permission to run commands through SMS. This stops random numbers from adding movies to your library.
|
||||
- #### The last values will vary dependant on your SMS service, but they are just the authentication values for your service.
|
||||
|
||||
- #### You must define a volume so that data is persistent across container reboots.
|
||||
### 4. Setup your Domain
|
||||
#### It is recommended but not technically required to have a domain in order for this to work. This container runs a flask image in order to accept POST requests and must be open to the internet so that incoming messages can be accepted. The process for this is different for every reverse proxy and I recommend that you refer to your proxies documentation for help. Once you have correctly proxied the domain you can test it by navigating to the domain, you should recieve a 404 error or be redirect to `home_domain` if the value has been set.
|
||||
|
||||
#### If you do not have a domain you can use a DDNS service or you can open port 4545 (or whatever exposed port you used) on your router.
|
||||
|
||||
### 5. Add the Domain
|
||||
#### Once you have configured your domain or router go to your sms services console and buy a number for SMS messaging. Once you buy the number you need to configure how it handles incoming messages, there you should be able to have the service send a POST request to a webhook for incoming message. You should overwrite or set this value to `http(s)://yourdomain.com/incoming` or `http://yourip:port/incoming`
|
||||
|
||||
### 6. Further Help
|
||||
#### Please open an issue if you need help with any part of setting this up (I know the docs/instructions aren't great). You can also email me at [contact@pkrm.dev](mailto:contact@pkrm.dev)
|
||||
|
||||
### Please open an issue if you have any trouble when getting started. Also, pull requests that add additional functionality or more SMS services are welcome!
|
||||
|
||||
#### Happy coding!
|
@ -1,11 +1,12 @@
|
||||
import telnyx
|
||||
from initialize_variables import sms_service, sms_api_key, api_number
|
||||
|
||||
from initialize_variables import *
|
||||
|
||||
def create_message(number, message):
|
||||
if sms_service == 'telnyx':
|
||||
telnyx.api_key = sms_api_key
|
||||
telnyx.api_key = telnyx_api_key
|
||||
telnyx.Message.create(
|
||||
from_=api_number,
|
||||
to=number,
|
||||
text=message
|
||||
)
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ from apscheduler.schedulers.background import BackgroundScheduler
|
||||
import sqlite3
|
||||
import requests
|
||||
|
||||
from initialize_variables import radarr_host, headers
|
||||
from initialize_variables import radarr_host_url, headers
|
||||
|
||||
# Remove all entries from the database of movies that have already finished downloading
|
||||
# This helps to stop from entries building up in the database and slowing down everything
|
||||
@ -17,7 +17,7 @@ def clear_database():
|
||||
''')
|
||||
movie_ids = cursor.fetchall()
|
||||
# Get all of the movie_ids that are currently downloading/queued and/or missing
|
||||
response = requests.get(f'{radarr_host}/api/v3/queue/', headers=headers)
|
||||
response = requests.get(f'{radarr_host_url}/api/v3/queue/', headers=headers)
|
||||
current_movie_ids = []
|
||||
for movie in response.json()['records']:
|
||||
current_movie_ids.append(str(movie['movieId']))
|
||||
|
@ -4,55 +4,70 @@ import requests
|
||||
|
||||
supported_sms_services = ['telnyx']
|
||||
|
||||
|
||||
radarr_host = os.environ['RADARR_HOST']
|
||||
radarr_api_key = os.environ['RADARR_API_KEY']
|
||||
try:
|
||||
home_domain = os.environ['HOME_DOMAIN']
|
||||
except:
|
||||
home_domain = None
|
||||
api_number = os.environ['API_NUMBER']
|
||||
val_nums = os.environ['VALID_SENDERS']
|
||||
root_folder_path = os.environ['ROOT_FOLDER_PATH']
|
||||
sms_service = os.environ['SMS_SERVICE']
|
||||
if sms_service not in supported_sms_services:
|
||||
print(f'{sms_service} is not a supported SMS service. Please choose from the supported list: {supported_sms_services}')
|
||||
exit()
|
||||
sms_api_key = os.environ['SMS_API_KEY']
|
||||
sms_service = str(os.environ['SMS_SERVICE']).lower()
|
||||
radarr_host_url = str(os.environ['RADARR_HOST_URL'])
|
||||
radarr_api_key = str(os.environ['RADARR_API_KEY'])
|
||||
|
||||
headers = {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Api-Key': radarr_api_key
|
||||
}
|
||||
|
||||
numbers_responses = {
|
||||
'1': 1, 'one': 1, '1.': 1,
|
||||
'2': 2, 'two': 2, '2.': 2,
|
||||
'3': 3, 'three': 3, '3.': 3
|
||||
}
|
||||
|
||||
# Open the quality_profile_id.yaml file and see if the quality_profile_id is set
|
||||
# Open the config.yaml file and see if the config is set
|
||||
try:
|
||||
with open('/data/quality_profile_id.yaml', 'r') as f:
|
||||
with open('/data/config.yaml', 'r') as f:
|
||||
file = yaml.load(f, Loader=yaml.FullLoader)
|
||||
try:
|
||||
quality_profile_id = int(file['quality_profile_id'])
|
||||
except:
|
||||
print('quality_profile_id is not set or is invalid. Please edit the quality_profile_id.yaml file and add the quality_profile_id from one of the integer values listed within the file')
|
||||
exit()
|
||||
except FileNotFoundError:
|
||||
# Create the quality_profile_id.yaml file
|
||||
with open('/data/quality_profile_id.yaml', 'w') as f:
|
||||
quality_profile_id = None
|
||||
|
||||
if not quality_profile_id:
|
||||
print('No quality_profile_id found. Please edit the quality_profile_id.yaml file and add the quality_profile_id from one of the integer values listed within the file')
|
||||
data = requests.get(f'{radarr_host}/api/v3/qualityprofile', headers=headers).json()
|
||||
# Open quality_profile_id.yaml and write each profile as a comment to the file
|
||||
with open('/data/quality_profile_id.yaml', 'w') as f:
|
||||
if str(file['home_domain']) != 'null':
|
||||
home_domain = str(file['home_domain'])
|
||||
|
||||
api_number = str(file['api_number'])
|
||||
val_nums = str(file['valid_senders'])
|
||||
root_folder_path = str(file['root_folder_path'])
|
||||
if sms_service not in supported_sms_services:
|
||||
print(f'{sms_service} is not a supported SMS service. Please choose from the supported list: {supported_sms_services}')
|
||||
exit()
|
||||
|
||||
if sms_service == 'telnyx':
|
||||
telnyx_api_key = str(file['telnyx_api_key'])
|
||||
|
||||
value_not_set = False
|
||||
except:
|
||||
print('One or more values are not set or not set correctly within the config.yaml file. Please edit the file or refer to the docs for more information.')
|
||||
exit()
|
||||
|
||||
except FileNotFoundError:
|
||||
# Create the config.yaml file
|
||||
with open('/data/config.yaml', 'w') as f:
|
||||
value_not_set = True
|
||||
|
||||
if value_not_set:
|
||||
print('One or more values are not set or not set correctly within the config.yaml file. Please edit the file or refer to the docs for more information.')
|
||||
data = requests.get(f'{radarr_host_url}/api/v3/qualityprofile', headers=headers).json()
|
||||
# Open config.yaml and write each profile as a comment to the file
|
||||
with open('/data/config.yaml', 'w') as f:
|
||||
f.write('# Quality Profile ID\'s\n')
|
||||
for entry in data:
|
||||
f.write(f'# {entry["id"]} - {entry["name"]}\n')
|
||||
|
||||
f.write("quality_profile_id: ")
|
||||
exit()
|
||||
f.write("\n")
|
||||
f.write("home_domain: null # Optional: 404/405 errors redirect to this domain, leaving as\n# null means the webserver will just return the error to the browser\n")
|
||||
f.write("api_number: # International format\n")
|
||||
f.write("valid_senders: # International format, comma-space separated (eg. +18005263256, +18005428741\n")
|
||||
f.write("root_folder_path: # Path to the root folder where movies are downloaded to\n")
|
||||
if sms_service not in supported_sms_services:
|
||||
print(f'{sms_service} is not a supported SMS service. Please choose from the supported list: {supported_sms_services}')
|
||||
exit()
|
||||
|
||||
if sms_service == 'telnyx':
|
||||
f.write("telnyx_api_key: \n")
|
||||
exit()
|
||||
|
||||
numbers_responses = {
|
||||
'1': 1, 'one': 1, '1.': 1,
|
||||
'2': 2, 'two': 2, '2.': 2,
|
||||
'3': 3, 'three': 3, '3.': 3
|
||||
}
|
@ -48,7 +48,10 @@ and then run the command if it is valid.
|
||||
def incoming():
|
||||
# Get the data and define the from_number (number that sent the message)
|
||||
data = flask.request.get_json()
|
||||
from_number = data['data']['payload']['from']['phone_number']
|
||||
|
||||
if sms_service == 'telnyx':
|
||||
from_number = data['data']['payload']['from']['phone_number']
|
||||
|
||||
# Make sure the number is a valid_sender, this stops random people from
|
||||
# adding movies to the library
|
||||
if from_number not in valid_senders:
|
||||
@ -69,7 +72,7 @@ def incoming():
|
||||
incoming_message = str(data['data']['payload']['text']).split(' ', 1)[1]
|
||||
movie_request = incoming_message.replace(' ', '%20')
|
||||
# Send a request to the radarr API to get the movie info
|
||||
response = requests.get(f'{radarr_host}/api/v3/movie/lookup?term={movie_request}', headers=headers)
|
||||
response = requests.get(f'{radarr_host_url}/api/v3/movie/lookup?term={movie_request}', headers=headers)
|
||||
# If there are no results, alert the user
|
||||
if len(response.json()) == 0:
|
||||
create_message(from_number, "There were no results for that movie. Please make sure you typed the title correctly.")
|
||||
@ -121,7 +124,7 @@ def incoming():
|
||||
del temp_movie_ids[from_number]
|
||||
return 'OK'
|
||||
|
||||
data = requests.get(f'{radarr_host}/api/v3/movie/lookup/tmdb?tmdbId={tmdb_id}', headers=headers)
|
||||
data = requests.get(f'{radarr_host_url}/api/v3/movie/lookup/tmdb?tmdbId={tmdb_id}', headers=headers)
|
||||
|
||||
data = data.json()
|
||||
movie_title = data['title']
|
||||
@ -130,14 +133,14 @@ def incoming():
|
||||
data['monitored'] = True
|
||||
data['rootFolderPath'] = root_folder_path
|
||||
# Pass this data into a pass request to the radarr API, this will add the movie to the library
|
||||
response = requests.post(f'{radarr_host}/api/v3/movie', headers=headers, json=data)
|
||||
response = requests.post(f'{radarr_host_url}/api/v3/movie', headers=headers, json=data)
|
||||
data = response.json()
|
||||
movie_id = data['id']
|
||||
# Send message to user alerting them that the movie was added to the library
|
||||
create_message(from_number, f"🎉 {data['title']} has been added to the library!\n\nTo check up on the status of your movie(s) send /status - please wait at least 5 minutes before running this command in order to get an accurate time.")
|
||||
# Finally, as to not slow up the sending of the message, send this request
|
||||
# Send a POST request to the radarr API to search for the movie in the indexers
|
||||
requests.post(f'{radarr_host}/api/v3/command', headers=headers, json={'name': 'MoviesSearch', 'movieIds': [int(movie_id)]})
|
||||
requests.post(f'{radarr_host_url}/api/v3/command', headers=headers, json={'name': 'MoviesSearch', 'movieIds': [int(movie_id)]})
|
||||
|
||||
# Add the movie_id to the database so that users can check up on the status of their movie
|
||||
db = sqlite3.connect('/data/movies.db')
|
||||
@ -156,7 +159,7 @@ def incoming():
|
||||
elif str(data['data']['payload']['text']).strip() == '/status':
|
||||
# This returns a list of ALL movies being downloaded, but not all of them were
|
||||
# requested by the user, so we need to filter out the ones that were not requested
|
||||
response = requests.get(f'{radarr_host}/api/v3/queue/', headers=headers)
|
||||
response = requests.get(f'{radarr_host_url}/api/v3/queue/', headers=headers)
|
||||
# Get all the movie_ids that were requested by the user
|
||||
db = sqlite3.connect('/data/movies.db')
|
||||
cursor = db.cursor()
|
||||
@ -197,7 +200,7 @@ def incoming():
|
||||
if message == "":
|
||||
# For all movie IDs within the database
|
||||
for movie_id in movies.keys():
|
||||
response = requests.get(f'{radarr_host}/api/v3/movie/{movie_id}', headers=headers)
|
||||
response = requests.get(f'{radarr_host_url}/api/v3/movie/{movie_id}', headers=headers)
|
||||
# This means that there is no current download, and no file has been found
|
||||
# MOST likely means a download just wasn't found, so alert the user
|
||||
data = response.json()
|
||||
@ -224,14 +227,12 @@ def incoming():
|
||||
# Handle 405 errors - when a user attempts a GET request on a POST only route
|
||||
@app.errorhandler(405)
|
||||
def method_not_allowed(e):
|
||||
if home_domain:
|
||||
return flask.redirect(home_domain, code=302)
|
||||
else:
|
||||
return 'Method not allowed', 405
|
||||
if home_domain != 'None':
|
||||
return flask.redirect(home_domain)
|
||||
return 'Method Not Allowed'
|
||||
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(e):
|
||||
if home_domain:
|
||||
return flask.redirect(home_domain, code=302)
|
||||
else:
|
||||
return 'Page not found', 404
|
||||
if home_domain != 'None':
|
||||
return flask.redirect(home_domain)
|
||||
return 'Page Not Found'
|
||||
|
Reference in New Issue
Block a user