Posting to a Discourse forum from AppleScript

how-to
asobjc

(Mark Alldritt) #1

As a follow up to my post about posting to a Discourse forum from iOS Shortcuts, here is some AppleScript code that does the same thing:

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

--	Discourse properties
property APIDOMAIN : "https://forum.latenightsw.com"
property APIPOSTS_ENDPOINT : "/posts.json"
property APICATAGORIES_ENDPOINT : "/categories.json"
property APIKEY : "your-discourse-api-key"
property APIUSER : "your-discouse-username"

-- classes, constants, and enums used
property NSJSONSerialization : a reference to current application's NSJSONSerialization
property NSData : a reference to current application's NSData
property NSString : a reference to current application's NSString
property NSURL : a reference to current application's NSURL
property NSURLRequest : a reference to current application's NSURLRequest
property NSURLRequestReloadIgnoringLocalCacheData : a reference to current application's NSURLRequestReloadIgnoringLocalCacheData
property NSMutableURLRequest : a reference to current application's NSMutableURLRequest
property NSURLConnection : a reference to current application's NSURLConnection
property NSURLComponents : a reference to current application's NSURLComponents
property NSURLQueryItem : a reference to current application's NSURLQueryItem

set topicTitle to "ASObjC Test Title"
set topicMarkdown to "# AppleScript ASObjC Test

This is a test post generated from AppleScript using ASObjC to communicate with Discourse.

----

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt 
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation 
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in 
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur 
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id 
est laborum.
"

--	Let the user pick a category into which the topic will go
set categoryChoice to choose from list getDiscourseCatagories() ¬
	with prompt "Forum Category" OK button name "Post" without multiple selections allowed and empty selection allowed
if categoryChoice = false then -- user cancelled?
	return
end if
set topicCategory to item 1 of categoryChoice

--	Post the topic to the Discouse forum
postToDiscourse(topicTitle, topicCategory, topicMarkdown)


on getDiscourseCatagories()
	local theJSON, theNames -- so SD can see them
	
	--	Construct a URL containing all the query parameters needed to create a Dicourse post
	set apiKeyParam to NSURLQueryItem's queryItemWithName:"api_key" value:APIKEY
	set userParam to NSURLQueryItem's queryItemWithName:"api_username" value:APIUSER
	
	set urlComponents to NSURLComponents's componentsWithString:(APIDOMAIN & APICATAGORIES_ENDPOINT)
	urlComponents's setQueryItems:{apiKeyParam, userParam}
	
	--	Send the create post request to the Discourse site
	set theRequest to NSURLRequest's requestWithURL:(urlComponents's |URL|) ¬
		cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10
	set theResult to NSURLConnection's sendSynchronousRequest:theRequest ¬
		returningResponse:(reference) |error|:(missing value)
	set theJSONData to item 1 of theResult
	set theJSON to NSJSONSerialization's JSONObjectWithData:theJSONData options:0 |error|:(missing value)
	
	set theNames to (theJSON's valueForKeyPath:"category_list.categories.name") as list
	return theNames
end getDiscourseCatagories

on postToDiscourse(postTitle, postCategory, postMarkdown)
	local theRequest, theResult, theJSONData, theJSON -- so SD can see them
	
	--	AppleScript strings often have CR line endings while Discourse expects LF line endings.  Convert all 
	--	CRs to LFs.
	set postMarkdown to (NSString's stringWithString:postMarkdown)'s ¬
		stringByReplacingOccurrencesOfString:return withString:linefeed
	
	--	Construct a URL containing all the query parameters needed to create a Dicourse post
	set apiKeyParam to NSURLQueryItem's queryItemWithName:"api_key" value:APIKEY
	set userParam to NSURLQueryItem's queryItemWithName:"api_username" value:APIUSER
	set titleParam to NSURLQueryItem's queryItemWithName:"title" value:postTitle
	set categoryParam to NSURLQueryItem's queryItemWithName:"category" value:postCategory
	set rawParam to NSURLQueryItem's queryItemWithName:"raw" value:postMarkdown
	
	set urlComponents to NSURLComponents's componentsWithString:(APIDOMAIN & APIPOSTS_ENDPOINT)
	urlComponents's setQueryItems:{apiKeyParam, userParam, titleParam, categoryParam, rawParam}
	
	--	Send the create post request to the Discourse site
	set theRequest to NSMutableURLRequest's requestWithURL:(urlComponents's |URL|) ¬
		cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10
	theRequest's setHTTPMethod:"POST"
	set theResult to NSURLConnection's sendSynchronousRequest:theRequest ¬
		returningResponse:(reference) |error|:(missing value)
	set theJSONData to item 1 of theResult
	set theJSON to NSJSONSerialization's JSONObjectWithData:theJSONData options:0 |error|:(missing value)
	
	return theJSON
end postToDiscourse

The resulting post looks like this: