Notifications

The notifications view presents the scaffolds associated with configuring templates for email, SMS, webhooks, and event health notices in response to events.

The notification actions scaffold enables clear communication to the RG end-user population, operators and administrators, as well as other systems.

Email is one of several end-user communication methods that are used to create a complete revenue generating network strategy. Email is an important part of the feedback loop when end-users purchase services. Event-based email notifications bring confidence to the end-user by offering a "receipt" when billing events occur. In addition, email can be used for marketing and administrative communication conveyance.

The rXg also uses email as a mechanism to communicate events to administrators. Events may be end-user related such as the service purchase case discussed before, or they may be system generated. Examples of system generated events include, but are not limited to, output from daily, weekly and monthly recurring system maintenance tasks, changes to uplink and monitored node status as well as detection of internal system problems.

The rXg sends emails to administrators and end-users when certain events occur (e.g., account creation, plan selection, etc.). These event-based email notifications draw from templates defined in the custom messages template. The templates may be customized for content, look and feel as well to change the language to match the locale.

custom message templates also be used by the administrator initiated bulk email jobs. For example, the administrator may wish to send some or all end-users an email indicating a maintenance window, a reduced price service special or a paid advertisement from a partner.

The rXg email mechanism also helps operators generate revenue by enabling bulk email marketing. For example, if an operator becomes an affiliate marketing program subscriber, the operator will receive email notifications of special offers. In many cases, affiliate marketing program subscribers are given the opportunity to offer exclusive discount codes to their market base as a purchasing incentive. When an operator receives such a notification, a new email template incorporating affiliate program linkage and incentive information may be formulated and a job created broadcast to the end-user population. The operator is then issued a credit For end-users who take advantage of the opportunity described in the bulk email.

Significant operational cost reduction may also be achieved through the use of the rXg bulk email mechanism. Notification of maintenance windows, end-user surveys, promotions and well-checks may all be accomplished via the bulk email mechanism. Using the bulk email mechanism minimizes the hours utilized by support staff to communicate system and network administration events. In addition, keeping end-users informed often and ahead of time helps reduce support load in maintenance situations.

Below is an example Custom Message that reports to the recipients the amount of revenue generated in the previous 24 hour period:

<p>Good Morning,</p>
<%
  rev = ArTransaction.where(['created_at > ?', 24.hours.ago]).sum(:credit)
%>
<p>Your network generated $
<b><tt><%= sprintf("%.2f", rev) %></tt></b>
yesterday. Have a nice day.
</p>

The Ruby script embedded inside the Custom Message above performs a calculation on the ArTransactions to generate a report for the recipients. Ruby scripts may also perform write operations on the database. For example, below is a Custom Message that is configured to be sent to a guest services representative on a daily basis. <p>Good Morning,</p> <% todays_credential = sprintf("%x%d", rand(255), rand(9999)) scg = SharedCredentialGroup.find_by_name('Guests') scg.credential = todays_credential scg.save %> <p>Today's shared credential for guest access is:</p> <p><b><tt><%= todays_credential %></tt></b></p> <p>Thank you.</p> The Ruby script embedded inside the Custom Message changes the designated Shared Credential Group to a randomly generated value and notifies the associated administators.

Adding Graphs to Custom Messages

Network, System, and Accounting graphs may be added to your custom messages in order to provide enhanced reporting emails to operators and administrators. By selecting associated Graph records in the custom messages's configuration, the system will automatically generate and attach PNG images of those graphs to the email as attachments.

Additionally, graph images may be inserted into the body of an email by calling the insert_attached_graphs method inside the body. The method takes an optional argument specifying the resolution of the image, such as_1000px*600px_ (the default). The resulting images will be stored on the rXg in a publicly accessible directory such that they may be retrieved by email clients.

For example, below is a Custom Message that inserts all associated graphs into the body of the email, separated by a line-break (<br>).

<h2>Weekly Report</h2>
<h3><%= Date.today.strftime("%a, %B %d, %Y") %></h3>
<br>

<%= insert_attached_graphs('1200px*700px') %>

If you wish to exercise greater control over the structure of your HTML email, you may provide a block to the method. The block will yield an array of hashes in the format of { graph_object => image_tag_string }. The array may be iterated over to insert each image tag into your desired HTML structure. For example:

<h2>Weekly Report</h2>
<h3><%= Date.today.strftime("%a, %B %d, %Y") %></h3>
<br>

<table>
<% insert_attached_graphs('600px*500px') do |graph_tags| %>
   <% graph_tags.each do |graph, image_tag| %>
      <tr> <td align="center" style="font-size:34px"><%= graph.title %></td> </tr>
      <tr> <td align="center" style="font-size:14px"><%= graph.subtitle %></td> </tr>
      <tr> <td><%= image_tag %></td> </tr>
   <% end %>
<% end %>
</table>

Webhooks, and Webhook Targets

The webhooks and webhook targets scaffolds enable an operator to integrate other systems with the rXg. Webhooks user defined HTTP callbacks which are triggered by specific events. The events are configured in the notification actions scaffold. When the triggered event occurs, a webhook gathers the required data (headers, and body), and sends it to the configured URL.

An entry in the webhook targets scaffold defines a set of 'global' parameters that all webhooks configured for the target will use. These include the Base URL, body formatting, error code response, as well as any global HTTP headers, or query parameters an operator may need to configure. This enables the flexibility to configure multiple unique webhooks, utilizing a common target, and eliminates the need for repeating common elements such as API-keys, or content-types on each configured webhooks

An entry in the webhooks scaffold defines the parameters for a single webhook. A webhook must have an associated webhook target, containing the base URL. The specific endpoint path is defined in the webhook scaffold entry. The path will be appended to the webhooks configured target base URL. An operator can override the base URL by starting the webook path with a /. The HTTP request method, as well as the body or data is also configured within the webhook scaffold. Any additional HTTP headers, or query parameters that are unique to the configured webhook can be added.

Notification Actions

An entry in the notification actions scaffold defines an event of which the rXg should complete the selected action(s). Events can include database changes, time and/or location based triggers, and more.

The name field is an arbitrary string descriptor used only for administrative identification. Choose a name that reflects the purpose of the record. This field has no bearing on the configuration or settings determined by this scaffold.

The note field is a place for the administrator to enter a comment. This field is purely informational and has no bearing on the configuration settings.

The event type field selects what kind of events should trigger a configured action. Depending on the selection, additional options may be rendered for operator configuration. For database changes, an operator can select Watch Scaffold, choose the appropriate modifiers (create, update, and/or delete).

The messages field configures a custom message to be sent when the criteria of the event is met. The message recievers are configured in the custom messages scaffold entry.

The webhooks field defines configured webhooks to be triggerd when the criteria of the event is met.

The health notice field defines whether the system should send a health notice. Choosing default will result in the default behavior of a configured event. For instance, "Certbot Failure" is configured to send a health notice on failure. If the event does not have a default health notice action, nothing is changed, and no health notice is sent. Choosing Disabled, will override the configured default health notice the event type, and not send it. For instance, with "Certbot Failure", choosing disabled will disable a health notice from being sent. Choosing Custom allows the operator to configure or override an existing health notice. For instance, "Watch Scaffold :: Administrators" wouldn't trigger a health notice by default. Choosing custom would allow an operator to configure a health notice for this event type.

Custom Messages

An entry in the custom messages scaffold creates a template that can be used for email notifications and bulk emails originating from the rXg.

The name field is an arbitrary string descriptor used only for administrative identification. Choose a name that reflects the purpose of the record. This field has no bearing on the configuration or settings determined by this scaffold.

The event drop down associates this template with an event which will trigger an email notification to an end-user. If no event is chosen, the template is assumed to be used in only an email campaign.

The from field defines the address from which emails sent using this template will originate. This email address should lead to an account that is regularly monitored because end-users who receive emails based on this template are likely to reply with questions.

The account and admin roles check boxes enables automatic sending of emails using this custom message for event notification. If the account check box is checked, then the custom message template will be populated with the appropriate data and transmitted to the end-user when the selected event occurs. Similarly, when one or more admin roles check boxes are checked, the custom message template will be populated with the appropriate data and send to the administrators who are linked of the to the checked admin role.

The subject and body fields define the payload of the email template. Place the desired content for the subject and message into the appropriate field. Placeholders for variable substitutions begin and end with the percent sign and must refer to fields from the usage plans or accounts scaffolds. For example, %account.first_name% %account.last_name% will be substituted for the full name of the end-user being targeted by the email. See the full manual page for more information about the values available for substitution.

The note field is a place for the administrator to enter a comment. This field is purely informational and has no bearing on the configuration settings.

Email Campaigns

An entry in the email campaigns scaffold defines a bulk email job. Once the job is complete (i.e., all emails are queued for transmission), the entry in email campaigns is automatically deleted.

The name field is an arbitrary string descriptor used only for administrative identification. Choose a name that reflects the purpose of the record. This field has no bearing on the configuration or settings determined by this scaffold.

The custom message field selects the template that will be used for this bulk email job. The template payload is defined in the custom messages scaffold.

The account groups field configures the set of end-users who will be sent the email template selected by the custom message via this job. The members of the groups are controlled by the account groups scaffold on the accounts view of the identifies subsystem.

The start at field defines the starting time and date for this job. If the value of the start at field is before the current date and time, the job will be started immediately. If the start at is set to the future, the job will start at the specified future date and time.

A job is automatically deleted after it is finished. The optional frequency field determines if this job is run more than once, and how often. The optional end at field defines when a repeat job is finished. A job with a set frequency and a blank end at field will repeat indefinitely at the configured frequency. A periodic job with a configured end at field is deleted when the time of the next iteration exceeds the end at date/time.

The note field is a place for the administrator to enter a comment. This field is purely informational and has no bearing on the configuration settings.

SMS Gateways

The SMS Gateways scaffold enables the creation of an SMS Gateway service which will be utilized for verifying a user's mobile number for the purpose of new account signups and/or password resets.

The name field identifies this SMS Gateway in the system.

The provider field specifies which provider this SMS Gateway relates to. Select a supported provider from the list.

The from field specifies the phone number, shortcode, or Alphanumeric Sender ID (not supported in all countries) to be used when sending SMS messages through this gateway. This value must correspond to a number purchased from or ported to the provider.

The Account SID and Auth Token fields specify the API credentials used to access the provider's REST API, and may be obtained from your dashboard within the provider's website.

The Usage Plans selections determine which usage plans are configured to utilize this SMS Gateway. The usage plan must also specify a validation method which includes SMS in order for messages to be sent via SMS.

The Splash Portals selections determine which splash portals are configured to utilize this SMS Gateway for the purposes of performing password resets. Accounts with a valid mobile phone number may request a password reset token via SMS or Email, depending on the password reset method specified in the splash portal.

The note field is a place for the administrator to enter a comment. This field is purely informational and has no bearing on the configuration settings.

For more information, see the SMS Integration manual entry.

Webhook Targets

An entry in the webhook targets scaffold defines a remote endpoint the rXg should send configured webhooks to.

The name field is an arbitrary string descriptor used only for administrative identification. Choose a name that reflects the purpose of the record. This field has no bearing on the configuration or settings determined by this scaffold.

The note field is a place for the administrator to enter a comment. This field is purely informational and has no bearing on the configuration settings.

The base url field should be configured with the top-level/base URL of the remote API endpoint. This allows for flexibility to have multiple webhooks configured to use the same target.

The persistent connection checkbox configures the rXg to send 'keep-alive' headers and persist the connection state.

The resend on failure checkbox configures the rXg to attempt resending if the initial connection fails.

The error status codes field defines a list of codes that should be considered error responses. The use of wildcard 'x' is available to the operator. Examples include: (400, 401, 4xx, 500, 5xx, 50x).

The body format selector defines the formatting of the body of webhooks configured to use this target. Selecting JSON automatically addsapplication/json to the HTTP Header content-type. SelectingProtobuf requires the operator to define a protobuf schema.

The body encoding selector defines an optional encoding scheme. Options include RAW (no encoding), Base64, and Base64 w/newline every 60 characters.

The webhook properties fields allow the operator to define additional HTTP Headers, or Query Parameters to send globally with all webooks configured to use this target.

Webhooks

An entry in the webhooks scaffold defines the body, target, method, and additional HTTP Headers and/or Query Parameters for a configured webhook.

The name field is an arbitrary string descriptor used only for administrative identification. Choose a name that reflects the purpose of the record. This field has no bearing on the configuration or settings determined by this scaffold.

The note field is a place for the administrator to enter a comment. This field is purely informational and has no bearing on the configuration settings.

The notification actions field displays what actions this webhook is configured for.

The webhook target dropdown configures the webhook target this webhook will use.

The path field is appended to the base url of the webhook target. This allows multiple webhooks to use the same webhook target, and be configured for unique endpoints.

The body field contains the body of the webhook.

The buffer field configures a time period (in minutes) before sending the webhook. "0" will disable buffering.

The webhook properties selector defines an optional encoding scheme. Options include RAW (no encoding), Base64, and Base64 w/newline every 60 characters.

The webhook properties fields allow the operator to define additional HTTP Headers, or Query Parameters to send only with this individual webhook.

Substitution

Payload fields may contain special keywords surrounded by % signs that will be substituted with relevant values. This enables the operator to deliver values stored in the database as part of the payload.

List of objects available:

Account Create Usage Plan Purchase Transaction: success/failure
cluster_node cluster_node cluster_node
custom_email custom_email custom_email
device_option device_option device_option
ip_group login_session login_session
login_session usage_plan merchant
usage_plan account payment_method
account merchant_transaction
usage_plan
account
Credit Card Expiring Coupon Redemption Account Charge: success/failure/no response
cluster_node cluster_node cluster_node
custom_email custom_email custom_email
device_option device_option device_option
login_session coupon login_session
payment_method login_session payment_method
usage_plan usage_plan response
account account usage_plan
account
Trigger: Connections Trigger: Quota Trigger: DPI
cluster_node cluster_node cluster_node
custom_email custom_email custom_email
device_option device_option device_option
login_session login_session login_session
max_connections_trigger quota_trigger snort_trigger
transient_group_membership transient_group_membership transient_group_membership
account account account
Trigger: Time Trigger: Log Hits Health Notice: create
cluster_node cluster_node cluster_node
custom_email custom_email custom_email
device_option device_option device_option
login_session login_session health_notice
time_trigger log_hits_trigger
transient_group_membership transient_group_membership
account account
Health Notice: cured
cluster_node
custom_email
device_option
health_notice

List of objects available for all associated record types:

Aged AR Penalty
cluster_node
custom_email
device_option
aged_ar_penalty
login_session
payment_method
usage_plan
account

List of attributes available for each object:

account usage_plan merchant
id id id
type account_group_id name
login name gateway
crypted_password description login
salt currency password
state recurring_method test
first_name recurring_day note
last_name variable_recurring_day created_at
email automatic_login updated_at
usage_plan_id note created_by
usage_minutes created_at updated_by
unlimited_usage_minutes updated_at signature
usage_expiration created_by partner
no_usage_expiration updated_by invoice_prefix
automatic_login time_plan_id integration
note quota_plan_id store_payment_methods
logged_in_at usage_lifetime_time live_url
created_at absolute_usage_lifetime pem
updated_at unlimited_usage_lifetime scratch
created_by no_usage_lifetime dup_timeout_seconds
updated_by recurring_retry_grace_minutes
mb_up recurring_fail_limit
mb_down prorate_credit
pkts_up permit_unpaid_ar
pkts_down pms_server_id
usage_mb_up lock_devices
usage_mb_down scratch
unlimited_usage_mb_up max_sessions
unlimited_usage_mb_down max_devices
company unlimited_devices
address1 unlimited_sessions
address2 usage_lifetime_time_unit
city max_dedicated_ips
region pms_guest_match_operator
zip recurring_lifetime_time
country recurring_lifetime_time_unit
phone unlimited_recurring_lifetime
bill_at sms_gateway_id
lock_version validation_method
charge_attempted_at validation_grace_minutes
lock_devices max_party_devices
relative_usage_lifetime unlimited_party_devices
scratch upnp_enabled
portal_message automatic_provision
max_devices conference_id
unlimited_devices ips_are_static
max_sessions base_price
unlimited_sessions vtas_are_static
max_dedicated_ips manual_ar
account_group_id
email2
pre_shared_key
phone_validation_code
email_validation_code
phone_validated
email_validated
phone_validation_code_expires_at
email_validation_code_expires_at
max_party_devices
unlimited_party_devices
nt_password
upnp_enabled
automatic_provision
ips_are_static
guid
vtas_are_static
account_id
max_sub_accounts
unlimited_sub_accounts
approved_by
approved_at
pending_admin_approval
wispr_data
hide_from_operator
payment_method merchant_transaction coupon
id id id
account_id account_id usage_plan_id
active payment_method_id code
company merchant_id credit
address1 usage_plan_id expires_at
address2 amount note
city currency created_by
state test updated_by
zip ip created_at
country mac updated_at
phone customer batch
note email scratch
created_at merchant_string max_redemptions
updated_at description unlimited_redemptions
created_by success
updated_by response_yaml
scratch created_at
customer_id updated_at
card_id created_by
nickname updated_by
encrypted_cc_number message
encrypted_cc_number_iv authorization
encrypted_cc_expiration_month hostname
encrypted_cc_expiration_month_iv http_user_agent_id
encrypted_cc_expiration_year account_group_id
encrypted_cc_expiration_year_iv subscription_id
encrypted_first_name
encrypted_first_name_iv
encrypted_middle_name
encrypted_middle_name_iv
encrypted_last_name
encrypted_last_name_iv
email
cc_number
cc_expiration_month
cc_expiration_year
first_name
middle_name
last_name
login_session ip_group device_option
id id id
account_id policy_id name
radius_realm_id name active
login priority device_location
ip note domain_name
mac created_at ntp_server
expires_at updated_at time_zone
online created_by smtp_address
radius_acct_session_id updated_by rails_env
radius_response scratch note
radius_class_attribute created_at
created_at updated_at
updated_at created_by
created_by updated_by
updated_by smtp_port
bytes_up smtp_domain
bytes_down smtp_username
pkts_up smtp_password
pkts_down cluster_node_id
usage_bytes_up scratch
usage_bytes_down log_rotate_hour
ldap_domain_id log_rotate_count
radius_realm_server_id ssh_port
ldap_domain_server_id country_code
cluster_node_id disable_hyperthreading
shared_credential_group_id developer_mode
ip_group_id sync_builtin_admins
account_group_id delayed_job_workers
usage_plan_id log_level
lock_version max_forked_processes
hostname soap_port
total_bytes_up reboot_timestamp
total_bytes_down reboot_time_zone
total_pkts_up limit_sshd_start
total_pkts_down limit_sshd_rate
radius_server_id limit_sshd_full
radius_request use_puma_threads
backend_login_at
http_user_agent_id
backend_login_seconds
portal_login_at
omniauth_profile_id
encrypted_password
encrypted_password_iv
conference_id
password
custom_email transient_group_membership time_trigger
id id id
name ip_group_id account_group_id
from mac_group_id name
subject account_group_id mon
body account_id tues
event ip wed
note mac thurs
created_by reason fri
updated_by expires_at sat
created_at created_by sun
updated_at updated_by start
send_to_account created_at end
scratch updated_at note
email_recipient cluster_node_id created_by
include_custom_reports_in_body max_connections_trigger_id updated_by
attachment_format quota_trigger_id created_at
custom_event time_trigger_id updated_at
delivery_method snort_trigger_id ip_group_id
sms_gateway_id hostname mac_group_id
reply_to radius_group_id scratch
ldap_group_id flush_states
login_session_id flush_dhcp
log_hits_trigger_id flush_arp
flush_states flush_vtas
flush_dhcp infrastructure_area_id
flush_arp previous_infrastructure_area_id
flush_vtas duration
vulner_assess_trigger_id current_dwell
previous_dwell
log_hits_trigger snort_trigger max_connections_trigger
id id id
ip_group_id ip_group_id ip_group_id
mac_group_id name name
name duration max_connections
note note duration
log_file created_by note
duration updated_by created_by
max_hits created_at updated_by
window updated_at created_at
scratch scratch updated_at
created_by mac_group_id scratch
updated_by flush_states mac_group_id
created_at flush_dhcp flush_states
updated_at flush_arp flush_dhcp
flush_states flush_vtas flush_arp
flush_dhcp flush_vtas
flush_arp max_duration
flush_vtas max_mb
period
active_or_expired
max_duration_logic
max_mb_logic
quota_trigger health_notice cluster_node
id id id
account_group_id cluster_node_id name
name name iui
usage_mb_down short_message database_password
usage_mb_down_unit long_message note
usage_mb_up cured_short_message created_by
usage_mb_up_unit cured_long_message updated_by
up_down_logic_operator severity created_at
note cured_at updated_at
created_by created_at ip
updated_by updated_at ssh_public_key
created_at created_by scratch
updated_at updated_by heartbeat_at
radius_group_id fleet_node_id data_plane_ha_timeout_seconds
ldap_group_id node_mode
period cluster_node_team_id
unlimited_period wal_receiver_pid
duration wal_receiver_status
unlimited_duration wal_receiver_receive_start_lsn
scratch wal_receiver_receive_start_tli
ip_group_id wal_receiver_received_lsn
mac_group_id wal_receiver_received_tli
flush_states wal_receiver_latest_end_lsn
flush_dhcp wal_receiver_slot_name
flush_arp wal_receiver_sender_host
flush_vtas wal_receiver_sender_port
wal_receiver_last_msg_send_time
wal_receiver_last_msg_receipt_time
wal_receiver_latest_end_time
op_cluster_node_id
priority
auto_registration
permit_new_nodes
auto_approve_new_nodes
pending_auto_registration
pending_approval
control_plane_ha_backoff_seconds
data_plane_ha_enabled
upgrading
enable_radius_proxy
aged_ar_penalty
id
name
amount
days
suspend_account
note
created_at
updated_at
created_by
updated_by
custom_email_id
scratch
record_type
days_type

Use Cases

Slack Integration: Notification when an admin is created or deleted

Procedure:

  1. Use Slack guide to create a new app, and configure incoming webhooks.
  2. Navigate to Services-->Notifications and create a new webhook target Insert the webhook address from your slack app as the base URL.

  3. Create a webhook for created admins. An example body is: { "attachments": [ { "fallback": "Admin Created on &lt%= DeviceOption.active.domain_name %&gt.", "color": "#36a64f", "pretext": "A New Administrator has been created", "author_name": "FQDN: &lt%= DeviceOption.active.domain_name %&gt", "author_link": "https://&lt%= DeviceOption.active.domain_name %&gt/admin/", "title": "Created Admin: &lt%= admin.login %&gt", "text": "*Created by:* &lt%= admin.created_by %&gt", "fields": [ { "title": "Priority", "value": "Medium", "short": false } ], "footer": "Slack API" } ] }

  4. Create a webhook for deleted admins An example body is: (notice the use of <%= admin_hash %> because the record has been deleted.)

{
  "attachments": [
    {
      "fallback": Admin Deleted on &lt%= DeviceOption.active.domain_name %&gt.",
      "color": "#FF0000",
      "pretext": "An Administrator has been deleted",
      "author_name": "FQDN: &lt%= DeviceOption.find_by(active: 'true').domain_name %&gt",
      "author_link": "https://&lt%= DeviceOption.find_by(active: 'true').domain_name %&gt/admin/",
      "title": "Deleted Admin: &lt%= admin_hash[:login] %&gt",
      "text": "*Deleted by:* &lt%= admin_hash[:updated_by] %&gt",
      "fields": [
        {
          "title": "Priority",
          "value": "High",
          "short": false
        }
      ],
      "footer": "Slack API"
    }
  ]
}

  1. Create a notification action for created admins.
  • Choose Event Type: Watch Scaffold
  • Choose Watched Model: Administrators
  • Select: Watch Create
  • Choose the Admin Created Webhook under actions
  1. Create a notification action for deleted admins.
  • Choose Event Type: Watch Scaffold
  • Choose Watched Model: Administrators
  • Select: Watch Delete
  • Choose the Admin Deleted Webhook under actions
  1. Navigate to System-->Admins, and create a new admin. Then delete the new admin. The channel configured in your Slack app will have messages posted via the rXg Notification Actions subsystem.

Location Based Crowding Notifications

Procedure:

  1. Navigate to Network :: Location
  2. Create or edit existing location areas.

  3. Edit individual areas and set crowd event thresholds. Thresholds can be set at region, floor, and site levels.

  4. Navigate to Services :: Notifications

  5. Create a notification action and select desired messages, webhooks and/or health notices to trigger.

Push Account To Remote rXg On Create

Procedure:

  1. Navigate to Services :: Notifications
  2. Create a new Notification Action

    • Event Type set to Watch Scaffold
    • Watched Model set to Accounts
    • Check the Watch Create checkbox
    • Click Create.
  3. Create a new Webhook Target

    • Input a Name
    • The base url will be https://FQDN\_of\_remote\_system/admins/scaffolds/
    • Select body format, JSON in this case, and Body Encoding as RAW
    • Add Webhook Property, Kind = Query Paramater, Key = api_key, the value will be the API key of an admin on remote system
    • Click Create
  4. Create a new Webhook

    • Input a name
    • Select Notification action created in step 1
    • Select the webhook target created above
    • Set path to accounts/create.json
    • Set Method to POST
    • Enter code into body (example below), click create.
<%
# get remote usage plan hash
result = HTTParty.post('https://FQDN_of_remote_system/admin/scaffolds/usage_plans/index.xml',
  body: {:api_key=>"REMOTE_ADMIN_API_KEY",
  :search=>account.usage_plan.try(:name)})
up = result["usage_plans"].try(:first)
# get remote account group hash
result = HTTParty.post('https://FQDN_of_remote_system/admin/scaffolds/account_groups/index.xml',
  body: {:api_key=>"REMOTE_ADMIN_API_KEY",
  :search=>account.account_group.try(:name)})
ag = result["account_groups"].try(:first)
# varible for device creation
count = 1
acct_hash = account.attributes
# remove attrs we dont want to push
acct_hash.delete("id")
acct_hash.delete("usage_plan_id")
acct_hash.delete("account_group_id")
acct_hash.delete("type")
acct_hash.delete("created_at")
acct_hash.delete("updated_at")
acct_hash.delete("created_by")
acct_hash.delete("updated_by")
acct_hash.delete("mb_up")
acct_hash.delete("mb_down")
acct_hash.delete("crypted_password")
acct_hash.delete("salt")
# make temporary password
acct_hash["password"] = acct_hash["password_confirmation"] = acct_hash["pre_shared_key"]
# add usage plan and do_apply_plan to hash if found on remote system
if up
  acct_hash["usage_plan"] = up["id"]
  acct_hash["do_apply_usage_plan"] = 1
end
# add account group to hash if found on remote system
if ag
  acct_hash["account_group"] = ag["id"]
end
# add all devices to account hash
acct_hash["devices"] = {}
account.devices.each do |device|
  acct_hash["devices"]["device#{count.to_s}"] = {
    "name" => device.name,
    "mac" => device.mac
  }
  count += 1
end
%>
{
  "record": <%= acct_hash.to_json %>
}

CRM Integration

This example will explore integrating the rXg with the community edition of vTiger CRM. This case demonstrates using an API requiring a multistep login process, and use of a disposable session key rather than static credentials.

Procedure:

  1. The community edition of vTiger uses a combination of a challenge token, username, and access key to generate an expiring session key to be used with API calls. Create a custom data key under System :: Portals as a place to store the key.
  • The only necessary field to populate is the name.
  1. Create a notification action to periodically get the session key, and perform a log in to the CRM.
  • Set the event type to periodic.
  • Choose a time within the session key expiration (the webhook will contain logic to determine if a refresh is necessary).
  1. Create a webhook target for the CRM.
  • Add an HTTP header of "Content-Type": "application/x-www-form-urlencoded"
  1. Create a webhook that uses embedded ruby to store the current session key in the previously defined custom data key. This example looks at the age of the current key to see if a new key is necessary before executing.
  • Choose the previously created notification action.
  • Choose the CRM webhook target.
  • Example Body:
<%
  api_key = CustomDataKey.find_by(name: 'api_key')
  if api_key.value_string.blank? || 30.minutes.since > api_key.updated_at
    query = {
      operation: "getchallenge",
      username: "username",
    }
    resp = HTTParty.get(webhook_target.base_url, query: query)
    token = JSON.parse(resp.body)['result']['token']
    access_key = Digest::MD5.hexdigest(token + 'access_key_from_GUI')

    body = {
      operation: "login",
      username: "username",
      accessKey: access_key,
    }

  login = HTTParty.post(webhook_target.base_url, body: body)
  session_id = JSON.parse(login.body)['result']['sessionName']
  api_key.value_string = session_id
  api_key.save!
  end
  raise DoNotSendError
%>

  1. Create a notfication action to trigger when a new account is created.
  • Choose the event type: Watch Scaffold
  • Choose the watched model: Accounts
  • Check: Watch Create
  1. Create a webhook to create the account on the CRM.
  • Select the previously created notification action.
  • Choose the CRM webhook target.
  • Set the method to POST
  • Example Body:
<%=
  {
    operation: "create",
    sessionName: CustomDataKey.find_by(name: 'api_key').value_string,
    elementType: "Contacts",
    element: {
      firstname: record_hash["first_name"],
      lastname: record_hash["last_name"],
      assigned_user_id: "20x4",
    }.to_json
  }.to_query
%>
  1. Because vTiger CRM expects the body of the HTTP POST to be url-encoded the body is enclosed in ERB tags "<%= ... %>" so certain methods can be used to make formatting easier. ## Webhook to retrieve System Info

In this example will show how to setup a Webhook to push System Info on a periodic interval.

Procedure:

  1. Create a new Notification Action
  • Populate the name field with the desired name.
  • Set the Event Type field to Periodic.
  • Specify how often the action should run using the Period field. Default is 5 minutes.
  • Click Create. 2. Create a new Webhook Target
  • Populate the name field with the desired name.
  • Specify the URL of the target using the Base URL field.
  • Click Create.

    1. Create a new Webhook
  • Populate the name field with the desired name.

  • Use the Notification Actions field to select the notification action created in step 1.

  • Select the webhook target created in step 2 in the Webhook Target field.

  • Set the path in the Path field.

  • The Body field is where we will put our payload.

<%= SystemInfo.first.attributes.to_json %> - Click Create. This will pass the following information.

{
  "id": 1048577,
  "cluster_node_id": null,
  "baseboard_asset_tag": "Not Specified",
  "baseboard_manufacturer": "Intel Corporation",
  "baseboard_product_name": "440BX Desktop Reference Platform",
  "baseboard_serial_number": "None",
  "baseboard_version": "None",
  "bios_vendor": "Phoenix Technologies LTD",
  "bios_version": "6.00",
  "chassis_asset_tag": "No Asset Tag",
  "chassis_manufacturer": "No Enclosure",
  "chassis_serial_number": "None",
  "chassis_type": "Other",
  "chassis_version": "N/A",
  "disk_device": "NECVMWar VMware SATA CD00 1.00",
  "hostname": "rxg.example.com",
  "os_arch": "amd64",
  "os_branch": "RELEASE",
  "os_kernel": "FreeBSD 12.2-RELEASE-p9 #16 476551a338d",
  "os_name": "FreeBSD",
  "os_release": "12.2-RELEASE-p9 #16",
  "os_version": "12.2",
  "processor_family": "Unknown",
  "processor_frequency": "2300 MHz",
  "processor_manufacturer": "GenuineIntel",
  "processor_version": "Intel(R) Xeon(R) D-2146NT CPU @ 2.30GHz",
  "rxg_build": "12.999",
  "system_manufacturer": "VMware, Inc.",
  "system_product_name": "VMware Virtual Platform",
  "system_serial_number": "VMware-56 4d fd 29 e4 1a c1 4e-a2 60 81 57 54 ff dd 51",
  "system_uuid": "29fd4d56-1ae4-4ec1-a260-815754ffdd51",
  "system_version": "None",
  "disk_total_gb": 111,
  "memory_free_mb": 3874,
  "memory_total_mb": 8192,
  "memory_used_mb": 4317,
  "processor_count": 4,
  "uptime": 85371,
  "load_avg_15m": "0.78",
  "load_avg_1m": "1.09",
  "load_avg_5m": "0.84",
  "processor_temp": "0.0",
  "bios_release_date": "2018-12-12",
  "booted_at": "2021-08-30T08:37:23.000-07:00",
  "created_by": "rxgd(InstrumentVitals)",
  "updated_by": "rxgd(InstrumentVitals)",
  "created_at": "2021-08-11T08:38:58.800-07:00",
  "updated_at": "2021-08-31T08:20:14.808-07:00",
  "rxg_iui": "4 2290 8192 111 ZKORHJVPDUQUZUNIBEWLHDFQ GZQQJUTGUDOIFDNTDUFQSKTW NLDQYHFARJWE",
  "system_family": "Not Specified",
  "fleet_node_id": null
}

Backend Scripts

The backend script allows the operator to write custom ruby scripts that can be used for things like interacting with mobile applications or performing a configuration change on a regular schedule. From the Notification Actions scaffold you can choose a trigger for the script from the drop down list. Some examples included manual, periodic, errors, and thresholds.

Big Red Button Mobile Application

This example will show how to setup a backend script that can be triggered by an API call executed by a mobile application which is available in the Apple and Google Play app stores.

This example assumes that you have an existing WLAN created under the WLANs scaffold with a record name of arena.

Procedure:

1) Browse to Services >> Notifications >> Backend Scripts 2) Click Create New 3) Name the backend script toggle_ssid. 4) Paste the following script into the body and click create.

def toggle_ssid   wlan = Wlan.find_by(name: 'arena')   ssid = wlan.ssid

  if ssid == 'basketball_arena'     wlan.ssid = 'hockey_arena'   else     wlan.ssid = 'basketball_arena'   end

  wlan.save! end

toggle_ssid

puts 'ssid toggled successfully'

5) Browse to Services >> Notifications >> Notification Actions 6) Click Create New 7) Name the notification action toggle_ssid. 8) Set the event type field to Manual. 9) Select toggle_ssid from the available scripts in the list.

Install the rXg Action Button Mobile App

Apple: https://apps.apple.com/us/app/rxg-action-button/id1483547358 Android: https://play.google.com/store/apps/details?id=net.lok.aidan.rxg_action_button

1) On the rXg browse to System >> Admins 2) Next to your admin account, click on the API Keys link. 3) Click Create New 4) Provide the API Key a name and click Create.

5) You will be presented with several QR codes. Make sure to leave this screen up.

6) From the mobile app, click Scan QR Code.

7) Scan the QR code labeled JSON. 8) Click Login With Saved Credentials

9) Set the action to toggle_ssid 10) Click on the slider to enable the button.

Now, simply press the red action button to toggle the SSID from basketball_arena to hockey_arena. These changes will be pushed to the wireless controller via config sync.

This is a very simple example of what can be done using a combination of a mobile application and the rXg backend scripts.


Cookies help us deliver our services. By using our services, you agree to our use of cookies.