csm-patterns

安装量: 50
排名: #14897

安装

npx skills add https://github.com/groeimetai/snow-flow --skill csm-patterns

Customer Service Management for ServiceNow

CSM enables organizations to deliver exceptional customer service through cases, accounts, and self-service.

CSM Architecture Account (customer_account) ├── Contacts (customer_contact) ├── Contracts (ast_contract) │ └── Entitlements (service_entitlement) ├── Assets (alm_asset) └── Cases (sn_customerservice_case) ├── Case Tasks └── Communications

Key Tables Table Purpose customer_account Customer accounts customer_contact Account contacts sn_customerservice_case Customer cases service_entitlement Service entitlements ast_contract Service contracts Customer Accounts (ES5) Create Customer Account // Create customer account (ES5 ONLY!) var account = new GlideRecord('customer_account'); account.initialize();

// Basic info account.setValue('name', 'Acme Corporation'); account.setValue('account_code', 'ACME-001'); account.setValue('industry', 'Technology');

// Contact info account.setValue('phone', '+1-555-123-4567'); account.setValue('email', 'info@acme.com'); account.setValue('website', 'https://www.acme.com');

// Address account.setValue('street', '123 Main Street'); account.setValue('city', 'San Francisco'); account.setValue('state', 'CA'); account.setValue('zip', '94105'); account.setValue('country', 'US');

// Account details account.setValue('account_type', 'customer'); // customer, partner, vendor account.setValue('tier', 'gold'); // bronze, silver, gold, platinum

// Assignment account.setValue('account_manager', accountManagerSysId);

account.insert();

Create Contact // Create contact for account (ES5 ONLY!) var contact = new GlideRecord('customer_contact'); contact.initialize();

// Link to account contact.setValue('account', accountSysId);

// Contact info contact.setValue('name', 'John Smith'); contact.setValue('email', 'john.smith@acme.com'); contact.setValue('phone', '+1-555-123-4568'); contact.setValue('title', 'IT Manager');

// Contact type contact.setValue('type', 'primary'); // primary, billing, technical contact.setValue('active', true);

// Create user for portal access var user = createUserFromContact(contact); contact.setValue('user', user);

contact.insert();

Customer Cases (ES5) Create Customer Case // Create customer case (ES5 ONLY!) var caseRecord = new GlideRecord('sn_customerservice_case'); caseRecord.initialize();

// Case info caseRecord.setValue('short_description', 'Unable to access product features'); caseRecord.setValue('description', 'Customer reports error when trying to use premium features');

// Classification caseRecord.setValue('category', 'product_issue'); caseRecord.setValue('subcategory', 'access_problem'); caseRecord.setValue('priority', 2);

// Customer caseRecord.setValue('account', accountSysId); caseRecord.setValue('contact', contactSysId);

// Product/Asset caseRecord.setValue('product', productSysId); caseRecord.setValue('asset', assetSysId);

// Assignment caseRecord.setValue('assignment_group', getGroupSysId('Customer Support'));

// Channel caseRecord.setValue('channel', 'email'); // email, phone, chat, web

caseRecord.insert();

Case Routing // Route case based on account and product (ES5 ONLY!) // Business Rule: before, insert, sn_customerservice_case

(function executeRule(current, previous) { if (current.assignment_group) { return; // Already assigned }

var group = determineAssignmentGroup(current);
if (group) {
    current.assignment_group = group;
}

})(current, previous);

function determineAssignmentGroup(caseRecord) { // Check for premium support entitlement if (hasPremiumSupport(caseRecord.getValue('account'))) { return getGroupSysId('Premium Support'); }

// Route by product
var product = caseRecord.product.getRefRecord();
if (product.isValidRecord()) {
    var supportGroup = product.getValue('support_group');
    if (supportGroup) {
        return supportGroup;
    }
}

// Default
return getGroupSysId('General Support');

}

function hasPremiumSupport(accountSysId) { var entitlement = new GlideRecord('service_entitlement'); entitlement.addQuery('account', accountSysId); entitlement.addQuery('type', 'premium_support'); entitlement.addQuery('start_date', '<=', new GlideDateTime()); entitlement.addQuery('end_date', '>=', new GlideDateTime()); entitlement.query(); return entitlement.hasNext(); }

Entitlements (ES5) Create Service Entitlement // Create entitlement (ES5 ONLY!) var entitlement = new GlideRecord('service_entitlement'); entitlement.initialize();

entitlement.setValue('name', 'Premium Support - Acme Corp'); entitlement.setValue('account', accountSysId); entitlement.setValue('contract', contractSysId);

// Entitlement type entitlement.setValue('type', 'premium_support');

// Dates entitlement.setValue('start_date', '2024-01-01'); entitlement.setValue('end_date', '2024-12-31');

// Limits entitlement.setValue('total_cases', 100); entitlement.setValue('used_cases', 0); entitlement.setValue('remaining_cases', 100);

// SLA entitlement.setValue('response_sla', '4 hours'); entitlement.setValue('resolution_sla', '24 hours');

entitlement.insert();

Check Entitlement // Check if customer is entitled to service (ES5 ONLY!) function checkEntitlement(accountSysId, entitlementType) { var now = new GlideDateTime();

var entitlement = new GlideRecord('service_entitlement');
entitlement.addQuery('account', accountSysId);
entitlement.addQuery('type', entitlementType);
entitlement.addQuery('start_date', '<=', now);
entitlement.addQuery('end_date', '>=', now);
entitlement.query();

if (entitlement.next()) {
    var remaining = parseInt(entitlement.getValue('remaining_cases'), 10);

    return {
        entitled: true,
        remaining: remaining,
        unlimited: remaining < 0,  // -1 = unlimited
        expiration: entitlement.getValue('end_date'),
        sla: {
            response: entitlement.getValue('response_sla'),
            resolution: entitlement.getValue('resolution_sla')
        }
    };
}

return {
    entitled: false,
    message: 'No active entitlement found'
};

}

Decrement Entitlement // Use entitlement when case created (ES5 ONLY!) // Business Rule: after, insert, sn_customerservice_case

(function executeRule(current, previous) { var accountSysId = current.getValue('account'); if (!accountSysId) return;

var entitlement = new GlideRecord('service_entitlement');
entitlement.addQuery('account', accountSysId);
entitlement.addQuery('type', 'support');
entitlement.addQuery('start_date', '<=', new GlideDateTime());
entitlement.addQuery('end_date', '>=', new GlideDateTime());
entitlement.addQuery('remaining_cases', '>', 0);
entitlement.orderBy('end_date');  // Use earliest expiring first
entitlement.setLimit(1);
entitlement.query();

if (entitlement.next()) {
    var used = parseInt(entitlement.getValue('used_cases'), 10);
    var remaining = parseInt(entitlement.getValue('remaining_cases'), 10);

    entitlement.setValue('used_cases', used + 1);
    entitlement.setValue('remaining_cases', remaining - 1);
    entitlement.update();

    // Link case to entitlement
    current.u_entitlement = entitlement.getUniqueValue();
    current.update();

    // Alert if running low
    if (remaining - 1 <= 5) {
        gs.eventQueue('entitlement.low', entitlement, accountSysId, (remaining - 1).toString());
    }
}

})(current, previous);

Customer Portal (ES5) Portal Case Submission // Widget Server Script for case submission (ES5 ONLY!) (function() { // Handle case creation if (input && input.action === 'createCase') { var contactId = getContactForUser(gs.getUserID()); if (!contactId) { data.error = 'No contact record found'; return; }

    var contact = new GlideRecord('customer_contact');
    contact.get(contactId);

    // Create case
    var caseRecord = new GlideRecord('sn_customerservice_case');
    caseRecord.initialize();
    caseRecord.setValue('short_description', input.subject);
    caseRecord.setValue('description', input.description);
    caseRecord.setValue('contact', contactId);
    caseRecord.setValue('account', contact.getValue('account'));
    caseRecord.setValue('priority', input.priority || 3);
    caseRecord.setValue('channel', 'web');

    var caseSysId = caseRecord.insert();

    data.success = true;
    data.case_number = caseRecord.getValue('number');
    data.case_sys_id = caseSysId;
}

// Get user's cases
if (!input || input.action === 'getCases') {
    var contactId = getContactForUser(gs.getUserID());
    data.cases = [];

    if (contactId) {
        var gr = new GlideRecord('sn_customerservice_case');
        gr.addQuery('contact', contactId);
        gr.orderByDesc('sys_created_on');
        gr.setLimit(20);
        gr.query();

        while (gr.next()) {
            data.cases.push({
                sys_id: gr.getUniqueValue(),
                number: gr.getValue('number'),
                short_description: gr.getValue('short_description'),
                state: gr.state.getDisplayValue(),
                priority: gr.priority.getDisplayValue(),
                opened_at: gr.getValue('opened_at')
            });
        }
    }
}

function getContactForUser(userId) {
    var contact = new GlideRecord('customer_contact');
    contact.addQuery('user', userId);
    contact.query();
    if (contact.next()) {
        return contact.getUniqueValue();
    }
    return null;
}

})();

MCP Tool Integration Available Tools Tool Purpose snow_query_table Query CSM tables snow_find_artifact Find CSM configurations snow_execute_script_with_output Test CSM scripts snow_deploy Deploy CSM widgets Example Workflow // 1. Query customer cases await snow_query_table({ table: 'sn_customerservice_case', query: 'active=true^priority<=2', fields: 'number,short_description,account,contact,state' });

// 2. Check entitlements await snow_execute_script_with_output({ script: var result = checkEntitlement('account_sys_id', 'premium_support'); gs.info(JSON.stringify(result)); });

// 3. Find accounts with expiring contracts await snow_query_table({ table: 'ast_contract', query: 'endsBETWEENjavascript:gs.beginningOfToday()@javascript:gs.daysAgoEnd(-30)', fields: 'number,vendor,ends,account' });

Best Practices Account Hierarchy - Parent/child accounts Contact Roles - Clear contact types Entitlements - Track usage limits SLA Mapping - Account tier to SLA Portal Access - Secure customer data Case Routing - Smart assignment Communication - Audit trail ES5 Only - No modern JavaScript syntax

返回排行榜