Skip to content

fixthestatusquo/proca

Proca Progressive Campaigning

Proca is an open-source campaign toolkit designed to empower activists and organisations in their digital advocacy efforts. It provides a flexible and customisable platform for creating and managing online petitions, email campaigns, and other forms of digital engagement, enabling users to effectively mobilise supporters and drive social change.

One of Proca's standout features is its robust support for coalition campaigns, allowing multiple organisations to collaborate seamlessly on shared initiatives. This coalition functionality enables partners to pool resources, amplify their collective voice, and reach a broader audience whilst maintaining individual branding and supporter relationships. By facilitating data sharing and joint campaign management, Proca helps coalitions to maximise their impact, streamline operations, and present a united front on critical issues, all whilst ensuring compliance with data protection regulations.

  • provide a state of the art campaiging tool
  • integrate with the campaign website, so no new CMS to learn
  • work with coalitions and GDPR
  • privacy first, every personal data of your supporter is encrypted with your organisation key

You want to engage your members and ask them to take an online action? Well, you won't be the first organisation, and you will soon realise that they aren't any decent looking petition tool that are easy to install and configure.

And this is what this tool solves.

Alternatively, we are providing this Campaign tool as a Service and are hosting and maintaining it for you if you prefer. It's definitely cheaper and easier if you have a one-off campaign, and cost effective if you have a more specific need or want us to provide some custom development.

Guiding principles and design

  • Focussed: this tool should do as little as possible. It doesn't have to be managing the content/layout of your campaign. You have already a prefered CMS for that, or can spin a wordpress one in no time. We provide action/petition widgets that you can embed into your site, we don't want to be yet another site you need to manage
  • Build relationship: We don't believe a petition is only a step in your campaign. Collecting your supporters information so you can contact them later for report back, quickers, more actions and campaigns
  • Privacy: We will always ask the people taking action to consent to their contact details being shared with your org. We will never use these contacts without their/and your consent.
  • Sharing is caring: We have seen how supporters can use social media to convince others to join. We see the designed the share step as a key component to this tool
  • Integrated: with your CRM/mailing list. If your supporter consented it, it should be as simple as possible to have their contact detail into your mailing plateform. CSV download is not simple, timeconsuming and errorprone.
  • Support coalitions: A successful campaign will have multiple partners. We make it easy to aggregate the signature counts, we make it easy to have multiple widgets for each partner (with different consent going to different CRMs)

Embeded in your existing website

Introducing a new tool is often a source of frustration for the users (new login, new interface to learn, new workflow, new bugs) and extra work for the IT team (adapt the layout). There are as well the issue of introducing a new domain/subdomain (weak SEO, potential confusion for your supporters).

Our solution? This petition tool is as transparent as possible and embed the action into one (or several) of your existing pages).

With a bit of javascript or even just html, you can control and adjust the text or layout of your widget.

The widget can also send you events to let you know what your supporters have done, and allow you to update the journey, display extra information or whaterver you want to do ;)

Full encryption mode

If the campaigner organisation provides an encryption key (based on NaCl, probably the best elliptic curve encryption solution), we store the signatures and actions encrypted. We will not be able to read them anymore. Even if the bad guys compromise the security of our server, they will not be able to read any personal data either, because the campaign organisation (having the key) is the only one that can

This simplify GDPR and other privacy compliance: we do not store any personal data, only encrypted blobs of data that we can't read.

Privacy

We are fully GDPR compliant. As part of a mandatory element of the signature form, we do ask the signatory to consent to be contacted, and record that information.

Performance

Benchmarked at > 1'000'000 signatures per hour on a 16 cores.

Technology

Front and back are clearly separated. the backend is headless, ie it only provides a graphQL API (so it's easier to build a different front-end for a specific org or campaign).

  • front-end: react, react-hook-form and material-ui
  • Back-end: elixir
  • api: graphql

Setup and 3 min intro

  • git clone this repository

  • npm install

  • npx proca config folder

  • proca config init --token API-xxx

  • get your widget's configuration from the server

    npx proca widget pull -i 42

    This will create the configuration file for the widget with id 42. it does also pull the configuration for the campaign into config/campaign/{shortname}.json

  • edit config/42.json or the config/campaign to adjust the steps, configure the components, change the color, whatever)

  • npx proca widget serve -i 42 runs a local server with the widget

  • npx proca widget build -i 42 generates the widget under d/{actionpage.NAME of the widget}

  • npx proca widget push -i 42 save the local config (under config) to the server

You can find more information in this config documentation

Documentation and Translation

One of the most common contribution we receive is help on the translations. We are using weblate and you are encouraged to participate, either to improve any of our 46 existing languages or request a new one.

We are usually following the material-ui guidelines:

  • Be concise
  • Use the present tense to describe product behavior
  • Use simple, direct language that makes content easy to understand.
  • Avoid using punctuation in places where it isn't necessary
  • Use common words that are clearly and easily understandable across all reading levels
  • Be inclusive

We strive to use an inclusive language in the code, translations, documentation and issue tracker. By contributing to this project, you agree to listen when someone raise an issue that doesn't affect you directly, reflect on it and refrain to argue endlessly. Atalassian has a good list that isn't meant to be exclusive but a starting point.

Community and code of conduct

Our vision is for radical change in society in a socialist, feminist, antiracist and sustainable direction. Our role within that is to make online campaigning easier and more effective and we are building a flexible and easy to use action tool which has all the useful features to help progressive campaigners change the world. We hope to help grow a diverse online community of progressive campaigners, technologists and activists who will support each other, share tricks and stories and grow together.

Before starting to change something, we recommend you to contact us (create an issue on github is fine), who knows, what you need might already be almost there, we are just missing some documentation and explanation.

Please note that this project is released with a Contributor Covenant. By participating in this project you agree to abide by its terms.

All the commands

These are all the command line commands to build and manage the locale cache (by default under the config folder). To see all the other commands, check proca-cli

proca campaign markdown

generate a markdown based on the config file of the campaign

USAGE
  $ proca campaign markdown [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n <value> | -x
    <value>] [--lang <value>]

FLAGS
  -i, --id=<value>
  -n, --name=<value>
  -x, --dxid=<value>  dxid
      --env=<value>   [default: default] allow to switch between configurations (server or users)
      --lang=<value>  [default: en] language to display as markdown

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  generate a markdown based on the config file of the campaign

proca campaign pull

pull the campaign from the server to the config file

USAGE
  $ proca campaign pull [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n <value> | -x
    <value>] [--git]

FLAGS
  -i, --id=<value>
  -n, --name=<value>
  -x, --dxid=<value>  dxid
      --env=<value>   [default: default] allow to switch between configurations (server or users)
      --[no-]git      commit the changes to git

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  pull the campaign from the server to the config file

proca campaign push

push the campaign from the config file to the server

USAGE
  $ proca campaign push [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n <value> | -x
    <value>] [--git]

FLAGS
  -i, --id=<value>
  -n, --name=<value>
  -x, --dxid=<value>  dxid
      --env=<value>   [default: default] allow to switch between configurations (server or users)
      --[no-]git      commit the changes to git

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  push the campaign from the config file to the server

proca campaign read

Reads a campaign configuration file

USAGE
  $ proca campaign read [--env <value>] [--json | --csv | --markdown] [--simplify] [-i <value> | -n <campaign> | -x
    <value>] [--config] [--locale <value>]

FLAGS
  -i, --id=<value>
  -n, --name=<campaign>  name (technical short name, also called slug)
  -x, --dxid=<value>     dxid
      --[no-]config      display the config
      --env=<value>      [default: default] allow to switch between configurations (server or users)
      --locale=<value>   display a locale

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  Reads a campaign configuration file

ALIASES
  $ proca campaign read

proca campaign translate

Translate a campaign's locale file from one language to another.

USAGE
  $ proca campaign translate --to <value> [--json | --csv | --markdown] [--env <value>] [--simplify] [-n <campaign>]
    [--from <value>] [--force] [--namespace <value>] [--dry-run]

FLAGS
  -n, --name=<campaign>    name (technical short name, also called slug)
      --dry-run            Perform a dry run without saving changes
      --env=<value>        [default: default] allow to switch between configurations (server or users)
      --force              Force overwrite of existing translations.
      --from=<value>       [default: en] Source language for translation.
      --namespace=<value>  Limit translation to a specific namespace (e.g., common, campaign, letter)
      --to=<value>         (required) Target language for translation.

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  Translate a campaign's locale file from one language to another.

proca campaign widget pull

pull all the widgets of a campaign

USAGE
  $ proca campaign widget pull [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n
    <the_short_name> | -x <value>]

FLAGS
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
      --env=<value>            [default: default] allow to switch between configurations (server or users)

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  pull all the widgets of a campaign

EXAMPLES
  $ proca-cli campaign widget pull climate-action

proca locale campaign read

Reads a campaign configuration file

USAGE
  $ proca locale campaign read [--env <value>] [--json | --csv | --markdown] [--simplify] [-i <value> | -n <campaign> | -x
    <value>] [--config] [--locale <value>]

FLAGS
  -i, --id=<value>
  -n, --name=<campaign>  name (technical short name, also called slug)
  -x, --dxid=<value>     dxid
      --[no-]config      display the config
      --env=<value>      [default: default] allow to switch between configurations (server or users)
      --locale=<value>   display a locale

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  Reads a campaign configuration file

ALIASES
  $ proca campaign read

proca locale pull

git pull of the config folder from the remote main

USAGE
  $ proca locale pull

DESCRIPTION
  git pull of the config folder from the remote main

proca locale push

git push of the config folder to the remote main

USAGE
  $ proca locale push

DESCRIPTION
  git push of the config folder to the remote main

proca locale status

git status of the config folder

USAGE
  $ proca locale status

DESCRIPTION
  git status of the config folder

proca locale widget read

Reads a widget configuration file

USAGE
  $ proca locale widget read [--env <value>] [--json | --csv | --markdown] [--simplify] [-i <value> | -n <widget> | -x
    <value>] [--config]

FLAGS
  -i, --id=<value>
  -n, --name=<widget>  name (technical short name, also called slug)
  -x, --dxid=<value>   dxid
      --[no-]config    display the config
      --env=<value>    [default: default] allow to switch between configurations (server or users)

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  Reads a widget configuration file

ALIASES
  $ proca widget read

proca target publish

publish the targets for the campaign to be accessible from the widget

USAGE
  $ proca target publish [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n
    <the_short_name> | -x <value>] [--campaign] [--git]

FLAGS
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
  --[no-]campaign
      --env=<value>            [default: default] allow to switch between configurations (server or users)
      --[no-]git               commit the changes to git

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  publish the targets for the campaign to be accessible from the widget

proca template push

push to the server a template

USAGE
  $ proca template push [--json | --csv | --markdown] [--env <value>] [--simplify] [-n <the_short_name>] [-i
    <value>] [-x <value>] [-c <value>] [--git]

FLAGS
  -c, --campaign=<value>       push all the widgets of that campaign [WIP]
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
      --env=<value>            [default: default] allow to switch between configurations (server or users)
      --[no-]git               commit the changes to git

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  push to the server a template

EXAMPLES
  $ proca template push -o <organisation>

proca widget build

build the widget

USAGE
  $ proca widget build [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n
    <the_short_name> | -x <value>]

FLAGS
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
      --env=<value>            [default: default] allow to switch between configurations (server or users)

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  build the widget

proca widget pull

pull the widget (and campaign) configuration from the server

USAGE
  $ proca widget pull [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n <widget> | -x
    <value>] [--campaign] [--git]

FLAGS
  -i, --id=<value>
  -n, --name=<widget>  name (technical short name, also called slug)
  -x, --dxid=<value>   dxid
      --[no-]campaign  pull the campaign as well
      --env=<value>    [default: default] allow to switch between configurations (server or users)
      --[no-]git       commit the changes to git

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  pull the widget (and campaign) configuration from the server

proca widget push

push to the server the local configuration of the widget

USAGE
  $ proca widget push [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n
    <the_short_name> | -x <value>] [--git]

FLAGS
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
      --env=<value>            [default: default] allow to switch between configurations (server or users)
      --[no-]git               commit the changes to git

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  push to the server the local configuration of the widget

proca widget read

Reads a widget configuration file

USAGE
  $ proca widget read [--env <value>] [--json | --csv | --markdown] [--simplify] [-i <value> | -n <widget> | -x
    <value>] [--config]

FLAGS
  -i, --id=<value>
  -n, --name=<widget>  name (technical short name, also called slug)
  -x, --dxid=<value>   dxid
      --[no-]config    display the config
      --env=<value>    [default: default] allow to switch between configurations (server or users)

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  Reads a widget configuration file

ALIASES
  $ proca widget read

proca widget serve

serve the local version of the widget

USAGE
  $ proca widget serve [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n
    <the_short_name> | -x <value>]

FLAGS
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
      --env=<value>            [default: default] allow to switch between configurations (server or users)

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  serve the local version of the widget

proca widget view

view the widget

USAGE
  $ proca widget view [--json | --csv | --markdown] [--env <value>] [--simplify] [-i <value> | -n
    <the_short_name> | -x <value>] [--preview]

FLAGS
  -i, --id=<value>
  -n, --name=<the_short_name>  name (technical short name, also called slug)
  -x, --dxid=<value>           dxid
      --env=<value>            [default: default] allow to switch between configurations (server or users)
      --preview                view the preview widget instead of the live version

OUTPUT FLAGS
  --csv            Format output as csv
  --json           Format output as json
  --markdown       Format output as markdown table
  --[no-]simplify  flatten and filter to output only the most important attributes, mostly relevant for json

DESCRIPTION
  view the widget

About

Widget to transform your website into a cutting-edge campaign in 10 min. multi-lingual, privacy first.

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Contributors

Languages