Copy External IPv4 Address, Then, Paste It Into Notes

I use VNC on both my home and small business Macs.

Occasionally, the ISP changes the external IPv4 address on one of the Macs. This prevents me from accessing that Mac, until the next day, after I have obtained the new external address.

My Macs restart each morning at 6 AM. I log in, then, I run an AppleScript that launches several applications, and, performs other tasks.

I want to add a routine to this AppleScript that obtains and copies the external IPv4 address, and then, pastes this string into the Notes app, in a specific account and in a specific folder. I have not found any AppleScript code to perform this task.

Can anyone suggest a method to accomplish this?

Thank you.

Kurt

To get the external IP you can use this…

set Temp_IP to do shell script "curl http://myexternalip.com/raw"

or using a different service here is another…

set Temp_IP to do shell script "curl https://ipinfo.io/ip"

I’ll see if i can play with notes later.

** EDIT ** - Do you want it to create a new note or add to the currently viewed note?

Here is a sample script to add to an existing Note…

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

local noteName, theNote, tempIP, theBody

set tempIP to do shell script "curl https://ipinfo.io/ip"

set noteName to "IP Addresses"
tell application "Notes"
	if noteName is not in (name of notes) then
		set theNote to make new note with properties {name:noteName}
	else
		set theNote to note noteName
	end if
	set theBody to body of theNote
	set theBody to theBody & "<div><font face=\"Helvetica\"><span style=\"font-size: 12px\">" & tempIP & "</span></font></div>"  & linefeed
	set body of theNote to theBody
end tell

robertfern,

This is a fine piece of work.

1: During my previous research, I stumbled across:
“curl --ipv4 https://ifconfig.co
Does “curl https://ipinfo.io/ip” provide a better solution?

2: I use “iCloud - IP Addresses” instead of “IP Addresses”. I distinguish my accounts by prefacing each note name with its server name. (iCloud, Google, et cetera)

3: I use English → System Font (default) → Regular → 13 for all of my notes bodies. (I use this same font formatting, with Bold added, for the note title, which is the first line of the note. e.g. iCloud - IP Addresses) The output formatting in the Note, that your code generates, is unchanged from my font settings. What does the HTML font assignment code do?

4: Is it possible to add a date/time prefix to each IPv4 string entry? I would use the YYYY-MM-DD HH:MM:SS date/time format.

As simple as it is, the note that your script generates is cool.

My gratitude.

Kurt

I don’t understand point #2. IP Addresses are for the whole computer, not an app.
What are you trying to achieve?

robertfern,

I described item number two, poorly. I should have not provided an explanation of my Note titling method. I should have just said that I changed the Note title from “IP Addresses” to “iCloud - IP Addresses”, and then, left it at that.

Kurt

OK how’s this so far?

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

local noteName, theNote, tempIP, theBody, mydate
set mydate to getDateString(current date)
set tempIP to do shell script "curl https://ipinfo.io/ip"

set noteName to "iCloud - IP Addresses"
tell application "Notes"
	if noteName is not in (name of notes) then
		set theNote to make new note with properties {name:noteName}
		set body of theNote to "<div><h1>iCloud - IP Addresses</h1></div>"
	else
		set theNote to note noteName
	end if
	set theBody to body of theNote
	set theBody to theBody & "<div><font face=\"Helvetica\"><span style=\"font-size: 12px\">" & mydate & ", " & tempIP & "</span></font></div>" & linefeed
	set body of theNote to theBody
end tell

on getDateString(adate)
	local tm, yr, mn, dy, tid
	set {yr, mn, dy} to {year, month, day} of adate
	set {yr, mn, dy} to {yr as text, mn as integer, dy as text}
	set mn to (item (((mn > 9) as integer) + 1) of {"0", ""}) & mn
	set {tid, text item delimiters} to {text item delimiters, ":"}
	set tm to text items of time string of adate
	if (last word of last item of tm) = "PM" then set item 1 of tm to ((item 1 of tm as integer) + 12) as text
	set last item of tm to word 1 of last item of tm
	set tm to yr & "-" & mn & "-" & dy & " " & tm as text
	set text item delimiters to tid
	return tm
end getDateString

Robert,

As I said, this is a fine piece of work. It will do, fine.

My gratitude.

Regards,

Kurt

Robert,

Your AppleScript revealed a changed IP address, just this morning. This was unexpected, but, welcomed. It also prompted two ideas.

Each morning, I run my startup AppleScript, which now includes your code to write the router IP address to Notes. Both Macs write their corresponding external IP addresses to the same Notes note. I synchronize Notes through iCloud across both Macs and my iPhone and iPad.

While examining the note content, which now includes the two different external IP addresses for two different Macs, I thought that it would be helpful to include the Mac name and both the local Ethernet IP address and the local Wi-Fi IP address. One of the Macs uses Ethernet for its network connection, while the other uses Wi-Fi. Infrequently, the Mac local IP address changes.

Overnight (literally) the script has demonstrated its value. These additions would increase its capability.

Regards,

Kurt

Try this…

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

local noteName, theNote, externalIP, lanIP, wifiIP, theBody, mydate
set mydate to getDateString(current date)
set externalIP to do shell script "curl https://ipinfo.io/ip"

set noteName to "iCloud - IP Addresses"
set lanIP to getIP(0)
set wifiIP to getIP(1)
tell application "Notes"
	if noteName is not in (name of notes) then
		set theNote to make new note with properties {name:noteName}
		set body of theNote to "<div><h1>iCloud - IP Addresses</h1></div>"
	else
		set theNote to note noteName
	end if
	set theBody to body of theNote
	set theBody to theBody & "<div><font face=\"Helvetica\"><span style=\"font-size: 12px\">" & mydate & ", " & (computer name of (system info)) & ", External-IP:" & externalIP & ", Lan-IP:" & lanIP & ", Wifi-IP:" & wifiIP & "</span></font></div>" & linefeed
	set body of theNote to theBody
end tell

on getDateString(adate)
	local tm, yr, mn, dy, tid
	set {yr, mn, dy} to {year, month, day} of adate
	set {yr, mn, dy} to {yr as text, mn as integer, dy as text}
	set mn to (item (((mn > 9) as integer) + 1) of {"0", ""}) & mn
	set {tid, text item delimiters} to {text item delimiters, ":"}
	set tm to text items of time string of adate
	if (last word of last item of tm) = "PM" then set item 1 of tm to ((item 1 of tm as integer) + 12) as text
	set last item of tm to word 1 of last item of tm
	set tm to yr & "-" & mn & "-" & dy & " " & tm as text
	set text item delimiters to tid
	return tm
end getDateString

on getIP(n as integer)
	local anIP, p, ans
	set anIP to do shell script "ifconfig en" & n -- ethernet IP --| grep inet | awk '{print $2}'
	set anIP to paragraphs of anIP
	set ans to "inactive"
	repeat with p in anIP
		if word 1 of p = "inet" then
			set ans to word 2 of p
			exit repeat
		end if
	end repeat
	return ans
end getIP

Robert,

AppleScript returned the following:

error “ifconfig: interface en0 does not exist” number 1

One month after my Mac Studio warranty expired, the internal Ethernet port failed. I purchased an Anker USB C to Gigabit Ethernet Adapter. Is en0 the internal Ethernet port?

Kurt

Yes, en0 is the internal Ethernet.
If you run “System Information”, go to the Network section and it will list the available network interfaces. and their BSD Device Names

BSD Device Name: en6

The other Mac possesses a functional en0 Ethernet port.

Can you query en0, and, if it does not respond, then, ignore it, so as to avoid the error message, yet, maintain the en0 functionality for the Mac that possesses the functional en0 Ethernet port?

Here is a better version…

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

local noteName, theNote, externalIP, lanIP, wifiIP, theBody, mydate
set mydate to getDateString(current date)
set externalIP to do shell script "curl https://ipinfo.io/ip"
set noteName to "iCloud - IP Addresses"
tell getNet()
	try
		set lanIP to my getIP(ethernet of it)
	on error
		set lanIP to "inactive"
	end try
	try
		set wifiIP to my getIP(wifi of it)
	on error
		set wifiIP to "inactive"
	end try
end tell

tell application "Notes"
	if noteName is not in (name of notes) then
		set theNote to make new note with properties {name:noteName}
		set body of theNote to "<div><h1>iCloud - IP Addresses</h1></div>"
	else
		set theNote to note noteName
	end if
	set theBody to body of theNote
	set theBody to theBody & "<div><font face=\"Helvetica\"><span style=\"font-size: 12px\">" & mydate & ", " & (computer name of (system info)) & ", External-IP:" & externalIP & ", Lan-IP:" & lanIP & ", Wifi-IP:" & wifiIP & "</span></font></div>" & linefeed
	set body of theNote to theBody
end tell

on getDateString(adate)
	local tm, yr, mn, dy, tid
	set {yr, mn, dy} to {year, month, day} of adate
	set {yr, mn, dy} to {yr as text, mn as integer, dy as text}
	set mn to (item (((mn > 9) as integer) + 1) of {"0", ""}) & mn
	set {tid, text item delimiters} to {text item delimiters, ":"}
	set tm to text items of time string of adate
	if (last word of last item of tm) = "PM" then set item 1 of tm to ((item 1 of tm as integer) + 12) as text
	set last item of tm to word 1 of last item of tm
	set tm to yr & "-" & mn & "-" & dy & " " & tm as text
	set text item delimiters to tid
	return tm
end getDateString

on getIP(net)
	local anIP, p, ans
	set anIP to do shell script "ifconfig " & net -- network IP
	set anIP to paragraphs of anIP
	set ans to "inactive"
	repeat with p in anIP
		if word 1 of p = "inet" then
			set ans to word 2 of p
			exit repeat
		end if
	end repeat
	return ans
end getIP

on getNet()
	local tid, netReport, netName, ans
	set netReport to rest of paragraphs of (do shell script "networksetup -listnetworkserviceorder")
	set tid to text item delimiters
	set text item delimiters to return
	set netReport to netReport as text
	set text item delimiters to return & return
	set netReport to text items of netReport
	set text item delimiters to {space, return}
	set ans to {}
	repeat with anItem in netReport
		set netName to text item 2 of anItem
		if netName = "Wi-fi" then
			set ans to ans & {wifi:last word of anItem}
		else if netName = "Ethernet" then
			set ans to ans & {ethernet:last word of anItem}
		end if
	end repeat
	set text item delimiters to tid
	return ans
end getNet

Robert,

The script does not include the code for Ethernet port en6. The home Mac uses en6. The office Mac uses en0. I did not make this clear. The script should test for both.

Otherwise, this script does what I need.

Kurt