Skip to content

About

Go application to facilitate the onboarding process of a new churchtools using community, if their members have been importet from an source of unknown quality.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

23 Commits

Folders and files

Repository files navigation

ChurchTools_Invite

Go Release License: MIT (Modified) Support: CFI-Kinderhilfe Build Status

Deutsch English (current)

Churchtools-invite is a lightweight Go CLI for mass ChurchTools system invitations from a CSV file, including:

  • CSV import with person IDs and optional e-mail sync
  • REST API invitations (POST /persons/{id}/invite)
  • Person export with campus, invitation and group filters; by default only persons not yet invited
  • Setup, dry-run and permission helpers
  • Skip already invited persons by default; if the CSV e-mail differs, update the address and invite again (--reinvite re-sends to persons with status Eingeladen only; Registriert is always skipped)

Features

  • Read person IDs from CSV (id, person_id, ct_id, …)
  • Send invitation e-mails via the ChurchTools REST API
  • Export persons (campus, invitation status, group; interactive selection)
  • Setup commands for instance name, login token, connection test and permission hints
  • Dry-run mode to check CSV and person data before sending
  • Sync CSV e-mail to ChurchTools when it differs (old address kept as additional)
  • Skip already invited persons when the e-mail matches; if the CSV e-mail differs, update and invite again; --reinvite re-sends to Eingeladen only (persons with status Registriert are never invited again)
  • Automatic group membership request when export or e-mail sync permissions are missing

Requirements

  • Go 1.26+ (for building from source)
  • ChurchTools account with permission Invite persons to ChurchTools
  • For export: export data permission (group “Personen exportieren”)
  • For e-mail sync on invite: write access permission (group “Personen bearbeiten”)
  • Login token or username/password

Installation

Binary download

Pre-built binaries for Linux, macOS, and Windows: Releases

Extract the archive and run churchtools-invite (churchtools-invite.exe on Windows).

Go Install

go install github.com/janmz/churchtools-invite@latest

Build from Source

git clone https://github.com/janmz/ChurchToolsInvite.git
cd ChurchToolsInvite
go build -o churchtools-invite .

On Windows the executable is churchtools-invite.exe.

Usage

Quick Start

cp config.example.json config.json
# edit config.json or run setup init

./churchtools-invite setup test
./churchtools-invite export -o personen.csv

Edit the list manually, then dry-run:

./churchtools-invite invite -f personen.csv --dry-run
./churchtools-invite invite -f personen.csv

Global option: -c config.json for an alternate config path.

Configuration

Copy config.example.json to config.json or use environment variables:

Variable Description
CT_BASE_URL Instance name (e.g. meine-gemeinde) or full URL (https:// only; http:// only for localhost)
main_url / CT_MAIN_URL Main (central) instance for a sub-instance login; only used when set explicitly
CT_LOGIN_TOKEN API login token
CT_USERNAME / CT_PASSWORD Alternative to token
delay_ms Pause after each invitation or e-mail update in milliseconds, 0–60000 (default: 500; skipped rows cause no pause)
campus_id Default campus when the user has none (set interactively on first export)
pre_join_groups Comma-separated groups to join in order before export/invite (default in config.example.json; set - to disable)
CT_PRE_JOIN_GROUPS Environment override for pre_join_groups

Obtain a login token:

./churchtools-invite setup init
# or, after login:
./churchtools-invite setup token

Main and sub-instance (OAuth)

In multi-campus ChurchTools setups, a sub-instance URL may look like https://main-sub.church.tools (e.g. https://meine-gemeinde-unterstadt.church.tools). User accounts live on the central instance https://main.church.tools (e.g. https://meine-gemeinde.church.tools).

The central instance is used only when it is configured as main_url (or CT_MAIN_URL). setup init suggests it for names like church-site and stores it only after confirmation – a host derived from the name could belong to another church, so credentials are never sent to a guessed host.

If direct login on the sub-instance fails and main_url is set, username/password auth runs the OAuth bridge (when direct login succeeds, OAuth is skipped):

  1. Login on the central instance (/api/login)
  2. oauthclients/…/startlogin on the sub-instance (redirect to central)
  3. OAuth authorize using the central session
  4. Callback on the sub-instance → local session
  5. API calls keep using the sub-instance (configured URL)

setup init can then fetch a sub-instance login token automatically (/api/person/me/apitoken).

If a login token is only valid on the central instance (and main_url is set), the tool falls back to the central URL for API calls (note in output).

Check permissions:

./churchtools-invite setup permissions

CSV Format

Export (export)

By default, only persons who have not been invited yet are exported. Use -i or --invited to include already invited or registered persons as well.

id,vorname,nachname,email,standort,status
123,Max,Muster,max@example.org,Rhein-Main,NEU
456,Anna,Beispiel,anna@example.org,Rhein-Main,Eingeladen
789,Tim,Test,tim@example.org,Rhein-Main,Registriert
  • status column: NEU (not yet invited), Eingeladen (invitation pending) or Registriert (ChurchTools account already accepted)
  • standort column: campus name from ChurchTools (export only)
  • Columns id, vorname, nachname, email are the invite CSV; standort and status are for manual review and are ignored on import with invite

Campus: --campus is only required when you do not want to export for your own campus, or when your user account has no campus assigned. Without --campus, export automatically uses the logged-in user's campus or campus_id from config.json.

--campus accepts either a numeric campus ID or a unique name substring. For name lookup, the campus list and search string are lowercased; everything except a–z is stripped from the search string. The tool picks the campus whose name contains the cleaned substring – there must be exactly one match (contains(campus.name, searchstring)).

Examples:

# Own campus – no --campus needed
./churchtools-invite export -o personen.csv

# Other campus by ID or unique name fragment
./churchtools-invite export -o all.csv --campus 3
./churchtools-invite export -o rheinmain.csv --campus rhein

# Include already invited/registered persons
./churchtools-invite export -o review.csv --invited

Import (invite)

id,vorname,nachname,email
123,Max,Muster,max@example.org
  • id column is required (also: person_id, ct_id)
  • Name and e-mail columns are optional; e-mail is used to update ChurchTools before inviting when it differs from the stored address
  • Extra columns such as standort and status from export are ignored

Dry-run – Check before sending

invite --dry-run runs the same checks as a real invite but does not send invitations and does not change any person (no e-mail sync). Pre-join and permission groups are still joined, because reading persons needs those rights; like in a real run they are left again at the end if you were not a member before. For each CSV row it verifies:

  • Does the person ID exist in ChurchTools?
  • Is the person already invited? Detected e.g. via invitationStatus (accepted, pending). By default: skip if the CSV e-mail matches ChurchTools; if it differs, simulate e-mail update and re-invite. Registriert persons are always skipped; --reinvite applies only to Eingeladen
  • Is there an invitation e-mail? ChurchTools always invites to the person's ChurchTools address; with --no-sync-email a person without one fails.
  • Would an e-mail sync from the CSV be required?

Output: each row is printed as soon as it is processed (OK, ÜBERSPRUNGEN or FEHLER, German labels), followed by a summary that repeats the failed rows. Exit code 1 if at least one row failed. Ctrl+C stops after the current row, prints the summary and leaves the temporary groups; a second Ctrl+C terminates immediately.

Recommended before the first real run. All invite options (--reinvite, --no-sync-email, …) apply to dry-run as well.

Commands

Command Purpose
setup init Interactive config.json (instance name, optional main instance, hidden password/token input)
setup test Test login and connection
setup token Fetch your own login token and store it encrypted in config.json (never printed)
setup permissions List invite-related permissions
whoami Show logged-in user, campus, group memberships (sorted by name, format Name ID) and instance URL
export -o FILE Export persons to invite CSV format (default personen.csv; - = stdout, hints go to stderr); by default only not-yet-invited persons
export --force Overwrite an existing output file (otherwise the export stops)
export -i / --invited Export all invitation statuses (NEU, Eingeladen, Registriert)
export --interactive Choose campus, optional filters (person status, group) and invitation status ([n] Neu, [e] Eingeladen, [r] Registriert)
export --campus VALUE Campus by ID or unique name substring (see CSV format); only needed for a different campus or when the user has no campus
export --campus all All campuses (alias for --all-campuses)
export --all-campuses No campus filter
export --status VALUE Only persons with this person status (member, guest, …) – ID or name, e.g. --status Mitglied; old name --status-id still works. Not the invitation status of the CSV column status
export --group VALUE Only members of this group – ID or name (unique part is enough); old name --group-id still works
list statuses Person statuses of your instance with ID and name (each church defines its own, IDs differ per instance)
list groups [--campus X] [--search TEXT] Groups with ID and name
list campuses Campuses with ID and name
export --skip-permission-request Do not request group membership for missing export rights
export --skip-pre-join-groups Skip pre-join groups before export
invite -f FILE Send invitations
invite -f FILE --dry-run Check/simulate without sending (see above)
invite -f FILE --delay-ms MS Pause after each invitation/e-mail update, 0–60000 (0 = delay_ms from config)
invite -f FILE --no-sync-email Skip CSV e-mail sync (mismatched e-mail → error)
invite -f FILE --reinvite Re-invite persons with status Eingeladen; Registriert is always skipped
invite -f FILE --skip-permission-request Do not request group membership for missing rights
invite -f FILE --skip-pre-join-groups Skip pre-join groups before invite
invite -f FILE --yes / -y Run the plan without asking (scripts); not allowed when the API runs on the main instance
invite -f FILE --ignore-name-mismatch Also process rows whose CSV name differs from the ChurchTools person
invite -f FILE --allow-single-email If ChurchTools rejects the address list, replace the primary e-mail (the previous address is lost)

Development

Linux/macOS release binaries have no embedded file icon (not standard for CLI tools). Windows release builds embed project-root vaya.ico via go-winres.

Tests: Running only go test in the repo root does nothing useful (package main has no tests). Use go test ./... — see TESTING.md for coverage, conventions, and manual checks against a real ChurchTools instance.

scripts/ci.sh      # or scripts/ci.ps1: gofmt, go vet, staticcheck, tests, build
go test ./...
go build -o churchtools-invite .

staticcheck (v0.8.2) needs Go 1.26 or newer; on older toolchains set SKIP_STATICCHECK=1.

Credentials and privacy

  • Encrypted secrets: login_token and password in config.json are encrypted with sconfig on first start (login_token_secure, secure_password; the plaintext field then shows a marker). The encryption is bound to this computer – on another PC enter the secrets again. To change a secret, write the new plaintext value into login_token / password.
  • config.json must be located below the program directory, the current working directory or your home directory (sconfig rule).
  • config.json and exported CSV files are readable only by the current user (Windows ACL, 0600 elsewhere). Environment variables (CT_*) are never written to the file.
  • No fallback to guessed hosts: credentials are only sent to base_url and, if configured, main_url. Redirects to another host or scheme are refused, also in the OAuth bridge (only base and main instance, https). setup init suggests the main instance the sub-instance itself reports; a host derived from the name has to be typed in. A login-token fallback to the main instance only happens on HTTP 401, and invite then warns and requires interactive confirmation.
  • Temporary groups: groups from pre_join_groups and permission groups that the tool joins for a run are left again at the end of export / invite; memberships you had before stay untouched. Joined groups are recorded in .churchtools-invite-groups.json next to config.json; if a run ends without leaving them (crash, closed window, second Ctrl+C), the next start offers to leave them. Joining via the public group signup form is only done after confirmation.
  • setup token stores only your own token, encrypted; it is never printed.
  • The CSV contains personal data: delete it after the invitations (the tool reminds you). Cells starting with = + - @ are prefixed with ' against formula injection; invite removes the prefix again. A person ID listed twice or an invalid e-mail address (exactly one plain address per cell) is rejected before anything is sent. CSV files are restricted to the current user when they are read.
  • Plan and confirmation: before a real invite run the CSV is checked like a dry-run; the plan lists the number of invitations and every e-mail change (old → new) and asks [j/N] (--yes for scripts). Rows whose CSV name does not match the ChurchTools person (shifted row, wrong ID) fail unless --ignore-name-mismatch is given, because the account activation would otherwise go to someone else.
  • Result lines of a real run mask e-mail addresses (ma***@example.org); full addresses only appear in the dry-run and in the plan. Text from the server or the CSV is printed without control characters.
  • Release archives come with a SHA256SUMS file (sha256sum -c SHA256SUMS).

Contributing

Contributions are welcome! Please check CONTRIBUTING.md before creating a pull request.

License

This software is under a modified MIT license (see LICENSE). You may freely use, modify, and distribute the code, provided you credit the original author Jan Neuhaus, VAYA Consulting and maintain a link to the original repository: https://github.com/janmz/ChurchToolsInvite.

No warranty is provided.

Support

If you find this project helpful, please support CFI-Kinderhilfe: https://cfi-kinderhilfe.de/jetzt-spenden?q=VAYACTINVITE (Donations go to CFI-Kinderhilfe, not the author.)

Contact

Author: Jan Neuhaus, VAYA Consulting – VAYA Consulting Repository: https://github.com/janmz/ChurchToolsInvite

Changelog

See Changelog.md for release history.

About

Go application to facilitate the onboarding process of a new churchtools using community, if their members have been importet from an source of unknown quality.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Contributors

Languages