Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
- Updated Vercel API to the latest versions
- Using `jq` for parsing responses
- Error handling
  • Loading branch information
iam-medvedev committed Mar 15, 2024
1 parent 7f3b189 commit 2135bfb
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 24 deletions.
30 changes: 24 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
# Vercel Dynamic DNS

Script for exposing local server with [Vercel DNS](https://vercel.com/docs/custom-domains). It runs every 15 minutes, checking current IP address and updates DNS records for your domain.
Simple script for exposing a local server with [Vercel DNS](https://vercel.com/docs/custom-domains).
It runs on CRON, checking the current IP address and updating DNS records for your domain.

## Installation

1. Download
2. Move `dns.config.example` into `dns.config`
3. Edit config
4. Open cron settings `crontab -e`
5. Add this line `*/15 * * * * /home/username/vercel-ddns/dns-sync.sh`
1. Ensure that you have [jq](https://github.com/jqlang/jq) installed
2. Download `dns-sync.sh`
3. Move `dns.config.example` to `dns.config`
4. Edit the configuration variables as required
5. Open the cron settings using the command `crontab -e`
6. Add the following line to the cron job: `*/15 * * * * /path-to/vercel-ddns/dns-sync.sh`

## Usage example

```sh
# Creating
➜ ./dns-sync.sh
Updating IP: x.x.x.x
Record for SUBDOMAIN does not exist. Creating...
🎉 Done!

# Updating
➜ ./dns-sync.sh
Updating IP: x.x.x.x
Record for SUBDOMAIN already exists (id: rec_xxxxxxxxxxxxxxxxxxxxxxxx). Updating...
🎉 Done!
```
114 changes: 98 additions & 16 deletions dns-sync.sh
Original file line number Diff line number Diff line change
@@ -1,21 +1,103 @@
#!/bin/bash

# Vercel Dynamic DNS
# https://github.com/iam-medvedev/vercel-ddns

source ./dns.config

# 1. Get current IP
IP=$(curl -s http://whatismyip.akamai.com/)
echo "$IP"

# 2. Create/update DNS record
curl -X POST "https://api.vercel.com/v2/domains/$DOMAIN_NAME/records" \
-H "Authorization: Bearer $VERCEL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "'$SUBDOMAIN'",
"type": "A",
"value": "'$IP'",
"ttl": 60
}'

echo ''
# Check if jq is installed
if ! command -v jq >/dev/null; then
echo "Error: 'jq' is not installed. Please install 'jq' to run this script."
exit 1
fi

# Returns current IP
get_current_ip() {
local ip
ip=$(curl -s http://whatismyip.akamai.com/)
echo $ip
}

# Function to check if subdomain exists
check_subdomain_exists() {
local subdomain="$1"
local response
response=$(curl -sX GET "https://api.vercel.com/v4/domains/$DOMAIN_NAME/records" \
-H "Authorization: Bearer $VERCEL_TOKEN" \
-H "Content-Type: application/json")

local record_id
record_id=$(echo "$response" | jq -r ".records[] | select(.name == \"$subdomain\") | .id")
if [[ -n "$record_id" ]]; then
# Return record ID if exists
echo "$record_id"
else
# Subdomain does not exist
return 1
fi
}

# Updates dns record
update_dns_record() {
local ip="$1"
local record_id="$2"
local response
response=$(curl -sX PATCH "https://api.vercel.com/v1/domains/records/$record_id" \
-H "Authorization: Bearer $VERCEL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"comment": "vercel-ddns",
"name": "'$SUBDOMAIN'",
"type": "A",
"value": "'$ip'",
"ttl": 60
}')

# Check for errors in the response
if [[ "$response" == *"error"* ]]; then
local error_message
error_message=$(echo "$response" | jq -r '.error.message')
echo "⚠️ Error updating DNS record: $error_message"
exit 1
fi
}

# Creates dns record
create_dns_record() {
local ip="$1"
local response
response=$(curl -sX POST "https://api.vercel.com/v4/domains/$DOMAIN_NAME/records" \
-H "Authorization: Bearer $VERCEL_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"comment": "vercel-ddns",
"name": "'$SUBDOMAIN'",
"type": "A",
"value": "'$ip'",
"ttl": 60
}')

# Check for errors in the response
if [[ "$response" == *"error"* ]]; then
local error_message
error_message=$(echo "$response" | jq -r '.error.message')
echo "⚠️ Error creating DNS record: $error_message"
exit 1
fi
}

# Get current IP
ip=$(get_current_ip)
echo "Updating IP: $ip"

# Check if subdomain exists
record_id=$(check_subdomain_exists "$SUBDOMAIN")
if [[ -n "$record_id" ]]; then
echo "Record for $SUBDOMAIN already exists (id: $record_id). Updating..."
update_dns_record "$ip" "$record_id"
else
echo "Record for $SUBDOMAIN does not exist. Creating..."
create_dns_record "$ip"
fi

echo "🎉 Done!"
9 changes: 7 additions & 2 deletions dns.config.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Get token here https://vercel.com/account/tokens
#!/bin/bash

# Get the token from https://vercel.com/account/tokens
VERCEL_TOKEN=""

# Your domain/subdomain
# Domain name (e.g. example.com)
DOMAIN_NAME=""

# Subdomain to update (note: use an empty string for the root record)
SUBDOMAIN=""

0 comments on commit 2135bfb

Please sign in to comment.