Get your free trail of Salsa

Advocacy Campaign Developer Documentation

There are three basic versions of the action tools.

Campaign Tool
A number of clients are still using a legacy version of actions, which is build is JSP. Developers can build custom pages which access the same JSP tools.
Advocacy Campaigns (Actions 2)
Most using "Actions 2", which is build in salsascript, but not very extendable.
Advocacy Campaigns 3
The next generation of actions supports target hooks and action style hooks. Target hooks allow third-party developers to define new kinds of targets, with custom UIs and restrictions. Style hooks let you define "kinds" of actions, like a petition, targeted action, or click-to-call script. That will be released in a few weeks, but we do have one third-party already developing on it.
The rest of this document will describe Advocacy Campaigns 3.

If you're new to Developing in Actions, try the tutorial! If you need to understand the process the actions framework uses to identify targets or if normal styles do not provide enough flexibility, see the Actions 3 Process.

Action Styles

Action styles define the user-facing look of a kind of action. A metadata.sjs file sets options for how the action will work, and when users come to the action page, the action framework will identify content and targets and pass these to the action style index.sjs page display and any further processing.

Action styles are defined in hook directories, at _hooks/action/styles. For example, the petition action is at _hook/action/styles/petition. This directory should have two files:
metadata.sjs
metadata is JSON object, which mostly defines the HQ interface for the action style. The following attributes are supported:
name: string
The name of this action style. e.g., Petition, Targeted.
description: string
The style description, shown when present style options
fullStyleControl: boolean (default: false)
Use the fullStyleControl to override the entire public facing page. This will bipass the targeting framework, so that the style will usually have to access or recreate the targeting logic themselves.
multipleSets: boolean
Does this style support multiple sets of content?
multipleLetters: boolean
Does this style support multiple letters within each set?
noTargets: boolean
Does this action take target recipients, as defined in a clients custom recipients and target hooks?
defaultContentSubject: string
The default subject for new content.
defaultContentContent: string.
The default content field for new content.
optionHideEmailLimit: boolean
Do not show the email limit on the Options workflow tab.
optionHideFaxLimit: boolean
Do not show the fax limit on the Options workflow tab.
showHqSignaturesLink: boolean; default: false
Show a "Show Signatures" link the HQ actions list for this action.
showHqLetterPreviewLink: boolean; default: false
Show a "Preview Letter" link the HQ actions list for this action.
submitMessage: string
The message that will be shown while the action form submission is being processed.
workflow: array of objects
The 'workflow' attribute takes an array of JSON objects. Each object is characterized by one of the following attributes:
  • 'replace': replaces a workflow tab of a given name; takes 'name' and 'path' attributes.
  • 'after', 'before': places a workflow tab after or before the given name; takes 'name' and 'path' attributes.
  • 'remove': removes a workflow tab of a given name.

In the case of 'replace', 'after', and 'before', the new tab will have a name characterized by the 'name' attribute, and the path given in 'path' will be accessed using the Crawler. The path will be prefixed by the organization's root url, and suffixed with ?key=[action key]. You may use Request.getParameter('key') to get the action key. This file must be in a public directory, and should start with "<noTemplate/>". The contents of that page will be placed inside a <form> with a submit button created by renderWorkflowSubmit(). You may include a 'noForm: true' property, in which case no form will be placed around your content, and the tab button will be created with renderWiorkflowSubmit(true) (i.e. 'continue to next step')

For example, the workflow attribute for the petition is as follows:

    workflow: [{replace: "Content", name: "Compose your Petition", path: "p/dia/action3/common/public/petition/compose.sjs"},
              {after: "User Information", name: "Signatures", path: "p/dia/action3/common/public/petition/signatures.sjs"},    
              {remove: "Targets"},
              {remove: "Topics"}]
	
defaultUserInfo: array of two strings
The first string in the array is the common-delimited list of requested information, used on the User Information tab. The second is the common-delimited list of required information. The client may change either of these.
index.sjs
After the content and target is determined by the action system, the style's index page is retrieved and handles the rest of the user's experience. It is passed three parameters: action_KEY, the action; and targets and content, both as JSON values.

The content object may have multiple indices, each of which is an action_content key, and with a corresponding value describing the values in an action_content_detail entry.

The targets parameter is an array of targets (typically either legislators from the warehouse, or custom recipients), which will typically have attributes like district_type, FH for federal House, FS for federal Senate, SH for state House, SS for state Senate; display_name, the target's name; html, an html representation of the target and some contact information; action_content_KEY, the index of the content object of the content selected by the framework for this target; and method, which may be "Email/Webform", "Fax", or "Black Hole".

The html from index.sjs will be loaded into a form that posts to api/processAction2.jsp, which saves supporters, and sends messages to targets. In addition to supporter information, it expects the following fields:

Subject[#] and Content[#] (multiple)
Each message's subject and content
target_type (one for each target)
Either 'legislator' or 'recipient'; more generally, an object name
target_key (one for each target)
Corresponding keys which identify each target
target_method (one for each target)
"Email", "Email/Webform", "Fax", or "Default"
target_subjectName (one for each target)
The corresponding subject input to be sent to this target
target_contentName (one for each target)
The corresponding content input to be sent to this target
For example, for each target, you can include the following:
	<?= target.html ?>
	<input type="hidden" name="target_type" value="<?= target.target_path || target.object ?>"/>
	<input type="hidden" name="target_key" value="<?=target.key?>"/>
	<input type="hidden" name="target_method" value="<?=target.method?>"/>
	<input type="hidden" name="target_subjectName" value="Subject"/>
	<input type="hidden" name="target_contentName" value="Content"/>
  

To test a new style, create the metadata and index files and then create an action with that style in the Advocacy Campaigns 3 HQ. Make sure that it has both content and targets. Then access it using the link at the top of the action workflow page. Unless the style uses fullStyleControl, the resulting page will always start the same way-- using the targeting framework to identify targets. Once targets are identified, the style's public index page will be included into the action page.

For an example of an action style, see the petition files: metadata.sjs, index.sjs, and compose.sjs. Note that the package containing new style hooks must be installed before they can be used.

For additional information, see instructions for Overriding the Composition Tab and Overriding the Targeting Process.

Action Targets

Action targets are defined in hook directories, at _hooks/action/targets. Target hooks return a JSON object defining a collection of targets and the UI for selecting them. That object supports the following attributes:
name: string
The name of the kind of targets. e.g., "US House"
getName: function
Takes a target object and returns a HQ-style name for that describes the target (for example, including district and party).
getHTML: function
Takes a target object and returns a box of HTML to present the target to users. Often this will include contact information and a photo.
helpText: string
Help text presented on the target filter workflow
filterHTML: string
The form used to filter targets. It is useful to use Response.buffer.start() and Response.buffer.dump() so that the contents of this form may be constructed directly in the target hook file, without resorting to string acrobatics.
targets: array of objects
The results from either the filter form or the user action will be passed to the hook to generate a list of targets. This attribute should contain a list of all the targets that satisfy the filter or supporter action. If the noTargets parameter is supplied, it should return []. If all selected targets should be returned (as in the case of custom recipients), use the keys parameter which will contain a list of keys.
requiredFields: array of strings
The 'targeting' fields required when a supporter takes an action. The action framework currently understands 'postal_code', 'region', and 'FH' (federal House district). This may be a name in the dia/action3/common/public/lookup directory, such as the above, or a path, starting after p/ to a custom lookup UI.
unFilterable: boolean (optional)
Should the "Filter" link appear next to this entry on the Targets tab?