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?