LoginSignup
0
0

ServiceNowのスクリプト-基本文法からScripted REST APIまで

Posted at

ServiceNowの基本コードまとめ

ServiceNowの基本コードといえるものをまとめます。
参考はChuck TomasiのYoutube動画です。

システムログ出力
gs.info('Hello, world!');
サーバースクリプト基本
var gr = new GlideRecord('task');
gr.addActiveQuery();
gr.query();

while (gr.next()) {
    gs.info(gr.getValue('number'));
}
クライアントスクリプト基本
function onLoad() {

  alert('Current state value is: ' + g_form.getValue('state'));

}
変数例と一般的な命名規則
var name   = 'Chuck';   // string型
var i      = 0;         // integer型
var answer = true;      // boolean型

// 変数命名規則
var c = "http://www.amazon.com";  // ×よくない
var case = 'CASE0010001';         // ×予約語
var lastEntryInTheListWithRelatedRecords = true; // △長すぎる
// personCount      // counter/integerを示す
// personList       // list式
// personObj        // Object式
// personGr         // GlideRecord式
オペレーター式
// 値の代入
var a = 12;
var b = 3;

// 値の追加
gs.info(2 + 2);
gs.info(a + 2);
b = b + 2;
// b += 2;  // 短縮式

// 1増加
a++;

// 1減少
b--;

// 掛け算
gs.info(a * b);

// 割り算
gs.info(a / b);

// 余り
gs.info('');
gs.info(a);
gs.info(b);
gs.info(a % b);

String型
var firstName = "Chuck";
var lastName  = 'Tomasi';  // シングルクォート、ダブルクォート両方ともok
var myCar     = "Chuck's Car";  // まぜたら紛らわしいのでよくない

// +で文字列をくっつけること可能
var name = firstName + ' ' + lastName;
gs.info(name);
gs.info('length of name=' + name.length);
特殊文字
// \n = 改行
// \t = タブ
// \\ = バックスラッシュ
// \' = single quote
// \" = double quote
//
gs.info('Single string\nTwo lines');
gs.info('Chuck\'s simple script');
gs.info('Don\'t confuse a forward slash (/) with a backslash(\\)');
型変換と型確認
var i = 5;
var iStr = i.toString();
gs.info(typeof i);
gs.info(typeof iStr);

var n = parseInt(iStr);
gs.info(typeof n + ' n=' + n);
コメントアウト
// This is a single line comment

/* This is another way to comment */
算術演算子
var a = 0;
var b = 1;
gs.info(a < b);

var n = '3';
var i = 3;
gs.info(n == i); // ???
gs.info(i = 4); // 代入
if文
var a = 1;
var b = 3;
var c = 5;
if (a < b)
  gs.info('a is less than b');

// else
if (a < b)
  gs.info('a is less than b');
else
  gs.info('a is greater than or equal to b');

// Else if and else
if (a < b)
  gs.info('a is less than b');
else if (a > b)
  gs.info('a is greater than b');
else if (a == b)
  gs.info('a equals b');
else
  gs.info('Uh-oh');

if (a < b)
  if (b < c)
      gs.info('a b c are in order');
boolean型
var a = 1;
var b = 3;
var c = 5;

if (a < b && b < c)
  gs.info('a b c are in order');

if (b > a || b > c)
  gs.info('b is greater than one of them.');

// Note, indentation can be deceptive!!!
if (a < b)
  if (b < c) {
    gs.info('a b c are in order');
    gs.info(' that means a is less than c');
  }
else
  gs.info('a is greater than or equal to b');

var valveOpen = true;
if (valveOpen == true)
  gs.info('Valve is currently open');

if (bool)
  gs.info('Valve is currently open');

var valveOpen = false;
if (!valveOpen)
  gs.info('Valve is currently closed');
三項演算子
var valveOpen = true;
var openStatusString;
if (valveOpen)
  openStatusString = 'open';
else
  openStatusString = 'closed';
  gs.info('1: Valve is currently ' + openStatusString);

// Introducing a shortcut way...
var openStatusString = (valveOpen) ? 'open' : 'closed';
gs.info('2: Valve is currently ' + openStatusString);
switch文
var level = 5;
var message = '';
switch (level) {
  case 0:
    message = 'Empty';
    break;

  case 1:
  case 2:
    message = 'Low';
    break;

  case 3: // Warning - what's wrong with case 3?
    message = 'Medium';
  case 4:
    message = 'High';
    break;

  case 5:
    message = 'Full';
    break;

  default:
    message = 'Uh-oh!';
}
gs.info('Level=' + level + ' status=' + message);
true/false
var boolTrue = true;
var boolFalse = false;
gs.info('boolTrue=' + boolTrue + ' boolFalse=' + boolFalse);
値がどう評価されるかクイズ
var num = 0; // <== try with different numbers
gs.info(num + ' is ' + ((num) ? 'true' : 'false'));

var string1;
var string2 = null;
var string3 = 'Hello, world!';
gs.info('string1=' + ((string1) ? 'true' : 'false'));
gs.info('string2=' + ((string2) ? 'true' : 'false'));
gs.info('string3=' + ((string3) ? 'true' : 'false'));
ループ文
var i = 0;
while (i < 5) {
  gs.info(i);
  i++;
}
gs.info('done i=' + i);

//break
var i = 0;
while (true) {
  if (i == 5)
    break;
  gs.info(i);
  ++i;
}

//continue
var i = 0;
var done = false;
while (!done) {
  if (i < 5) {
    ++i;
    gs.info(i + ' done=' + done);
    continue;
  }
  gs.info('I think we are done');
  done = true;
}
gs.info(i);

gs.info('done');
for文の継続
for (var i = 0; i < 5; i++) {
  gs.info(i);
}
gs.info('done i=' + i);
do-while
var i = 0;
gs.info('start');
do {
  gs.info('i=' + i);
  ++i;
} while (i < 5);
gs.info('done i=' + i);
ネスト式ループ
for (var i = 0; i < 5; i++) {
  for (var j = 0; j < 3; j++) {
    gs.info('i=' + i + ' j=' + j);
  }
}
gs.info('Done i=' + i + ' j=' + j);
関数定義
function sayHello() {
  gs.info('Hello');
}
sayHello();

//引数つき関数
function toCelsius(fahrenheit) {

    var c = (5 / 9) * (fahrenheit - 32);

    gs.info(c);
}
toCelsius(32);
toCelsius(100);

//返り値付きの関数

function toCelsius(fahrenheit) {

    return (5 / 9) * (fahrenheit - 32);

}
var c = toCelsius(32);
gs.info(c);
c = toCelsius(212);
gs.info(c);

//ローカル変数の関数
function toCelsius(fahrenheit) {

    // c is only known in the function toCelsius()
    var c = (5 / 9) * (fahrenheit - 32);

    return c;
}
gs.info(c); // What happened?

//自立式の関数
var i = 20;

(function() {

  // Local variable
  i = 10; // uh-oh, forgot the var!

  gs.info('i=' + i);
  
}());

i = 3;
gs.info('i=' + i);

try/catch
try {
  for (var i = 0; i < 5; i++) {
    gs.info('i=' + i + ' answer=' + answer);
  }
} catch (e) {
  gs.error('Uh-oh ' + e.message);
} finally {
  gs.info('done');
}
DBクエリ
var incGr = new GlideRecord('incident');
incGr.query();

while (incGr.next()) {
  gs.info(incGr.getValue('number'));
}

//クエリ文追加
var incGr = new GlideRecord('incident');
incGr.addQuery('active', true);
incGr.orderBy('number');
incGr.setLimit(5);
incGr.query();

while (incGr.next()) {
  gs.info(incGr.getValue('number'));
}

//Getメソッドの型に注意
var incGr = new GlideRecord('incident');
incGr.setLimit(1);
incGr.query();

if (incGr.next()) {
  var dotNumber = incGr.number;
  var gvNumber  = incGr.getValue('number');
  gs.info('dotNumber=' + typeof dotNumber + ' gvNumber=' + typeof gvNumber);
}

// Why should I care? I'll show you when we get to arrays...

//1レコードを早くとる秘密
var incGr = new GlideRecord('incident');

if (incGr.get('965c9e5347c12200e0ef563dbb9a7156')) {
  gs.info(incGr.getValue('number'));
}

// or...
var incGr = new GlideRecord('incident');

if (incGr.get('number', 'INC0000059')) {
  gs.info(incGr.getValue('sys_id'));
}
配列型
var list = [];
list[0] = 1;
list[1] = 3;
list[2] = 5;
gs.info('length of list is: ' + list.length);

//短縮
var list = [1, 3, 5];

//配列処理
var list = [1, 3, 5];
for (var i = 0; i < list.length; i++) {
  gs.info('i=' + i + ' value=' + list[i]);
}

// Slightly better
var list = [1, 3, 5];
var len = list.length;
for (var i = 0; i < len; i++) {
  gs.info('i=' + i + ' value=' + list[i]);
}
foreach
var list = [1, 3, 5];

list.forEach(myFunction);

function myFunction(item) {
  gs.info('myFunction item=' + item);
}

// 埋め込みforeach
var list = ['apple', 'banana', 'orange'];

list.forEach(function (item, index, arr) {
  gs.info('embedded function item=' + item + ' index=' + index + ' arr=' + arr);
});
配列処理
var list = ['Chuck', 'Kreg', 'Stacey'];
gs.info('list=' + list);

var list = ['Chuck', 'Kreg', 'Stacey'];
gs.info('join: list=' + list.join(', '));

// push(value1, value2, ..., valueX)
list.push('Dave');
list.push('Andrew');
gs.info('push: list=' + list.join(', '));

// pop()
list.pop();
gs.info('pop: list=' + list.join(', '));

//shift()
var list = ['Chuck', 'Kreg', 'Stacey'];
gs.info('Before shift(), list[0]=' + list[0]);
list.shift();
gs.info('shift: list=' + list.join(', '));
gs.info('After shift(), list[0]=' + list[0]);

// unshift
var list = ['Chuck', 'Kreg', 'Stacey'];
var newLength = list.unshift('Jason', 'Andrew');
gs.info('new length=' + newLength + ' unshift() list=' + list.join(', '));

// spice
var names = ["Eric", "Donna", "Melanie", "Jessie"];
gs.info(names.join(', '));
names.splice(2, 0, "Cary", "Henri");
gs.info(names.join(', '));

//slice
var names = ["Eric", "Donna", "Melanie", "Jessie", "Howard", "Tomasz"];
gs.info(names.join(', '));
var subNames = names.slice(1, 3); // Get names at positions 1 and 2
gs.info(subNames.join(', '));

//reverse
var names = ["Eric", "Donna", "Melanie", "Jessie", "Howard", "Tomasz"];
names.reverse();
gs.info(names.join(', '));

//値の取り出し
var list = [];
var incGr = new GlideRecord('incident');
incGr.addQuery('priority', '1');
incGr.query();

while (incGr.next()) {
    list.push(incGr.getValue('sys_id'));
}

gs.info('list=\n' + list.join('\n'));
ArrayUtil
// L25S01 - ArrayUtil
//
var au = new ArrayUtil();
var names = [
  "Eric",
  "Donna",
  "Melanie",
  "Jessie",
  "Howard",
  "Eric",
  "Jessie",
  "Tomasz"
];
var newNames = au.unique(names);
gs.info(newNames.join(', '));
hasownproperty
var vehicle = {
  "year" : 2018,
  "make"  : "Toyota",
  "model" : "Sienna"
};
gs.info(vehicle.hasOwnProperty("year"));  // <== true
gs.info(vehicle.hasOwnProperty("price")); // <== false
object key/value
var vehicle = {
  "year" : 2018,
  "make"  : "Toyota",
  "model" : "Sienna"
};
for (var key in vehicle) {
  gs.info('key=' + key + ' value=' + vehicle[key]);
}
配列オブジェクト処理
var bookList = [
  {
    "title" : "Harry Potter and the Chamber of Secrets",
    "author" : "J.K. Rowling"
  },
  {
    "title" : "Moby Dick",
    "author" : "Herman Melville"
  },
  {
    "title" : "A Tale of Two Cities",
    "author" : "Charles Dickens"
  }
];
var len = bookList.length;
gs.info('Last author=' + bookList[len].author);

for (var i = 0; i < len; i++) {
  var book = bookList[i];
  gs.info(i + ' - Title: ' + book.title + ' - Author: ' + book.author);
}
Str化/Parse
var bookList = [
  {
    "title" : "Harry Potter and the Chamber of Secrets",
    "author" : "J.K. Rowling"
  },
  {
    "title" : "Moby Dick",
    "author" : "Herman Melville"
  },
  {
    "title" : "A Tale of Two Cities",
    "author" : "Charles Dickens"
  }
];
gs.info(bookList); // That's not very helpful!

var bookListStr = JSON.stringify(bookList);
gs.info(bookListStr);  // I can read it - sort of

var bookListStrFormat = JSON.stringify(bookList, null, 4);
gs.info(bookListStrFormat); // Ah - that's better!

// parse
var libraryStr = '[{"title":"Harry Potter and the Chamber of Secrets","author":"J.K. Rowling"},{"title":"Moby Dick","author":"Herman Melville"},{"title":"A Tale of Two Cities","author":"Charles Dickens"}]';
gs.info('length=' + libraryStr.length);
var libraryObj = JSON.parse(libraryStr);
gs.info('length=' + libraryObj.length);
gs.info(JSON.stringify(libraryObj, null, 4));
string処理
var subject = 'Warning: Email is not working';
var pos = subject.indexOf('Email');
gs.info(pos);

var short_description = 'System is displaying error message';
if (short_description.indexOf('error') >= 0) {
  gs.info("Error message found");
}

//substring
var str = 'Approved: RITM0010001 - Laptop renewal';
var pos = str.indexOf('RITM');
var ritmNumber = str.substring(pos, pos + 11);
gs.info(ritmNumber);

//Case形式
var firstName = 'Chuck';
var loginName = 'chuck';
if (loginName == firstName) {
  gs.info('names match');
} else {
  gs.info('names do not match');
}

//upper/lower
var firstName = 'Chuck';
var loginName = 'chuck';
gs.info('firstName=' + firstName.toUpperCase() + ' loginName=' + loginName.toUpperCase());
if (loginName.toUpperCase() == firstName.toUpperCase()) {
  gs.info('names match');
} else {
  gs.info('names do not match');
}
再帰
function factorial(x) {

  // TERMINATION
  if (x < 0)
    return;

  // BASE
  if (x === 0)
    return 1;

  // RECURSION
  return x * factorial(x - 1);
}
gs.info(factorial(3)); // 6
class,object.prototype
var person = Class.create();
person.prototype = {
    initialize: function() {
      this.firstName = '';
      this.lastName  = '';
    },

    setFirstName : function(str) {
      this.firstName = str;
    },

    setLastName : function(str) {
      this.lastName = str;
    },

    getDisplayName : function() {
      return this.firstName + ' ' + this.lastName;
    },

    type: person
};

var me = new person();
me.setFirstName('Chuck');
me.setLastName('Tomasi')
gs.info('me=' + me.firstName + ' ' + me.lastName); // Not advised
var name = me.getDisplayName();
gs.info(name);

// initialize
var person = Class.create();
person.prototype = {
    initialize: function(str1, str2) {
      this.firstName = str1;
      this.lastName  = str2;
    },

    setFirstName : function(str) {
      this.firstName = str;
    },

    setLastName : function(str) {
      this.lastName = str;
    },

    getDisplayName : function() {
      return this.firstName + ' ' + this.lastName;
    },

    type: 'person'
};

var me = new person('Chuck', 'Tomasi');
var name = me.getDisplayName();
gs.info(name);
me.setFirstName('Fred');
me.setLastName('Luddy');
gs.info(me.getDisplayName());
Objectへの関数渡し
var item = Class.create();
item.prototype = {
    initialize: function() {
    },

    debugObject : function(obj) {

      gs.info('object=' + JSON.stringify(obj, null, 4));
    },

    type: 'item'
};

var myObj = {
  "type"   : "vehicle",
  "engine" : true,
  "wheels" : 4,
  "state"  : "allocated"
};
var myItem = new item();
myItem.debugObject(myObj); // Loosely coupled
継承
var vehicle = Class.create();
vehicle.prototype = {
    initialize: function(year, make, model) {
      this.make = make;
      this.model = model;
      this.year = year;
    },

    register : function() {
      gs.info(this.getDisplayName() + ' registered!');
    },

    info : function() {
      gs.info('Vehicle info: TBD');
    },

    getDisplayName : function() {

      return this.year + ' ' + this.make + ' ' + this.model;

    },

    type: 'vehicle'
};

var car = Class.create();
car.prototype = Object.extendsObject(vehicle, {

    findDealer : function() {
      gs.info('Find dealer is not yet implemented');
    },

    info : function() {
      gs.info('Car info: TBD');
    },

    type: 'car'
});

var v1 = new vehicle('2018', 'John Deere', 'Tractor');
v1.register();
v1.info();

var v2 = new car('2017', 'Honda', 'CR-V');
v2.register();
v2.findDealer();
v2.info();
Script REST API
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {

  return "hello, world!";
    
})(request, response);

// Example Query parameters
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 
  // https://<instance_rest_endpoint>?active=true&name=now
  var queryParams   = request.queryParams; 
  var isActiveQuery = queryParams.active; //true
  var nameQueryVal  = queryParams.name; //‘now’

  var answer = "Response: active=" + isActiveQuery + " name=" + nameQueryVal;

  return answer;
    
})(request, response);

// Scripted REST API with path parameters
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 
  // Example path parameters
  // https://instance.service-now.com/api/now/myservice/{tableName}/{id}
  // https://instance.service-now.com/api/now/myservice/myApp_table/1234
  var pathParams = request.pathParams; 
  var tableName  = pathParams.tableName; //‘myApp_table’ 
  var id         = pathParams.id; //‘1234’

  var answer = "Response: tableName=" + tableName + " id=" + id;

  return answer;
    
})(request, response);

// Scripted REST API (POST) with request body payload
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 
    var name  = request.body.data.name;
    var id    = request.body.data.id;
    var color = request.body.data.color;
    
    var answer = "Response: name=" + name + " id=" + id + " color=" + color;

    return answer;
    
})(request, response);

// Scripted REST API with POST and response
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 
    var name  = request.body.data.name;
    var id    = request.body.data.id;
    var color = request.body.data.color;
    
    // Do some processing here
    
    var answer = {};
    answer.status = "OK";
    answer.author = "system";
    answer.item = {"name" : "Rome", "owner" : "Chuck Tomasi", "count" : 12};
    answer.active = true;
    response.setBody(answer);

    return response;
    
})(request, response);
Quiz
// Lab 2
//
// What is 3 + 2 * 5?
//
gs.info(3 + 2 * 5); // 13

// Create a three string variables.
// Print the length of each string
// concatenate them together with a new line character and save to a new variable
// Print the new variable and length of the new variable
//
var string1 = 'Chuck';
var string2 = 'Tomasi';
var string3 = 'JavaScript';
gs.info('length1 = ' + string1.length);
gs.info('length2 = ' + string2.length);
gs.info('length3 = ' + string3.length);

var allStrings = string1 + '\n' + string2 + '\n' + string3;
gs.info('allStrings=' + allStrings);
gs.info('length of allStrings=' + allStrings.length);

/*
Output from Scripts - background

*** Script: length1 = 5
*** Script: length2 = 6
*** Script: length3 = 10
*** Script: allStrings=Chuck
Tomasi
JavaScript
*** Script: length of allStrings=23
*/

// Create a script that takes a string variable "Hello world"
// and translates it to at least 3 different languages
// based on a 'language' variable.
// Make the default language English if a match isn't found.

var language   = 'German';
var fromString = 'Hello world';
var toString   = '';

switch (language) {
    case 'German':
        toString = 'Hallo Welt';
        break;
    case 'French':
        toString = 'Bonjour le monde';
        break;
    case 'Spanish':
        toString = 'Hola Mundo';
        break;
    default:
        toString = 'Hello, world';
}

gs.info(fromString + ' in ' + language + ' ==> ' + toString);

// Create a script that creates 5 teams of 4 people
// and assigns a unique identifier to each team member.
// The script should display the team number,
// person number, and identifier for that person/team.
// Avoid displaying zeros for a better user experience.
//

var id = 1;
for (var team = 0; team < 5; team++) {
    for (var person = 0; person < 4; person++) {
        gs.info('id=' + id + ' team=' + team+1 + ' person=' + person+1);
        ++id;
    }
}

// Lab 6a: Create a script to accept a table name and
// return a list records display values.
// Hint: use GlideRecord.getDisplayValue()
//
// @param tableName - name of table to query
// @return array - list of record display values
//
function listRecords(tableName) {

    var answer = [];
    var recGr = new GlideRecord(tableName);
    recGr.query();
    
    while (recGr.next()) {
        answer.push(recGr.getDisplayValue());
    }
    
    return answer;
}

gs.info(listRecords('incident').join('\n'));

// Lab 6b: Update your previous script to accept a limit parameter.
// Hint: use GlideRecord.setLimit()
//
// @param tableName - name of table to query
// @param limit - integer > 0
// @return array - list of record display values
//
function listRecords(tableName, limit) {

    var answer = [];
    var recGr = new GlideRecord(tableName);
    if (limit && limit > 0) {
        recGr.setLimit(limit);
    }
    recGr.query();
    
    while (recGr.next()) {
        answer.push(recGr.getDisplayValue());
    }
    
    return answer;
}

gs.info(listRecords('incident', 10).join('\n'));

// Update your previous lab to return the sys_id and
// display value of the records you found using an array of objects.
// Return an array of objects.
//
// @param tableName - name of table to query
// @param limit - integer > 0
// @return array of objects
//    {
//      "display_value" : <display value>,
//      "sys_id" : <sys_id>
//    }
//
function listRecords(tableName, limit) {

    var answer = [];
    var recGr = new GlideRecord(tableName);
    if (limit && limit > 0) {
        recGr.setLimit(limit);
    }
    recGr.query();
    
    while (recGr.next()) {
        var obj = {};
        obj.display_value = recGr.getDisplayValue();
        obj.sys_id = recGr.getUniqueValue();
        answer.push(obj);
    }
    
    return answer;
}

var list = listRecords('incident', 10);
gs.info(JSON.stringify(list, null, 4));

// Lab 8a - Rebuild the previous lab as a scripted REST API
//  Use Query parameters to accept the table name and limit
//  Return the array of objects in the response body
//
// Get table record display values and sys_ids
//
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 
    var queryParams = request.queryParams; 
    var tableName   = queryParams.tableName;
    var limit       = queryParams.limit;

    var answer = [];
    var recGr = new GlideRecord(tableName);
    
    if (limit && limit > 0) {
        recGr.setLimit(limit);
    }
    recGr.query();
    
    while (recGr.next()) {
        var obj = {};
        obj.display_value = recGr.getDisplayValue();
        obj.sys_id = recGr.getUniqueValue();
        answer.push(obj);
    }
    
    response.setBody(answer);
    
})(request, response);

// Lab 8b Script Include Test Script
//
var list = new SNJS().getRecords('problem', 5);
gs.info(list.length);

// Script Include
var SNJS = Class.create();
SNJS.prototype = {
    initialize: function() {
    },

    getRecords : function(tableName, limit) {
    
        var answer = [];
        var recGr = new GlideRecord(tableName);
    
           if (limit && limit > 0) {
            recGr.setLimit(limit);
        }
        recGr.query();
    
        while (recGr.next()) {
            var obj = {};
            obj.display_value = recGr.getDisplayValue();
            obj.sys_id = recGr.getUniqueValue();
            answer.push(obj);
        }
        
        return answer;

    },

    type: 'SNJS'
};

// Lab 8b - Rebuild the previous lab using a script include for the core logic
//  Use Query parameters to accept the table name and limit
//  Return the array of objects in the response body
//
// Get table record display values and sys_ids
//
(function process(/*RESTAPIRequest*/ request, /*RESTAPIResponse*/ response) {
 
    var queryParams = request.queryParams; 
    var tableName   = queryParams.tableName;
    var limit.      = queryParams.limit;

    var list = new SNJS().getRecords(tableName, limit);
        
    response.setBody(list);
    
})(request, response);
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0