Target user:
Administrators of small scale NGOs
Value Proposition:
ContactsForGood (CFG) helps NGO administrators efficiently manage donors, volunteers, and partners by organising contacts and tracking engagement. With its typing-focused interface and offline, editable data, CFG hopes to streamline contact management, allowing administrators to focus on outreach and mission-critical tasks.
Download the latest .jar file from here.
Copy the file to the folder you want to use as the home folder for CFG (e.g. create the folder "contactsforgood" in "Documents").
Open a command terminal. Run the java -version command to ensure you are using Java 17.
Use cd to navigate to the folder containing the .jar file.
cd stands for "change directory".cd Documents/contactsforgoodUse the java -jar contactsforgood.jar command to run the application.
Your command terminal should look similar to this after steps 4 and 5 (adjusted for your folder's path).

A GUI similar to the below should appear in a few seconds after running the java -jar contactsforgood.jar command. Note how the app contains some sample data.

Type the command in the command box and press Enter to execute it. e.g. typing help and pressing Enter will open the help window.
Some example commands you can try:
list : Lists all contacts.
add r/volunteer h/30 n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01 : Adds a
contact named John Doe with a volunteer role to CFG.
delete 3 : Deletes the 3rd contact shown in the current list.
clear : Deletes all contacts.
exit : Exits the app.
Refer to the Features below for details of each command.
Notes about the command format:
UPPER_CASE are the parameters to be supplied by the user.
e.g. in add n/NAME, NAME is a parameter which can be used as add n/John Doe.Each parameter is preceded by a prefix, which indicates the type of data the parameter represents.
For example:
n/ is the prefix for NAME, as in add n/John Doe.p/ is the prefix for PHONE_NUMBER, as in add p/12345678.Any unrecognized parameter's prefix will be treated as part of the value for the preceding valid prefix. For example:
add n/John Doe p/12345678add n/John Doe xyz/12345678 (In this case, xyz/12345678 will be treated as part of the name value, which
will result in an error)Items in square brackets are optional.
e.g. n/NAME [t/TAG] can be used as n/John Doe t/friend or as n/John Doe.
Note: If an optional field is not required, avoid leaving the prefix empty, as this will result in an invalid command.
e.g. edit 1 n/ is not a valid command.
Items with … after them can be used multiple times including zero times.
e.g. [t/TAG]… can be used as (i.e. 0 times), t/friend, t/friend t/family etc.
An INDEX refers to the person at the index number shown in the last displayed person list.
The index must meet the following conditions:
Correct Format:
The index must be a positive integer (e.g. 1, 2, 3, …). Non-numeric or improperly formatted inputs (e.g. -1, abc, 1.5) will be deemed as incorrect format.
Valid Index:
The index must be within the range of the last displayed person list. Indices that are numeric but refer to non-existent entries in the list (e.g. 999 when the list has only 10 people) will be deemed as invalid indices.
INDICES takes in multiple INDEXs
INDEX can be a single number (e.g. 2) or a closed range (e.g. 5-9).INDEX is separated by spaces (e.g. of an INDICES, 1 2 3 5-9).5-9 is correct,
but 5 - 9 or 5 -9 or 5- 9 are incorrect).INDICES expects at least one INDEX unless the INDICES item is optional.n/NAME p/PHONE_NUMBER, p/PHONE_NUMBER n/NAME is also acceptable.help, exit and clear) will be ignored.
e.g. if the command specifies help 123, it will be interpreted as help.| Action | Format | Example |
|---|---|---|
| Add | add [r/ROLE] n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]… [h/HOURS] [d/DONATED_AMOUNT] [ped/PARTNERSHIP_END_DATE] | add r/volunteer n/James Ho p/81234567 e/jamesho@example.com a/123, Clementi Rd, 123456 h/19 |
| Clear | clear | clear |
| Delete | delete INDICES | delete 1 2 3 5-7 |
| Edit | edit INDEX [n/NAME] [p/PHONE_NUMBER] [e/EMAIL] [a/ADDRESS] [t/TAG]… [h/HOURS] [d/DONATED_AMOUNT] [ped/PARTNERSHIP_END_DATE] | edit 2 n/James Lee e/jameslee@example.com |
| Search | search PREFIX/KEYWORD [MORE_PREFIX/KEYWORD]… | search n/john |
| List | list | list |
| Sort | sort [s/SORT_OPTION] | sort s/name |
| Action | Format | Example |
|---|---|---|
| Create Group | createGroup g/GROUP_NAME m/INDICES | createGroup g/blood drive m/1 2 4-7 |
| Add New Members to Group | addToGroup g/GROUP_NAME m/INDICES | addToGroup g/beach cleanup m/1 2 3-6 |
| Remove Existing Members from Group | removeFromGroup g/GROUP_NAME m/INDICES | removeFromGroup g/blood drive m/1 2 3 5-7 |
| Edit Group Name | editGroupName g/OLD_GROUP_NAME g/NEW_GROUP_NAME | editGroupName g/blood drive g/blood donation |
| List Groups | listGroups | listGroups |
| Delete Group | deleteGroup g/GROUP_NAME | deleteGroup g/blood donation |
| Action | Format | Example |
|---|---|---|
| Help | help | help |
| Get Emails | email | email |
| Exit Application | exit | exit |
addThis command adds a contact to CFG. There are 4 types of contacts: Volunteer, Donor, Partner, Person (default).
Format: add [r/ROLE] n/NAME p/PHONE_NUMBER e/EMAIL a/ADDRESS [t/TAG]… [h/HOURS] [d/DONATED_AMOUNT] [ped/PARTNERSHIP_END_DATE]
ROLE (Optional): Specifies the type of contact. If not provided, the contact will be added as a general Person.NAME: The contact's full name (case-insensitive).PHONE_NUMBER: The contact's phone number (Any length is allowed, accommodating 3-digit emergency numbers to 15-digit international numbers).EMAIL: The contact's email address (Only english emails are currently supported).ADDRESS: The contact's physical address.TAG (Optional): Additional tags associated with the contact (A contact can have any number of tags, including none).Person)
h/HOURS - Represents contributed hours.d/DONATED_AMOUNT - Represents total donation amount in thousands of USD.
123.45 represents 123,450 USD).12345678 will be displayed as 1.2345678E7, equivalent to 12,345,678 thousand USD).ped/PARTNERSHIP_END_DATE - Represents the partnership's end date.
2023-03-15 (Past date).2025-10-20 (Future date).2021-02-29 (February 29 does not exist in 2021 because it is not a leap year).2023-03-33 (March does not have 33 days).Volunteer, h/HOURS is required.Donor, d/DONATED_AMOUNT is required.Partner, ped/PARTNERSHIP_END_DATE is required.add command will be deemed invalid.Examples:
add r/volunteer h/10 n/John Doe p/98765432 e/johnd@example.com a/John street, block 123, #01-01add r/donor d/100 n/Betsy Crowe t/friend e/betsycrowe@example.com a/Newgate Prison p/1234567 t/richclearClears all entries from CFG.
Format: clear
deleteDeletes the specified person from CFG.
Format: delete INDICES
INDICES.Tip: Be careful when using the delete command.
Examples:
list followed by delete 2 4 6-8 deletes the 2nd, 4th, 6th, 7th, and 8th persons in CFG.search n/Betsy followed by delete 1 3-5 deletes the 1st, 3rd, 4th, and 5th persons in the results of the
search command.editEdits an existing person in CFG.
Format: edit INDEX [r/ROLE] [n/NAME] [p/PHONE] [e/EMAIL] [a/ADDRESS] [t/TAG]… [h/HOURS] [d/DONATED_AMOUNT] [ped/PARTNERSHIP_END_DATE]
INDEX. The index refers to the index number shown in the displayed person list.t/ without specifying any tags after it.Role-specific fields must correspond to the resulting role after editing:
Volunteer, h/HOURS is required.Donor, d/DONATED_AMOUNT is required.Partner, ped/PARTNERSHIP_END_DATE is required.edit command will be invalid.Examples:
edit 1 p/91234567 e/johndoe@example.com Edits the phone number and email address of the 1st person to be 91234567 and johndoe@example.com respectively.edit 2 n/Betsy Crower t/ Edits the name of the 2nd person to be Betsy Crower and clears all existing tags.searchSearch persons whose fields match the keywords given.
Format: search PREFIX/KEYWORD [MORE_PREFIX/KEYWORD]…
hans will match Hans.search n/alex t/friends will return the same result as search t/friends n/alex.friend will not match friends.search n/Alex David returns both Alex and David).Tip: Supported search prefixes include:
NAME: n/TAG: t/PHONE_NUMBER: p/GROUP: g/ROLE: r/Examples:
name: Alex Yeoh tag: friends phone number: 87438807 role: person name: Irfan Ibrahim tag: classmates phone number: 92492021 role: person name: Charlotte Oliveiro tag: neighbours phone number: 93210283 role: personsearch n/alex returns persons with the name alex like Alex Yeoh.search r/person returns all contacts with role Person like Alex Yeoh, Irfan Ibrahim and Charlotte Oliveiro.search n/charlotte t/neighbours p/93210283 returns all persons with name matching charlotte, tag matching neighbours, phone number 93210283 like Charlotte Oliveiro. listShows a list of all persons in CFG.
Format: list
sortSorts the currently visible list of persons by a specified field.
Format: sort [s/SORT_OPTION]
sort to arrange the contacts in the list you're currently viewing, whether it's the full list or a subset from commands like search.sort will restore the currently displayed list to its default order (i.e. the order in which contacts were added).hours):
Supported sort options include:
name: Sorts contacts alphabetically by name.
hours: Sorts volunteers by hours contributed (in descending order).donations: Sorts donors by donation amount (in descending order).end_date: Sorts partners by partnership end date (from earliest to latest).Examples:
sortsort s/namesort s/hourscreateGroupCreates a new group with people as members.
Format: createGroup g/GROUP_NAME m/INDICES
GROUP_NAME.INDICES to the group.
Indices refer to the index numbers shown in the displayed person list.
There must be at least one index provided, and indices should be separated by a space.GROUP_NAME currently exists, the command will fail.Example:
createGroup g/blood drive 2024 m/3 4 creates a new group named blood drive 2024
with the 3rd and 4th persons in the current list in view as members.addToGroupAdds new members to a group that currently exists.
Format: addToGroup g/GROUP_NAME m/INDICES
GROUP_NAME.GROUP_NAME. The indices
must be valid indices.Example:
addToGroup g/blood drive 2024 m/1 2 5 6 adds the persons at index 1, 2, 5 and 6 of
the current list in view as members to the existing group named blood drive.removeFromGroupRemove members from a group that currently exists.
Format: removeFromGroup g/GROUP_NAME m/INDICES
GROUP_NAME.GROUP_NAME. The indices
must be valid indices.Example:
removeFromGroup g/blood drive 2024 m/1 2 5 6 removes the persons at index 1, 2, 5 and 6 of
the current list in view from the existing group named blood drive.Tip: For ease of use, first list out the people in the group using the search command, then remove persons using this command.
editGroupNameEdits the name of a group that currently exists.
Format: editGroupName g/OLD_GROUP_NAME g/NEW_GROUP_NAME
OLD_GROUP_NAME to NEW_GROUP_NAME.Example:
editGroupName g/blood drive 2024 g/charity run renames an existing group called
blood drive 2024 into charity run.listGroupsShows a list of all existing groups.
Format: listGroups
Tip: To view all members of a group with more than 3 people, use search g/GROUP_NAME.
deleteGroupDeletes a group.
Format: deleteGroup g/GROUP_NAME
GROUP_NAME.GROUP_NAME must exist.Example:
deleteGroup g/blood drive 2024helpShows a message explaining how to access the help page.

Format: help
emailCopies to system clipboard the emails of all persons in the current list, separated by commas.
Format: email
exitExits the program.
Format: exit
CFG data are saved in the hard disk automatically after any command that changes the data. There is no need to save manually.
ContactsForGood data are saved automatically as a JSON file [JAR file location]/data/addressbook.json. Advanced users are welcome to update data directly by editing that data file.
Caution:
If your changes to the data file makes its format invalid, ContactsForGood will discard all data and start with an empty data file at the next run. Hence, it is recommended to take a backup of the file before editing it.
Furthermore, certain edits can cause the ContactsForGood to behave in unexpected ways (e.g. if a value entered is outside the acceptable range). Therefore, edit the data file only if you are confident that you can update it correctly.
Q: Can I use CFG offline?
A: Yes! CFG is fully offline, storing data locally. You can manage contacts and use all commands without an internet connection, making it convenient and accessible anywhere.
Q: How do I transfer my data to another computer?
A: Install the app on the other computer and overwrite the empty data file it creates with the file containing the data from your previous CFG home folder.
Q: How does CFG handle duplicate contacts?
A: CFG checks for duplicates by comparing contact names. If a contact with the same name already exists, CFG will prevent the addition of a duplicate. Modify the name slightly or add unique identifiers if you need to create a similar entry.
Q: I ran a command, but it didn’t seem to work. What went wrong?
A: Check if you entered the command parameters in the correct format and order. For a quick glance at the correct syntax, refer to the Command Summary section.
Q: How can I improve search accuracy in CFG?
A: For more precise search results:
search n/John t/friend) to filter by multiple criteria.Q: How do I view all members in a large group?
A: Use search g/GROUP_NAME to display all members, regardless of the group size.
Q: Can a contact belong to multiple groups?
A: Yes, a contact can be a member of multiple groups. Simply use the addToGroup command with the contact’s index to include them in additional groups without affecting their membership in existing groups.
Q: Can I add or remove multiple members from a group at once?
A: Yes, CFG allows you to add or remove several members from a group in a single command. Use the createGroup or addToGroup command with a space-separated list of indices or a closed range to add multiple members. Similarly, use the removeFromGroup command with multiple indices or ranges to remove members efficiently.
Q: Can I rename a group without changing its members?
A: Yes, you can use the editGroupName command to change a group’s name while keeping its members intact. Just specify the old name and the new name, and the group will be updated without losing any contacts.
preferences.json file created by the application before running the application again.help command (or use the Help menu, or the keyboard shortcut F1) again, the original Help Window will remain minimized, and no new Help Window will appear. The remedy is to manually restore the minimized Help Window.