mobile-development

Mobile Development for ServiceNow

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "mobile-development" with this command: npx skills add groeimetai/snow-flow/groeimetai-snow-flow-mobile-development

Mobile Development for ServiceNow

Mobile development enables native mobile experiences with offline capabilities.

Mobile Architecture

Mobile App Configuration ├── App Screens │ ├── List Views │ ├── Detail Views │ └── Card Builders ├── Push Notifications ├── Offline Rules └── Mobile Actions

Key Tables

Table Purpose

sys_sg_mobile_app

Mobile app configs

sys_sg_screen

Mobile screens

sys_sg_card_builder

Card builders

sys_push_notification

Push configs

sys_sg_offline_rule

Offline rules

Mobile App Configuration (ES5)

Create Mobile App

// Create mobile app configuration (ES5 ONLY!) var app = new GlideRecord("sys_sg_mobile_app") app.initialize()

app.setValue("name", "IT Support") app.setValue("description", "Mobile app for IT support tasks")

// App settings app.setValue("active", true) app.setValue("version", "1.0.0")

// Branding app.setValue("primary_color", "#1976D2") app.setValue("secondary_color", "#FFFFFF") app.setValue("icon", "attachment_sys_id")

// Default screen app.setValue("home_screen", homeScreenSysId)

// Roles app.setValue("roles", "itil")

app.insert()

Configure Mobile Screen

// Create mobile screen (ES5 ONLY!) var screen = new GlideRecord("sys_sg_screen") screen.initialize()

screen.setValue("name", "My Incidents") screen.setValue("mobile_app", mobileAppSysId) screen.setValue("type", "list") // list, record, custom

// Data source screen.setValue("table", "incident") screen.setValue("filter", "assigned_to=javascript:gs.getUserID()^active=true")

// Display screen.setValue("title", "My Incidents") screen.setValue("icon", "list")

// Ordering screen.setValue("order", 100)

screen.insert()

Card Builder (ES5)

Create Card Configuration

// Create card builder for list display (ES5 ONLY!) var card = new GlideRecord("sys_sg_card_builder") card.initialize()

card.setValue("name", "Incident Card") card.setValue("table", "incident")

// Card layout card.setValue("primary_field", "number") card.setValue("secondary_field", "short_description") card.setValue("tertiary_field", "priority")

// Additional fields card.setValue( "fields", JSON.stringify([ { field: "caller_id", label: "Caller" }, { field: "state", label: "Status" }, { field: "opened_at", label: "Opened" }, ]), )

// Visual indicators card.setValue("color_field", "priority") card.setValue( "color_mapping", JSON.stringify({ 1: "#D32F2F", // Critical - Red 2: "#F57C00", // High - Orange 3: "#FBC02D", // Moderate - Yellow 4: "#388E3C", // Low - Green 5: "#1976D2", // Planning - Blue }), )

card.insert()

Custom Card Actions

// Add actions to card (ES5 ONLY!) function addCardAction(cardSysId, actionDef) { var action = new GlideRecord("sys_sg_card_action") action.initialize()

action.setValue("card_builder", cardSysId) action.setValue("label", actionDef.label) action.setValue("icon", actionDef.icon) action.setValue("order", actionDef.order)

// Action type action.setValue("action_type", actionDef.type) // script, navigate, share

// Script action (ES5 ONLY!) if (actionDef.type === "script") { action.setValue("script", actionDef.script) }

action.insert() }

// Example actions addCardAction(cardSysId, { label: "Acknowledge", icon: "check", order: 100, type: "script", script: "(function(gr) {\n" + " gr.state = 2; // In Progress\n" + ' gr.work_notes = "Acknowledged via mobile";\n' + " gr.update();\n" + ' gs.addInfoMessage("Incident acknowledged");\n' + "})(current);", })

Push Notifications (ES5)

Configure Push Notification

// Create push notification config (ES5 ONLY!) var push = new GlideRecord("sys_push_notification") push.initialize()

push.setValue("name", "High Priority Incident Assigned") push.setValue("description", "Notify when high priority incident assigned")

// Target table and condition push.setValue("table", "incident") push.setValue("condition", "priority<=2^assigned_to.changes()")

// Notification content push.setValue("title", "High Priority Incident Assigned") push.setValue("body", "${number}: ${short_description}")

// Recipients push.setValue("recipient_type", "field") push.setValue("recipient_field", "assigned_to")

// Deep link push.setValue("deep_link", true) push.setValue("link_url", "/incident/${sys_id}")

push.setValue("active", true)

push.insert()

Send Push Notification Programmatically

// Send push notification (ES5 ONLY!) function sendPushNotification(userSysId, message) { try { var push = new sn_notification.PushNotification()

push.setTitle(message.title)
push.setBody(message.body)

if (message.data) {
  push.setData(message.data)
}

if (message.deepLink) {
  push.setDeepLink(message.deepLink)
}

push.send(userSysId)

return { success: true }

} catch (e) { gs.error("Push notification failed: " + e.message) return { success: false, error: e.message } } }

// Example sendPushNotification(userSysId, { title: "Task Assigned", body: "You have a new task assigned", deepLink: "/task/" + taskSysId, })

Offline Capabilities (ES5)

Configure Offline Rules

// Create offline sync rule (ES5 ONLY!) var rule = new GlideRecord("sys_sg_offline_rule") rule.initialize()

rule.setValue("name", "My Open Incidents") rule.setValue("mobile_app", mobileAppSysId) rule.setValue("table", "incident")

// Sync filter rule.setValue("filter", "assigned_to=javascript:gs.getUserID()^active=true")

// Fields to sync rule.setValue("fields", "number,short_description,description,priority,state,caller_id,opened_at")

// Related records rule.setValue("include_references", true) rule.setValue("reference_fields", "caller_id,assignment_group")

// Sync limits rule.setValue("max_records", 100)

// Update frequency rule.setValue("sync_frequency", "on_demand") // on_demand, periodic

rule.setValue("active", true)

rule.insert()

Handle Offline Data

// Check for offline changes on sync (ES5 ONLY!) function processOfflineChanges(userId) { var offlineQueue = new GlideRecord("sys_sg_offline_queue") offlineQueue.addQuery("user", userId) offlineQueue.addQuery("processed", false) offlineQueue.orderBy("created_on") offlineQueue.query()

var results = { processed: 0, errors: [] }

while (offlineQueue.next()) { try { var tableName = offlineQueue.getValue("table") var recordSysId = offlineQueue.getValue("record") var changes = JSON.parse(offlineQueue.getValue("changes"))

  // Apply changes
  var gr = new GlideRecord(tableName)
  if (gr.get(recordSysId)) {
    for (var field in changes) {
      if (changes.hasOwnProperty(field)) {
        gr.setValue(field, changes[field])
      }
    }
    gr.update()
    results.processed++
  }

  // Mark as processed
  offlineQueue.processed = true
  offlineQueue.update()
} catch (e) {
  results.errors.push({
    record: offlineQueue.getValue("record"),
    error: e.message,
  })
}

}

return results }

Mobile Actions (ES5)

Create Mobile Action

// Create mobile-specific action (ES5 ONLY!) var action = new GlideRecord("sys_sg_action") action.initialize()

action.setValue("name", "Scan Barcode") action.setValue("label", "Scan Asset") action.setValue("description", "Scan barcode to find asset")

// Action type action.setValue("type", "native") // native, script, link action.setValue("native_action", "barcode_scan")

// Available on action.setValue("screens", screenSysIds)

// Callback script (ES5 ONLY!) action.setValue( "callback_script", "(function(result) {\n" + " if (!result.value) return;\n" + " \n" + ' var asset = new GlideRecord("alm_asset");\n' + ' asset.addQuery("asset_tag", result.value);\n' + " asset.query();\n" + " \n" + " if (asset.next()) {\n" + " // Navigate to asset\n" + ' sn_mobile.navigate("record", {\n' + ' table: "alm_asset",\n' + " sys_id: asset.getUniqueValue()\n" + " });\n" + " } else {\n" + ' gs.addErrorMessage("Asset not found: " + result.value);\n' + " }\n" + "})(scanResult);", )

action.insert()

Location-Based Action

// Get user location for mobile (ES5 ONLY!) // Available in mobile context

function getCurrentLocation() { try { var location = sn_mobile.getLocation() return { latitude: location.latitude, longitude: location.longitude, accuracy: location.accuracy, } } catch (e) { return null } }

// Use location for nearby assets function findNearbyAssets(latitude, longitude, radiusMeters) { var assets = []

var gr = new GlideRecord("alm_asset") gr.addNotNullQuery("location.latitude") gr.query()

while (gr.next()) { var assetLat = parseFloat(gr.location.latitude) var assetLon = parseFloat(gr.location.longitude)

var distance = calculateDistance(latitude, longitude, assetLat, assetLon)

if (distance &#x3C;= radiusMeters) {
  assets.push({
    sys_id: gr.getUniqueValue(),
    name: gr.getDisplayValue(),
    distance: Math.round(distance),
  })
}

}

return assets.sort(function (a, b) { return a.distance - b.distance }) }

MCP Tool Integration

Available Tools

Tool Purpose

snow_query_table

Query mobile configs

snow_execute_script_with_output

Test mobile scripts

snow_find_artifact

Find configurations

Example Workflow

// 1. Query mobile apps await snow_query_table({ table: "sys_sg_mobile_app", query: "active=true", fields: "name,description,version,roles", })

// 2. Get push notification configs await snow_query_table({ table: "sys_push_notification", query: "active=true", fields: "name,table,condition,title", })

// 3. Check offline rules await snow_query_table({ table: "sys_sg_offline_rule", query: "active=true", fields: "name,table,filter,max_records", })

Best Practices

  • Offline First - Design for connectivity issues

  • Minimal Data - Sync only necessary fields

  • Push Wisely - Don't overwhelm with notifications

  • Native Features - Use camera, GPS, barcode

  • Card Design - Key info at a glance

  • Performance - Optimize for mobile

  • Testing - Test on actual devices

  • ES5 Only - No modern JavaScript syntax

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-review

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

client-scripts

No summary provided by upstream source.

Repository SourceNeeds Review
General

predictive-intelligence

No summary provided by upstream source.

Repository SourceNeeds Review
General

scheduled-jobs

No summary provided by upstream source.

Repository SourceNeeds Review