IronPython Scripts for Extensibility

IronPython scripts are scripts that you can use to customize and extend the functionality of your TouchPoint database. They are written in a programming language called IronPython. We are not going to teach you how to program in that language, but we are going to give you lots of examples here, and explain a few things that you need to know to get started. At the end of this article are a few tips regarding the Python programming language.

First of all, you need to have the role Admin to modify or create these scripts.

There are three different areas in which you can utilize IronPython Scripts. These will grow as we continue to add new features:

  • RegisterEvent

  • VitalStats report

  • MembershipAutomation


Our friends at Redeemer have multiple campuses and have been using an online registration to let their congregants choose the campus with which they wanted to affiliate. This created a bit of work on the back end when an affiliation notification came in. They had to edit the People record and update the Campus for each person. They wanted this to happen automatically and then to create a task for the appropriate person to follow up with this new affiliation.

About a year ago, we introduced the concept of allowing for IronPython scripts to be used as event handlers to do custom tasks. The event in this case would be an Online Registration with a corresponding small group choice. So this was our first event handler for this exact use case and we plan to grow from there. The actual script used for Redeemer to accomplish this task is shown below the following Notes.

Be sure to let us know how you might want to use this capability. Your feedback will help us to determine what new features we add to this.

Notes about the IronPython script

  • You must declare a class called RegisterEvent

  • There is a function called GetCampusId that is a user defined function below the class definition

  • The function AddToSmallGroup is the event handler within the RegisterEvent class

  • AddToSmallGroup takes to parameters, smallgroup and orgmember

  • smallgroup is the name of the smallgroup being joined (in this case, representing the name of the Campus)

  • orgmember is the object that describes the person’s membership in the organization

  • Person is a property of the orgmember object that contains all the properties of the person joining the small group.

  • CampusId is the property of a Person object which indicates by number which campus a person is associated with.

  • model is a utility object passed into the script.

  • CreateTask is a function on the model object that takes PeopleId, Person, and a string describing the task.

  • The script is saved in the Admin > Special Content > Text Files area and given a specific name.

  • In the organization(s) you want to use this script, you refer to this name in the “OnRegister Script Name”  field found under Settings > Registration at the bottom of the page.

As stated above, our goal is not to teach you the IronPython programming language, but we do want to give you some tips.

Here are tips about IronPython language

  • Tabs and white space at the beginning of a line are significant.

  • Basically tabs and white space at the beginning of a line serve to define the block of code that goes with the previous line which is indented by a lesser amount that the following lines.

  • Note the above code line 10 (highlighted)

  • All the statements below that line (11-19) belong to that function definition

  • # introduces a comment

  • the conditional test part of if statements is ended with a :

  • == is the equality test operator

  • self is a reference to the outer class

  • . notation references a property of an object

Vital Stats

This is a report that is found on the Reports menu. Every church will be able to customize the types of data they want to look at here.

Below is the script that we use at Bellevue:

class Data:

vs = Data()
vs.days = 7

number = "{:,}"
vs.members = number.format(q.QueryCount("Stats:Members"))
vs.decisions = number.format(q.QueryCount("Stats:Decisions"))
vs.meetings = number.format(q.MeetingCount(vs.days, 0, 0, 0))
vs.numPresent = number.format(q.NumPresent(vs.days, 0, 0, 0))

vs.uniqueAttends = number.format(q.QueryCount("Stats:Attends"))
vs.newAttends = number.format(q.QueryCount("Stats:New Attends"))
vs.connectGroupsAttends = number.format(q.QueryCount("Stats:Connect Groups All"))
vs.cgApplingAttends = number.format(q.QueryCount("Stats:Appling Connect Groups"))
vs.cgArlingtonAttends = number.format(q.QueryCount("Stats:Arlington Connect Groups"))
vs.cgBellaVistaAttends = number.format(q.QueryCount("Stats:Bella Vista Connect Groups"))
vs.cgFrayserAttends = number.format(q.QueryCount("Stats:Frayser Connect Groups"))
vs.contacts = number.format(q.QueryCount("Stats:Contacts"))
vs.registrations = number.format(q.RegistrationCount(vs.days, 0, 0, 0))
money = "{:,.0f}"
fund = 1
vs.cnAmtPrev7 = money.format(q.ContributionTotals(7*2, 7, fund))
vs.cnCntPrev7 = number.format(q.ContributionCount(7*2, 7, fund))
vs.AvgAmtPerDonorYear = money.format(q.ContributionTotals(53*7, 7, fund) / q.ContributionCount(53*7, 7, fund))
vs.Weekly4WeekAvg = money.format(q.ContributionTotals(7*5, 7, fund) / 4)
vs.WeeklyAvgCurrYear = money.format(q.ContributionTotals(53*7, 7, fund) / 52)
vs.WeeklyAvgPrevYear = money.format(q.ContributionTotals(53*7*2, 53*7+7, fund) / 52)

template = '''
<table style="width:auto;margin-left:auto;margin-right:auto" class="table">

    <tr><th colspan="2">Counts for past {{days}} days</th></tr>

    <tr><td align="right">Members</td>
        <td align="right">{{members}}</td>
    <tr><td align="right">Decisions</td>
        <td align="right">{{decisions}}</td>
    <tr><td align="right">Meetings</td>
        <td align="right">{{meetings}}</td>
    <tr><td align="right">Sum of Present in Meetings</td>
        <td align="right">{{numPresent}}</td>
    <tr><td align="right">Unique Attends</td>
        <td align="right">{{uniqueAttends}}</td>
    <tr><td align="right">New Attends</td>
        <td align="right">{{newAttends}}</td>
    <tr><td align="right">Connect Group Attendance All Campuses</td>
        <td align="right">{{connectGroupsAttends}}</td>
    <tr><td align="right">Appling Connect Group Attendance</td>
        <td align="right">{{cgApplingAttends}}</td>
    <tr><td align="right">Arlington Connect Group Attendance</td>
        <td align="right">{{cgArlingtonAttends}}</td>
    <tr><td align="right">Bella Vista Connect Group Attendance</td>
        <td align="right">{{cgBellaVistaAttends}}</td>
    <tr><td align="right">Frayser Connect Group Attendance</td>
        <td align="right">{{cgFrayserAttends}}</td>
    <tr><td align="right">Contacts</td>
        <td align="right">{{contacts}}</td></tr>
    <tr><td align="right">Registrations</td>
        <td align="right">{{registrations}}</td>

    <tr><th colspan="2">Contributions-Budget and Love Offering</th></tr>

    <tr><td align="right">Average amount per donor per year</td>
        <td align="right">{{AvgAmtPerDonorYear}}</td
    <tr><td align="right">Weekly 4 week average</td>
        <td align="right">{{Weekly4WeekAvg}}</td>
    <tr><td align="right">Weekly average current year</td>
        <td align="right">{{WeeklyAvgCurrYear}}</td>
    <tr><td align="right">Weekly average previous year</td>
        <td align="right">{{WeeklyAvgPrevYear}}</td>
print q.RenderTemplate(template, vs)

Latest Update


Updated link to blog.