Instant message with Telegram with Node-RED and AppleScript

Lets say you are looking for a solution to send instant message from AS to mobile device.
Maybe you have limited knowledge about programming but you do know AppleScript.

To make instant message we will use Telegram.

  1. You need a token and chatId
    You could go here to get it: https://telegram.org

The script use 2 arguments: content message to send, chatId.

Why is this useful
The AppleScript could ask for any information and feed that message to Node-Red that later send instant message to mobile device. Anything is possible with very little knowledge and programming skills. Node-Red is a event-driven approach that make automation connection with many different protocols. In return the user do not need to program whose API in low level programming or frameworks.

Ps. I’m sure other approaches to use Apple message is possible, but what will you do if you like to send a message to a user who do not use a iPhone.

use framework "Foundation"
use scripting additions

on run argv
	set aList to {}
	try
		set countItems to count items of argv
		repeat with i from 1 to countItems
			if countItems > 0 then
				copy item i of argv to end of aList
			end if
		end repeat
	end try
	
	-- the handler
	its makeJSONString(sendingMessage(item 1 of argv, item 2 of argv))
end run

on sendingMessage(theMessage, theChatId)
	return {chatId:theChatId, type:"message", content:theMessage}
end sendingMessage

on makeJSONString(theRecord)
	set {theData, theError} to current application's NSJSONSerialization's dataWithJSONObject:theRecord options:0 |error|:(reference)
	if theData is missing value then error (theError's localizedDescription() as text)
	set theString to current application's NSString's alloc()'s initWithData:theData encoding:(current application's NSUTF8StringEncoding)
	return theString as text
end makeJSONString

The flow in Node-Red to test…

Here is other example… to follow my first message in this topic.

This example will get data from Numbers from a specific Sheet, Table, Cell and Column
Return a record to feed the message to Node-Red.

This example only use 1 argument in the run handle and that is is chatId

The rest will use AppleScript to get data from Numbers. If everything is working you will have a
instans message in Telegram with the Category and Value from Numbers.

use framework "Foundation"
use scripting additions

on run argv
	set aList to {}
	try
		set countItems to count items of argv
		repeat with i from 1 to countItems
			if countItems > 0 then
				copy item i of argv to end of aList
			end if
		end repeat
	end try
	
	-- get data from numbers
	set theData to getDataFromCells()
	set {theName, theValue} to {its category of theData, its value of theData}
	
	-- the handler
	its makeJSONString(sendingMessage(theName & ":" & theValue, item 1 of argv))
end run

on getDataFromCells()
	tell application "Numbers"
		set theDoc to make new document with properties {document template:template "Simple Budget"}
		tell theDoc to tell sheet "Budget"
			set theTable to table "Expenses"
			tell theTable
				set theCell to 2
				{category:its value of cell theCell of column 1, |value|:its value of cell theCell of column 2}
			end tell
		end tell
	end tell
end getDataFromCells

on sendingMessage(theMessage, theChatId)
	return {chatId:theChatId, type:"message", content:theMessage}
end sendingMessage

on makeJSONString(theRecord)
	set {theData, theError} to current application's NSJSONSerialization's dataWithJSONObject:theRecord options:0 |error|:(reference)
	if theData is missing value then error (theError's localizedDescription() as text)
	set theString to current application's NSString's alloc()'s initWithData:theData encoding:(current application's NSUTF8StringEncoding)
	return theString as text
end makeJSONString

The idea about AppleScript was to find a way to be able to send message between applications.
The solution Apple choose to do it was Apple Events. Apple Events is a event-driven programming or inter-process communication IPC.

So when you think about it, is not that what Node-Red does in some ways.

Inputs, function and outputs

When we think a task to be inputs, function or outputs it become clear or make it more easier to
understand different technology or API’s.

  1. Web application trigger a event to execute a unix command.
  2. The unix command ask the user for input
  3. The unix command execute functions to get data from other application or process.
  4. The data is converted to JSON format
  5. Trigger a function with data to send data or payload’s to a service.
use framework "Foundation"
use scripting additions

on run argv
	set aList to {}
	try
		set countItems to count items of argv
		repeat with i from 1 to countItems
			if countItems > 0 then
				copy item i of argv to end of aList
			end if
		end repeat
	end try
	
	-- get data from Numbers.app
	set theNumber to (display dialog "Choose category row" default answer "Type a number greater and 2 as integer")'s text returned
	set theData to getDataFromCellsWithRow(theNumber as integer)
	set {theName, theValue} to {its category of theData, its value of theData}
	
	-- Quit the apps (Numbers.app)
	its quitAll()
	
	-- the handler
	return its makeJSONString(sendingMessage(theName & ": " & theValue, item 1 of argv))
end run

on quitAll()
	tell application "Numbers"
		if application "Numbers" exists then
			quit
		end if
	end tell
end quitAll

on getDataFromCellsWithRow(theRow)
	tell application "Numbers"
		set theDoc to make new document with properties {document template:template "Simple Budget"}
		tell theDoc to tell sheet "Budget"
			set theTable to table "Expenses"
			tell theTable
				set theCell to theRow
				return {category:its value of cell theCell of column 1, |value|:its value of cell theCell of column 2}
			end tell
		end tell
	end tell
end getDataFromCellsWithRow

on sendingMessage(theMessage, theChatId)
	return {chatId:theChatId, type:"message", content:theMessage}
end sendingMessage

on makeJSONString(theRecord)
	set {theData, theError} to current application's NSJSONSerialization's dataWithJSONObject:theRecord options:0 |error|:(reference)
	if theData is missing value then error (theError's localizedDescription() as text)
	set theString to current application's NSString's alloc()'s initWithData:theData encoding:(current application's NSUTF8StringEncoding)
	return theString as text
end makeJSONString