ADMIN SIGN IN

Pages

Pages allows you to create custom html pages to use for the member portal landing page and for creating custom registration cards. To use pages you must have account admin permission. Pages will appear in the main menu on the left when you are logged into the admin portal. Click on this to go to the pages application. From here you will see a list of your current pages.

To add a new page click on the “Add page” button. This will open a dialog where you can select the type of page you want to add, web or registration.

After selecting the page type, a default page layout will be generated and will be opened up in the page editor.

Pages are made up of sections, you can think of these as rows, and elements, you can think of these as columns within the rows. All content is edited from the left hand panel. To add a section, click the “Add section” button. To delete a section, click the trash can icon in the section title bar. You can move sections up and down using the up and down arrows in the section title bar.

To edit content within a section, click on the section title bar to reveal the sections content.

Click on a modules title bar to reveal the modules settings

From here you can edit all of the modules content and styling. The changes you make here will be reflected in the preview in the right hand side. Use the “Add module” button to add additional modules. Click the arrow buttons in the module title bar to move the module left or right, use the trash can icon to delete a module.

Make sure to give the page a name that makes sense to you and save your changes when you are done.

To set a page as the landing/home page in the member portal, navigate to the Administration -> Portal page and select the Home Page you would like to use. “Build-in” is the default panels view.

To use a page as a registration card go to the event registrations, and select the “Dash card” for the registration you want to create a registration card for, then in the dialog select the registration card you would like to use.

The “Default/Built-in” option is the layout that works with pre-printed registration cards that use the Middletwin dash card layout.

Email template strings cheatsheet

When creating an email template you can use string replacement tags in the email template and these will be replaced with values from database fields. All string replacements use the pattern dollar sign – open curly brace – tag – close curly brace (ie ${tag}).

Here is an example

Hello ${fname},
Your member number is ${id}.

Member email (all)

  • ${fname} – member first name
  • ${lname} – member last name
  • ${name} – member full name
  • ${id} – member number
  • ${email} – member email address
  • ${expiration} – member expiration date
  • ${contact.firstname} – member first name
  • ${contact.lastname} – member last name
  • ${contact.name} – member full name
  • ${contact.email} – member email address
  • ${contact.address} – member address
  • ${contact.city} – member city
  • ${contact.state} – member state
  • ${cotnact.zip} – member postal code
  • ${contact.id} – member id
  • ${contact.expiration} – member expiration date

Member Expiring and expired email

  • ${fname} – member first name
  • ${lname} – member last name
  • ${name} – member full name
  • ${id} – member id
  • ${email} – member email address
  • ${expiration} – member expiration date

Event participant signup email

  • ${fname} – participant first name
  • ${lname} – participant last name
  • ${name} – participant full name
  • ${number} – participant registration number
  • ${email} – participant email address
  • ${class} – participant class number

Event shift worker signup email

  • ${fname} – worker first name
  • ${lname} – worker last name
  • ${name} – worker full name
  • ${email} – worker email address
  • ${phone} – worker phone number

Event vendor signup email

  • ${address1} – vendor address 1
  • ${address2} – vendor address 2
  • ${city} – vendor city
  • ${state} – vendor state
  • ${zip} – vendor postal code
  • ${phone} – vendor phone number
  • ${name} vendor name
  • ${number} – vendor number
  • ${email} – vendor email address
  • ${spaces} – a comma separate list of the spaces purchased

Event ticket confirmation

  • ${name} – the name of the purchaser
  • ${tickets} – list of links to ticket

Activity Reminder email

  • ${title} – the activity title
  • ${description} – the activity description
  • ${date} – the activity date
  • ${start} – start time
  • ${end} – end time

If you need something that is not on this list please contact support at support@middletwin.com.

Social

To get a list of social media posts use the following:

{
"action":"get_posts",
"limit":<number>,
"offset": <number>
}

A successful response will contain an array of posts in JSON format with each post item containing the following:

{
"media": <array of media>,
"post": {
"author":<string>,
"commentCount":<number>,
"created": <unix_timestamp>,
"edited":<unix_timestamp>,
"id":<number>,
"memberId":<number>,
"message":<string>,
"parentId":<number>
},
"reactions": <array of reactions>
}

Each media item will contain:

{
"id":<number>,
"imageData": <string: base 64 encoded image>,
"postId":<number>
}

Each reaction item will contain:

{
"id":<number>,
"memberId":<number>,
"postId":<number>,
"reaction":<number: reaction type index>
}

Create

A member can use the following POST request to create a social media post:

{
"action":"create_post",
"memberId":<number: the members id>,
"message":<string>,
"images":<array of images>
}

If this is a comment on a post, use the same data but add “parentId” with the id of the post that this is a comment for.

Update

A member can update their own post using the following request:

{
"action":"update_post",
"id":<number: post id to update>,
"memberId":<number: the members id>,
"message":<string>,
"images":<array of images>
}

Delete

A member can delete their own post using the following POST request:

{
"action":"delete_post",
"postId":<number>
}

Reactions

Create

You can create a reaction to a post using the following:

{
"action":"create_post_reaction",
"postId":<number>,
"memberId":<number>,
"reaction":<number: type of reaction>
}

Get

{
"action": "get_post_reactions",
"postId":<number>
}

Comments

Get

{
"action":"get_post_comments",
"postId":<number>
}

Note: Use the create post action to create comments by specifying a parentId in the request body.

Store

Purchasing store items should only be performed in the actual portal because a secure connection to the payment processing system, stripe, needs to be established. Please do not create your own interface for this.

Files

To display a list of shared files for members perform a post with the following data:

{
“action”:”get_media”,
“shared”: true
}

A successful response will contain an array of files with the following data:

{
"contentType":<string>,
"height":<number>,
"id":<number>,
"name":<string>,
"report":<boolean>,
"share":<boolean>,
"storageId":<number>,
"url":<string>,
"width": <number
}

Note that width and height only apply to image file type. The content type is a mime type.

Classifieds

Through the member portal API you can perform many operations on classifieds. A classified represents something that a member wants to sell to other members.

Get Classifieds

{
"action":"get_classifieds",
"limit": <number>",
"offset":<number>
}

A successful response will have an array of classifieds in JSON data format. Each classified contains the following data:

{
"created":<unix_timestamp>,
"deleted":null,
"description":<string>,
"fullCount":<number:total number of classifieds>,
"id":<number>,
"images": <optional: array of image data>,
"label":<string>,
"memberId": <number: id of member selling item>,
"price":<number>
}

If there are images each image item will contain the following:

{
"classified":<number>,
"id":<number>,
"imageData":<string: base 64 encoded image data>
}

Create

To create a classified perform a post with the following data:

{
"action":"create_classified",
"description":<string>,
"images": <optional: array of image data>,
"label":<string>,
"memberId": <number: id of member selling item>,
"price":<number>
}

If successful the API will return the id of the created classified.

Update

To update an existing classified perform a post with the following data:

{
"action":"update_classified",
"id":<number: id of classified to update>
"description":<string>,
"images": <optional: array of image data>,
"label":<string>,
"memberId": <number: id of member selling item>,
"price":<number>
}

Note that a member can only update a classified that they created. So this option should only be available of the memberId of the classified matches the id of the logged in member.

Delete

To delete an existing classified that the logged in member created, perform a post with the following data:

{
"action":"delete_classified",
"id":<number: id of classified to delete>
}

Getting another members info

Note that in the classified view a member may want to access the contact information for a member that is selling something. To perform this use the following action:

{
"action":"get_member",
"id":<number: id of member>
}

This should only be used when a member wants to view this data, not for every classified in an array.

Activities

Through the member portal the only activities action that the member can perform is a get_actvities. This action takes 2 parameters, start and end, which are until timestamps representing the start and end day to get the activities for.

{
"action":"get_activities",
"start": <unix_timestamp>,
"end": <unix_timestamp>
}

The successful response will have a JSON body with the key activities which will have an array of the activities to display. Each activity will have the following data:

{
"start": <time>,
"end": <time>,
"date": <unix_timestamp>,
"id":<unique id>,
"title":<string>,
"description":<string>
}

It would be typical to display this as a calendar view with next and previous month controls.

Getting Started with Member Portal APIs

We provide a member portal for group members to use with their group. The member portal is available both as a web application at a url that the group sets up, as well as through a mobile app that we have developed.

The member portal theme can be changed through your administration portals settings section to use the styling that your club prefers, and you can control what options your group members can have access to through the portal as well.

You can also develop your own portal by using the same API’s that we have developed for our portal. This document will describe the steps to authenticate a member login, and access the API’s. Note that an API key, as described in the Getting started with API integration is not required for using the member portal APIs.

Getting the tenant information

The first step in the portal development process is to get the information for the tenant that you want to authenticate a member with. To do this you need to make a request with the get_tenant action and the subdomain for the tenant you are interested in.

{
"action": "get_tenant",
"subdomain": <tenant_subdomain>
}

If the group is found this will return the tenant information record. You will need some of the information in this record for future calls. You can save this information somewhere so you do not need to make this API call every time.

Authenticating a Member

Looking up the member

Authenticating a member is a multi step process. The first step involves looking up the member. You do this with the lookup_member action

{
"action":"lookup_member",
"tenant": <tenant_id>,
"username": <member_email_address>
}

This will cause the system to look for a member with the exact same email address that you provide. If the member is found you will get back a successful JSON response with the member record. One of the most important keys in this response will be the “hasPassword” key. If this is false you will need to walk the member through the process of setting up a password. If the member already has a password you can go to the next step of validating the member password with their email address.

If the member was not found you will get back an error response

{
"member":null,
"redirect":null,
"success":false,
"errorMessage":"Unable to find user with email fake@nowhere.com"
}

Logging in the member

After you have confirmed that you have found the member through the lookup, and they have a password, you can ask them to provide the password to you and send a member_login action with the login information

{
"action":"member_login",
"password": <password>,
"tenant": <tenant_id>,
"username": <member_email_address>
}

If the password is invalid you will get back an error

{
"success":false,
"errorMessage":"Invalid Password"
}

If successful you will get back a success response with an X-Dart-Token in the response header. You need to store this token as it will serve as the member identity for all member portal API’s. The token is good for 24 hours, but for security we recommend you build in an inactivity timeout and sign out the member and delete the token if they leave the portal.

Setting up a password

If the member is found by the lookup but hasPassword is false, you will need to setup their password. This is done with the member_set_password action

{
"action":"member_set_password",
"tenant": <tenant_id>,
"username": <member_email_address>,
"password": <password>
}

Security starts with strong passwords and the weakest link in security is always poor passwords. We strongly recommend that you check the password before setting it to verify that it meets industry security standards, like a mixture of upper and lower case letters, at least one number, at least one special characters, and at least 8 characters in length. Note that this API will only work to establish a password for the first time. If the user has forgotten their password you will need to use the forgot password API to force a strong password to be generated and emailed to the member.

{
"action":"member_forgot_password",
"tenant": <tenant_id>,
"username":<member_email_address>
}

The forgot password action will fail if the member has never had a password setup, so make sure you do not expose forgot password functionality if the hasPassword flag is false on the member record response.

Conclusion

With the X-Dart-Token you will be able to make any of the portal API calls on behalf of the member. We may add multi-factor authentication to member logins, like we do for admin logins, and if we do that we will update this documentation and give you time to implement it in your code.

Tags

In the middletwin platform tags are the object types that are used for grouping member objects together.

Tag object properties

FieldRequiredDescription
idUpdate/Deletelong – The id of an existing tag
textYesString – The text of the tag (64 max)

Tags have the following actions

get_all_tags

This action will return an array list of all the tags in the system that have member associations. It has no options.

get_tags

This action will return an array list of all the tags in the system. It has no options.

get_matching_tags

This action will return an array of tags that have text that match a passed in string. This action has one required parameter named ‘text’ that will have the text to search for. 

create_tag

This action will create a new tag and requires one parameter named ‘text’. You can optionally pass in a parameter named ‘members’ with an array of member id’s to associate with this new tag.

update_tag

This action will update an existing tag and requires two parameters, one named ‘id’ with the id of the tag to update and one named ‘text’ with the new text value for the tag.

delete_tag

This action will delete an existing tag and requires one parameter named ‘id’ with the id of the tag to delete.

get_tag_members

This action will return an array of member objects that are associated with a tag. It requires one parameter named ‘tag’ that contains the id of the tag.

create_tag_member

This action will create an association between an existing member and an existing tag. It requires two parameters, one named ‘member’ with the id of the member for the association and one named ‘tag’ with the id of the tag for the association.

delete_tag_member

This action will delete an association between an exiting tag and an existing member. It requires two parameters, one named ‘member’ with the id of the member for the association and one named ‘tag’ with the id of the tag for the association.

Member API

In the middletwin platform, members are the object types that contain contact information for individual members. If performing an action like sending a message or an email, you will need to provide a member id. Members have the following actions.

create_member

update_member

delete_member

get_member

get_all_members

get_matching_members

Contact Properties for create/update actions

FieldRequiredDescription
idUpdate/Deletelong – The id of the member
fnamenString – The members first name (64 max)
lnamenString – The members last name (64 max)
addressnString – The members street address (128 max)
citynString – The members city (64 max)
statenString – The members state (32 max)
zipnString – The members zip (16 max)
phone1yString – The members mobile number (24 max)
phone2nString – The members other number (24 max)
email_addressnString – The members other number (128 max)
stoppednboolean – The members 

get_all_members has an optional type parameter which defaults to json, but you can specify csv to get a csv response.

get_matching_members requires the search_term parameter. The search_term is a String and will be compared against the members name, city, state, and email address. Matching members will be returned in an array. 

1 2 3 4 5
Privacy Settings
We use cookies to enhance your experience while using our website. If you are using our Services via a browser you can restrict, block or remove cookies through your web browser settings. We also use content and scripts from third parties that may use tracking technologies. You can selectively provide your consent below to allow such third party embeds. For complete information about the cookies we use, data we collect and how we process them, please check our Privacy Policy
Youtube
Consent to display content from - Youtube
Vimeo
Consent to display content from - Vimeo
Google Maps
Consent to display content from - Google
Spotify
Consent to display content from - Spotify
Sound Cloud
Consent to display content from - Sound