API Code Samples: Difference between revisions
| (4 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
{{usermanualsapidevelopersguide}} | {{usermanualsapidevelopersguide}} | ||
==Introduction== | ==Introduction== | ||
Following are samples for using the low level | Following are samples for using the low level RangerMSP API. The samples are basic and provide an easy starting point. | ||
__TOC__ | __TOC__ | ||
| Line 64: | Line 64: | ||
GetChargesRecIdOfTkRequstXml = | GetChargesRecIdOfTkRequstXml = | ||
"<?xml version=""1.0"" ?>" & _ | "<?xml version=""1.0"" ?>" & _ | ||
"<? | "<?crmxmlqueryrequest version=""1.0"" ?>" & _ | ||
"< | "<CRMQueryDataRequest>" & _ | ||
"<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _ | "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _ | ||
"<Datakind> CHARGE </Datakind>" & _ | "<Datakind> CHARGE </Datakind>" & _ | ||
| Line 79: | Line 79: | ||
"</Order>" & _ | "</Order>" & _ | ||
"</Query>" & _ | "</Query>" & _ | ||
"</ | "</CRMQueryDataRequest>" | ||
End Function | End Function | ||
| Line 108: | Line 108: | ||
GetChargeRecDataReqXml = | GetChargeRecDataReqXml = | ||
"<?xml version=""1.0"" ?>" & _ | "<?xml version=""1.0"" ?>" & _ | ||
"<? | "<?crmxmlgetrecdatarequest version = ""1.0"" ?>" & _ | ||
"< | "<CRMGetRecDataRequest>" & _ | ||
"<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _ | "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _ | ||
"<GetRecordByRecId>" & xcRecId & "</GetRecordByRecId>" & _ | "<GetRecordByRecId>" & xcRecId & "</GetRecordByRecId>" & _ | ||
"<SelectFieldsList>" & GetChargeFlds() & " </SelectFieldsList>" & _ | "<SelectFieldsList>" & GetChargeFlds() & " </SelectFieldsList>" & _ | ||
"</ | "</CRMGetRecDataRequest>" | ||
End Function | End Function | ||
| Line 135: | Line 135: | ||
Dim aCurChargeRecIdStr As String | Dim aCurChargeRecIdStr As String | ||
Rem **** Establishing connection with | Rem **** Establishing connection with RangerMSP, Should be called only once for the entire session ****** | ||
Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus) | Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus) | ||
| Line 141: | Line 141: | ||
If nStatus <> C_Ok Then | If nStatus <> C_Ok Then | ||
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize) | Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize) | ||
MsgBox (" | MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize ) | ||
Else | Else | ||
rem *** ADD YOUR CODE HERE (replace the line below this section): | rem *** ADD YOUR CODE HERE (replace the line below this section): | ||
| Line 251: | Line 251: | ||
Private Function GetFldAttrRequstXml(xcDicId) | Private Function GetFldAttrRequstXml(xcDicId) | ||
GetFldAttrRequstXml = "<?xml version=""1.0"" ?>" & _ | GetFldAttrRequstXml = "<?xml version=""1.0"" ?>" & _ | ||
"<? | "<?crmxmlgetfieldattributesrequest version = ""1.0"" ?>" & _ | ||
"< | "<CRMGetRecDataRequest>" & _ | ||
"<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _ | "<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _ | ||
"<GetRecordByRecId>" & xcDicId & "</GetRecordByRecId>" & _ | "<GetRecordByRecId>" & xcDicId & "</GetRecordByRecId>" & _ | ||
"</ | "</CRMGetRecDataRequest>" | ||
End Function | End Function | ||
| Line 261: | Line 261: | ||
rem ************************************************************************************************* | rem ************************************************************************************************* | ||
rem *** This code shows how to retrieve field attributes (e.g Field Label, Field Name, etc.) | rem *** This code shows how to retrieve field attributes (e.g Field Label, Field Name, etc.) | ||
rem *** from the | rem *** from the RangerMSP database dictionary. | ||
rem *** It performs the following steps: | rem *** It performs the following steps: | ||
rem *** 1. Initialized a connection with the database | rem *** 1. Initialized a connection with the database | ||
| Line 280: | Line 280: | ||
If nStatus <> C_Ok Then | If nStatus <> C_Ok Then | ||
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize) | Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize) | ||
MsgBox (" | MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize ) | ||
Else | Else | ||
aRequestXml = GetFldAttrRequstXml("FLDCRDCITY") | aRequestXml = GetFldAttrRequstXml("FLDCRDCITY") | ||
| Line 307: | Line 307: | ||
===Data Update API Samples=== | ===Data Update API Samples=== | ||
The following code samples demonstrate how to add and update a record in | The following code samples demonstrate how to add and update a record in RangerMSP from VBA, C++ or Delphi programs. | ||
Make sure to read [[ | Make sure to read [[API Developers Guide|RangerMSP API Developers Guide]] before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used. | ||
To test samples, it is recommended that you download a trial version of | To test samples, it is recommended that you download a trial version of RangerMSP from our web site and install it on a new computer that is not running RangerMSP. Then, modify the paths in the source code to point to folder <testcomputer>\RangerMSP\LastVer (and to the same files it already points to). | ||
When developing your programs please make sure you work under the <testcomputer>\ | When developing your programs please make sure you work under the <testcomputer>\RangerMSP\ThirdParty\UserDev folder (or at least call the dlls in this location). Do not copy the dll’s to any other location. | ||
These samples create a connection to | These samples create a connection to RangerMSP's database, add a new Account record into | ||
the database, and update it. Each transaction should specify the database table to be updated by the transaction. See more details in the [[API Reference Manual]]. | the database, and update it. Each transaction should specify the database table to be updated by the transaction. See more details in the [[API Reference Manual]]. | ||
| Line 365: | Line 365: | ||
If nStatus <> C_Ok Then | If nStatus <> C_Ok Then | ||
MsgBox (" | MsgBox ("RangerMSP Init failed. Error code: " & nStatus) | ||
Else | Else | ||
Rem ******************** Establishing connection with | Rem ******************** Establishing connection with RangerMSP, Should be called only once for the entire session ****** | ||
MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDFULLNAME" + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDCONTACT" | MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDFULLNAME" + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDCONTACT" | ||
DataBuff = "'Bart De Hantsetters','De Hantsetters','Hantsetters'" | DataBuff = "'Bart De Hantsetters','De Hantsetters','Hantsetters'" | ||
| Line 471: | Line 471: | ||
char* C_AppName = "Demo"; | char* C_AppName = "Demo"; | ||
//* Establishing connection with | //* Establishing connection with RangerMSP, Should be called only once for the entire session ** | ||
CmtInitDbEngDll(C_AppName, // Your application name. This will be used for all functions of the | CmtInitDbEngDll(C_AppName, // Your application name. This will be used for all functions of the | ||
// package. | // package. | ||
// Specify a meaningful value. | // Specify a meaningful value. | ||
"C:\\Demo\\DB\\", //Path to the database folder where | "C:\\Demo\\DB\\", //Path to the database folder where RangerMSP the server is | ||
// installed <server>\ | // installed <server>\RangerMSP\Db | ||
&Status); //Returned connection status | &Status); //Returned connection status | ||
| Line 548: | Line 548: | ||
}; | }; | ||
//****Terminate connection with | //****Terminate connection with RangerMSP******************* | ||
CmtTerminateDbEngDll(); | CmtTerminateDbEngDll(); | ||
} | } | ||
else | else | ||
{ | { | ||
printf(" | printf("RangerMSP Init failed. Error code: %d\n", Status); | ||
}; | }; | ||
| Line 592: | Line 592: | ||
s: string; | s: string; | ||
//** Establishing connection with | //** Establishing connection with RangerMSP, Should be called only once for the entire session * | ||
Procedure CmtInitDbEngDll ( | Procedure CmtInitDbEngDll ( | ||
xSoftWareName : PChar; // Your application name. Once selected this string | xSoftWareName : PChar; // Your application name. Once selected this string | ||
// will be used for all | // will be used for all | ||
// functions of the package. Specify a meaningful value. | // functions of the package. Specify a meaningful value. | ||
xDbPath : PChar; // Path to the DB folder under where | xDbPath : PChar; // Path to the DB folder under where RangerMSP server is | ||
// installed <server>\ | // installed <server>\RangerMSP\Db | ||
var xvStatus : integer // Returned connection status | var xvStatus : integer // Returned connection status | ||
| Line 623: | Line 623: | ||
); stdcall; external CmtDbEngDll; | ); stdcall; external CmtDbEngDll; | ||
//**** Terminate connection with | //**** Terminate connection with RangerMSP **** | ||
procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll; | procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll; | ||
| Line 664: | Line 664: | ||
GetMem(aStatusErrCode,C_DescSize); | GetMem(aStatusErrCode,C_DescSize); | ||
CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode); | CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode); | ||
writeln(' | writeln('RangerMSP Init failed. Error code: '+Inttostr(xCode)+' Desc: '+string(aStatusErrCode)); | ||
finally | finally | ||
FreeMem(aStatusErrCode); | FreeMem(aStatusErrCode); | ||
| Line 672: | Line 672: | ||
begin | begin | ||
//**** Establishing connection with | //**** Establishing connection with RangerMSP, Should be called only once for the entire session | ||
CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used | CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used | ||
// for all functions of the package. Specify a meaningful value. | // for all functions of the package. Specify a meaningful value. | ||
'C:\DemoDelphi\db\', // Path to the DB folder under where | 'C:\DemoDelphi\db\', // Path to the DB folder under where RangerMSP server is | ||
// installed <server>\ | // installed <server>\RangerMSP\Db | ||
Status // Returned connection status | Status // Returned connection status | ||
); | ); | ||
| Line 761: | Line 761: | ||
end; | end; | ||
//**** Terminate connection with | //**** Terminate connection with RangerMSP**** | ||
CmtTerminateDbEngDll(); | CmtTerminateDbEngDll(); | ||
| Line 775: | Line 775: | ||
====Python Sample==== | ====Python Sample 1==== | ||
For all field description see the [[API Reference Manual]]. | For all field description see the [[API Reference Manual]]. | ||
| Line 787: | Line 787: | ||
CRMEntity = { | |||
"Account" : 10, | "Account" : 10, | ||
"Accounts" : 10, | "Accounts" : 10, | ||
| Line 810: | Line 810: | ||
} | } | ||
class | class CRMRecord: | ||
def __init__(self, tableID, dataBuff, mapBuff, recID = ""): | def __init__(self, tableID, dataBuff, mapBuff, recID = ""): | ||
self.tableID = tableID | self.tableID = tableID | ||
| Line 827: | Line 827: | ||
return str(self.recIDBuff.raw, encoding='ascii') | return str(self.recIDBuff.raw, encoding='ascii') | ||
class | class CRMDB: | ||
def __init__(self, appName = ' | def __init__(self, appName = 'CRMAgent', CRMPath = r'C:\RangerMSP'): | ||
self.CRMPath = CRMPath | self.CRMPath = CRMPath | ||
self.serverPath = CRMPath + r'\Server' | self.serverPath = CRMPath + r'\Server' | ||
| Line 865: | Line 865: | ||
if __name__ == '__main__': | if __name__ == '__main__': | ||
# db.status should be 1 if library initialized properly | # db.status should be 1 if library initialized properly | ||
db = | db = CRMDB() | ||
db.InitDbEngDll() | db.InitDbEngDll() | ||
| Line 872: | Line 872: | ||
mapStr = "'\n,\nFLDCRDFULLNAME\nFLDCRDCONTACT" | mapStr = "'\n,\nFLDCRDFULLNAME\nFLDCRDCONTACT" | ||
rec = | rec = CRMRecord(tableID = CRMEntity["Account"], | ||
dataBuff = dataStr, | dataBuff = dataStr, | ||
mapBuff = mapStr) | mapBuff = mapStr) | ||
| Line 885: | Line 885: | ||
mapStr = "'\n,\nFLDCRDLASTNAME\nFLDCRDRECID" | mapStr = "'\n,\nFLDCRDLASTNAME\nFLDCRDRECID" | ||
rec = | rec = CRMRecord(tableID = CRMEntity["Account"], | ||
dataBuff = dataStr, | dataBuff = dataStr, | ||
mapBuff = mapStr) | mapBuff = mapStr) | ||
| Line 894: | Line 894: | ||
db.TerminateDbEngDll() | db.TerminateDbEngDll() | ||
</pre> | |||
====Python Sample 2==== | |||
For all field description see the [[API Reference Manual]]. | |||
''Contributed by: Ilja Christensen'' | |||
<pre> | |||
import clr | |||
from System import String, Char, Int32 | |||
CRMLib = clr.AddReference(R'\\RangerMSP\ThirdParty\UserDev\CRMLib.dll') | |||
import CRM | |||
MSP = CRM.Application | |||
MSPConfig = CRM.Config() | |||
MSPConfig.AppName = "CRMAgent" | |||
MSPConfig.DllFolder = R"\\RangerMSP\ThirdParty\UserDev" | |||
MSPConfig.DbFolder = R"\\RangerMSP\Db" | |||
MSP.Initialize(MSPConfig) | |||
print(f"Database initialized: {MSP.instance().initialized_}") | |||
# Search account by name, the list has to be initialized before using it. | |||
accountlist=[] | |||
accountSearch = CRM.ObjectQuery[CRM.Account]() | |||
accountSearch.AddCriteria(CRM.Account.Fields.FileAs, CRM.OperatorEnum.opEqual, 'ACME Cool Company') | |||
accountlist=accountSearch.FetchObjects() | |||
# Display results | |||
print (f"Number of accounts: {len(accountlist)}") | |||
for x in range(len(accountlist)): | |||
print (f"Found REC_ID: {accountlist[x].AccountREC_ID}") | |||
# If we find exactly one record then we update it (otherwise a new record is created) | |||
if (len(accountlist) == 1): | |||
account = CRM.Account(accountlist[0].AccountREC_ID) | |||
else: | |||
account = CRM.Account() | |||
account.FileAs = "ACME Cool Company" | |||
account.Dear = "Mr." | |||
account.Contact = "Johnny Doe" | |||
account.Save() | |||
RecID = account.AccountREC_ID | |||
print (f"Updated: {RecID}") | |||
# Close Database connection | |||
MSP.Terminate() | |||
print(f"Database initialized: {MSP.instance().initialized_}") | |||
</pre> | </pre> | ||
===XML samples=== | ===XML samples=== | ||
Following are samples for adding a new Ticket and a new Charge to the | Following are samples for adding a new Ticket and a new Charge to the RangerMSP database using XML formatted messages. | ||
Make sure to go over the [[Email Connector]] setup guide, and perform the XML API setup steps prior to testing the XML API. | Make sure to go over the [[Email Connector]] setup guide, and perform the XML API setup steps prior to testing the XML API. | ||
Also please read [[ | Also please read [[API_Developers_Guide#Using_API|RangerMSP API Reference Manual]] before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used. | ||
Notes on API by Email Activation: | Notes on API by Email Activation: | ||
| Line 910: | Line 959: | ||
*Using a Password - If you wish to use a verification password for the XML transactions, define the password using the ServerConfig.exe utility. To do so, go to the XML tab, enable the API by Email option and set a password (as specified in the XML - see [[API_Code_Samples#General_XML_Tokens|General XML Tokens]]). Make sure to set the same Password in ServerConfig and in the XML email itself. | *Using a Password - If you wish to use a verification password for the XML transactions, define the password using the ServerConfig.exe utility. To do so, go to the XML tab, enable the API by Email option and set a password (as specified in the XML - see [[API_Code_Samples#General_XML_Tokens|General XML Tokens]]). Make sure to set the same Password in ServerConfig and in the XML email itself. | ||
You can read more about the ServerConfig and how to setup the API by Email configuration in the [[Email Connector| | You can read more about the ServerConfig and how to setup the API by Email configuration in the [[Email Connector|RangerMSP Email Connector]] Setup guide. | ||
| Line 920: | Line 969: | ||
<?xml version="1.0" ?> | <?xml version="1.0" ?> | ||
<? | <?crmxml version = "1.0" ?> | ||
< | <crmTransaction> | ||
<ExternalApplicationName>N-Able</ExternalApplicationName> | <ExternalApplicationName>N-Able</ExternalApplicationName> | ||
<SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail> | <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail> | ||
| Line 931: | Line 980: | ||
... the transaction goes here ... | ... the transaction goes here ... | ||
</RecordData> | </RecordData> | ||
</ | </crmTransaction> | ||
{| class="wikitable" | {| class="wikitable" | ||
| Line 941: | Line 990: | ||
| The XML version - Always 1.0 | | The XML version - Always 1.0 | ||
|- | |- | ||
| <? | | <?crmxml version ="1.0" ?> | ||
| The | | The RangerMSP API XML version - Always 1.0 | ||
|- | |- | ||
| < | | <crmTransaction> | ||
| Start and end transactions with this token (may have more than one in a single email) | | Start and end transactions with this token (may have more than one in a single email) | ||
|- | |- | ||
| Line 954: | Line 1,003: | ||
|- | |- | ||
| <Password> | | <Password> | ||
| Optional Password - Only emails with a password that matches the password set in the Email Connector Settings will be processed (to prevent SPAM email from being processed and added to your | | Optional Password - Only emails with a password that matches the password set in the Email Connector Settings will be processed (to prevent SPAM email from being processed and added to your RangerMSP database). | ||
|- | |- | ||
| <DataKind> | | <DataKind> | ||
| Line 976: | Line 1,025: | ||
<?xml version="1.0" ?> | <?xml version="1.0" ?> | ||
<? | <?crmxml version = "1.0" ?> | ||
< | <crmTransaction> | ||
<ExternalApplicationName>N-Able</ExternalApplicationName> | <ExternalApplicationName>N-Able</ExternalApplicationName> | ||
<SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail> | <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail> | ||
| Line 995: | Line 1,044: | ||
<FLDTKTFORDISPATCH>Y</FLDTKTFORDISPATCH> | <FLDTKTFORDISPATCH>Y</FLDTKTFORDISPATCH> | ||
</RecordData> | </RecordData> | ||
</ | </crmTransaction> | ||
====Adding new Charges==== | ====Adding new Charges==== | ||
<?xml version="1.0" ?> | <?xml version="1.0" ?> | ||
<? | <?crmxml version = "1.0" ?> | ||
< | <crmTransaction> | ||
<ExternalApplicationName>Alert</ExternalApplicationName> | <ExternalApplicationName>Alert</ExternalApplicationName> | ||
<SendResponseToEmail>your email address for responses</SendResponseToEmail> | <SendResponseToEmail>your email address for responses</SendResponseToEmail> | ||
| Line 1,022: | Line 1,071: | ||
<FLDSLPUSER1> Field 1... </FLDSLPUSER1> | <FLDSLPUSER1> Field 1... </FLDSLPUSER1> | ||
</RecordData> | </RecordData> | ||
</ | </crmTransaction> | ||
| Line 1,033: | Line 1,082: | ||
<?xml version="1.0" ?> | <?xml version="1.0" ?> | ||
<? | <?crmxml version="1.0" ?> | ||
< | <crmResponse> | ||
<Status>SUCCESS</Status> | <Status>SUCCESS</Status> | ||
<AffectedRecId>TKTN1NIQEYYQ8PBJMDAX</AffectedRecId> | <AffectedRecId>TKTN1NIQEYYQ8PBJMDAX</AffectedRecId> | ||
<ReturnTransactionID>data from external application (as-is)</ReturnTransactionID> | <ReturnTransactionID>data from external application (as-is)</ReturnTransactionID> | ||
</ | </crmResponse> | ||
<u>Response in case of error:</u> | <u>Response in case of error:</u> | ||
<?xml version="1.0" ?> | <?xml version="1.0" ?> | ||
<? | <?crmxml version="1.0" ?> | ||
< | <crmResponse> | ||
<Status>FAILURE</Status> | <Status>FAILURE</Status> | ||
<AffectedRecId></AffectedRecId> | <AffectedRecId></AffectedRecId> | ||
| Line 1,053: | Line 1,102: | ||
TKTN1NIQEYYQ8PBJMDAX | TKTN1NIQEYYQ8PBJMDAX | ||
</ResultMessage> | </ResultMessage> | ||
</ | </crmResponse> | ||
| Line 1,064: | Line 1,113: | ||
| The XML version - Always 1.0 | | The XML version - Always 1.0 | ||
|- | |- | ||
| <? | | <?crmxml version ="1.0" ?> | ||
| The | | The RangerMSP API XML version - Always 1.0 | ||
|- | |- | ||
| < | | <crmResponse> | ||
| The response starts and ends with this token | | The response starts and ends with this token | ||
|- | |- | ||
| Line 1,080: | Line 1,129: | ||
|- | |- | ||
|<ResultCodes><br><ResultMessage> | |<ResultCodes><br><ResultMessage> | ||
|In case of a failure, this will contain the error code and description. You can find more information about error codes [[ | |In case of a failure, this will contain the error code and description. You can find more information about error codes [[API Reference Manual#Error Codes Description|here]]. | ||
|} | |} | ||
== See Also == | == See Also == | ||
*[[ | *[[API Developers Guide|API Developers Guide]] | ||
*[[API Reference Manual]] | *[[API Reference Manual]] | ||
[[Category:User Manuals]] | [[Category:User Manuals]] | ||
[[Category:Integration]] | [[Category:Integration]] | ||
Latest revision as of 11:36, 2 November 2020
Introduction
Following are samples for using the low level RangerMSP API. The samples are basic and provide an easy starting point.
API functions
For detailed listing of the API functions and their parameters see API Functions Reference Manual.
Code samples
Data Retrieval API Samples
VB Sample - Data Retrieval
Private Declare Sub CmtInitDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xSoftWareName As String, _
ByVal xDbPath As String, _
ByRef xvStatus As Integer)
Private Declare Sub CmtTerminateDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ()
Private Declare Sub CmtGetDescriptionByCode Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xCode As Long, _
ByVal xDescLen As Long, _
ByVal xvDesc As String)
Private Declare Sub CmtGetDescriptionByStatus Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xCode As Long, _
ByVal xDescLen As Long, _
ByVal xvDesc As String)
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
Private Declare Sub CmtGetFieldAttributesByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xXMLRequestBuff As String, _
ByVal xXMLRequestBuffLen As Integer, _
ByVal xXMLResponseDataBuff As String, _
ByVal xXMLResponseDataBuffLen As Integer, _
ByRef xvStatus As Integer)
Private Declare Sub CmtGetRecordDataByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xXMLRequestBuff As String, _
ByVal xXMLRequestBuffLen As Integer, _
ByVal xXMLResponseDataBuff As String, _
ByVal xXMLResponseDataBuffLen As Integer, _
ByRef xvStatus As Integer)
Private Declare Sub CmtGetQueryRecIds Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xXMLRequestBuff As String, _
ByVal xXMLRequestBuffLen As Integer, _
ByVal xXMLResponseDataBuff As String, _
ByVal xXMLResponseDataBuffLen As Integer, _
ByRef xvStatus As Integer)
Private Const C_Ok As Integer = 1
Private Const C_AppName As String = "Demo"
Private Const C_ErrorDescSize As Integer = 1024
Private Const C_REC_ID_LEN As Integer = 20
Private Const C_TktDataBuffSize As Integer = 1024
Private Const C_ChargeDataBuffSize As Integer = 16384
rem *** XML containing a query for retrieving Charges of a specific Ticket
Private Function GetChargesRecIdOfTkRequstXml(xcTktRecId)
GetChargesRecIdOfTkRequstXml =
"<?xml version=""1.0"" ?>" & _
"<?crmxmlqueryrequest version=""1.0"" ?>" & _
"<CRMQueryDataRequest>" & _
"<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
"<Datakind> CHARGE </Datakind>" & _
"<MaxRecordCount> 100 </MaxRecordCount>" & _
"<Query>" & _
"<Where>" & _
"<Link> ( </Link>" & _
"<FLDSLPTICKETID op=""="">" & xcTktRecId & "</FLDSLPTICKETID>" & _
"<Link> ) </Link>" & _
"</Where>" & _
"<Order>" & _
"<FLDSLPSLIPDATE dir=""asc""> </FLDSLPSLIPDATE>" & _
"</Order>" & _
"</Query>" & _
"</CRMQueryDataRequest>"
End Function
rem *** String containing the Charge fields to be retrieved
Private Function GetChargeFlds()
GetChargeFlds = "FLDSLPCARDID_FLDCRDFULLNAME" & "," & _
"FLDSLPCONTACTID_FLDCRDCONTACT" & "," & _
"FLDSLPTICKETID_FLDTKTTICKETNO" & "," & _
"FLDSLPBCRECID_FLDBCTCODE" & "," & _
"FLDSLPBCRECID_FLDBCTNAME" & "," & _
"FLDSLPITEMID_FLDITMITEMNO" & "," & _
"FLDSLPITEMID_FLDITMNAME" & "," & _
"FLDSLPSLIPDATE" & "," & _
"FLDSLPSTARTTIME" & "," & _
"FLDSLPENDTIME" & "," & _
"FLDSLPQUANTITY" & "," & _
"FLDSLPPRICE" & "," & _
"FLDSLPBILLTOTAL" & "," & _
"FLDSLPHOURSAMOUNT" & "," & _
"FLDSLPITEMUNITISHOUR" & "," & _
"FLDSLPITEMTYPEGROUP" & "," & _
"FLDSLPRECID" & "," & _
"FLDSLPDESC"
End Function
rem *** XML for retrieving a specific Charge
Private Function GetChargeRecDataReqXml(xcRecId)
GetChargeRecDataReqXml =
"<?xml version=""1.0"" ?>" & _
"<?crmxmlgetrecdatarequest version = ""1.0"" ?>" & _
"<CRMGetRecDataRequest>" & _
"<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
"<GetRecordByRecId>" & xcRecId & "</GetRecordByRecId>" & _
"<SelectFieldsList>" & GetChargeFlds() & " </SelectFieldsList>" & _
"</CRMGetRecDataRequest>"
End Function
rem *************************************************************************************************
rem *** This code shows how to retrieve charges of a specific Ticket.
rem *** It performs the following steps:
rem *** 1. Initialized a connection with the database
rem *** 2. Calls CmtGetQueryRecIds to retrieve the Charges of a specific ticket according to the query
rem *** defined in aRequestXml (which is returned from GetChargesRecIdOfTkRequstXml)
rem *** 3. Calls CmtGetRecordDataByRecId to retrieve the Charge details of all charges returned.
rem *************************************************************************************************
Public Sub DbQry()
Dim nStatus As Integer
Dim aTktXMLResponseDataBuff As String * C_TktDataBuffSize
Dim aChargeXMLResponseDataBuff As String * C_ChargeDataBuffSize
Dim aErrorDescSize As String * C_ErrorDescSize
Dim aChargesRecIdStr As String
Dim aCurChargeRecIdStr As String
Rem **** Establishing connection with RangerMSP, Should be called only once for the entire session ******
Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus)
If nStatus <> C_Ok Then
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
Else
rem *** ADD YOUR CODE HERE (replace the line below this section):
rem *** Change the ticket ID below to fit a real ticket in your database.
aRequestXml = GetChargesRecIdOfTkRequstXml("TKTVHIUTGO5KGUUCB4SL")
Call CmtGetQueryRecIds(aRequestXml, Len(aRequestXml), aTktXMLResponseDataBuff, C_TktDataBuffSize, nStatus)
If nStatus <> C_Ok Then
MsgBox (aTktXMLResponseDataBuff)
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
rem *** ADD YOUR CODE HERE:
rem *** parse the XML Buffer -> aTktXMLResponseDataBuff. Extract the error code that was returned from the api***
rem *** Call CmtGetDescriptionByCode(ErrorCodeFromXml, C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )
Else
MsgBox (aTktXMLResponseDataBuff)
rem **** ADD YOUR CODE HERE (replace the line below this section):
rem **** parse the XML Buffer(extract the charge(s) recid of the ticket) -> aTktXMLResponseDataBuff ****
rem **** The aChargesRecIdStr vairable contain the Charges recid that were extracted from the XML buffer
aChargesRecIdStr = "SLPXBV3YB7F9F2DPGDC5SLPLORCIOPWYP5VW4NWASLPFYKGUNYT8E3NE23XU"
Do while (Len(aChargesRecIdStr)> 0 )
aCurChargeRecIdStr = Left(aChargesRecIdStr, C_REC_ID_LEN)
aChargesRecIdStr = Right(aChargesRecIdStr, Len(aChargesRecIdStr) - C_REC_ID_LEN)
aRequestXml = GetChargeRecDataReqXml(aCurChargeRecIdStr)
Call CmtGetRecordDataByRecId(aRequestXml, Len(aRequestXml), aChargeXMLResponseDataBuff, C_ChargeDataBuffSize, nStatus)
If nStatus <> C_Ok Then
MsgBox (aChargeXMLResponseDataBuff )
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
rem *** ADD YOUR CODE HERE:
rem *** parse the XML Buffer -> aChargeXMLResponseDataBuff. Extract the error code that was return from the api***
rem *** Call CmtGetDescriptionByCode(nStatus,C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )
Else
MsgBox (aChargeXMLResponseDataBuff)
rem **** ADD YOUR CODE HERE: parse the XML Buffer(extract the charge info) -> aChargeXMLResponseDataBuff ****
End If
loop
End If
End If
Call CmtTerminateDbQryDll
End Sub
VB Sample - Field Attributes Retrieval
Private Declare Sub CmtInitDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xSoftWareName As String, _
ByVal xDbPath As String, _
ByRef xvStatus As Integer)
Private Declare Sub CmtTerminateDbQryDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ()
Private Declare Sub CmtGetDescriptionByCode Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xCode as long, _
ByVal xDescLen as long, _
ByVal xvDesc As String)
Private Declare Sub CmtGetDescriptionByStatus Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xCode as long, _
ByVal xDescLen as long, _
ByVal xvDesc As String)
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
Private Declare Sub CmtGetFieldAttributesByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xXMLRequestBuff As String, _
ByVal xXMLRequestBuffLen As Integer, _
ByVal xXMLResponseDataBuff As String, _
ByVal xXMLResponseDataBuffLen As Integer, _
ByRef xvStatus As Integer)
Private Declare Sub CmtGetRecordDataByRecId Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xXMLRequestBuff As String, _
ByVal xXMLRequestBuffLen As Integer, _
ByVal xXMLResponseDataBuff As String, _
ByVal xXMLResponseDataBuffLen As Integer, _
ByRef xvStatus As Integer)
Private Declare Sub CmtGetQueryRecIds Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbQry.dll" ( _
ByVal xXMLRequestBuff As String, _
ByVal xXMLRequestBuffLen As Integer, _
ByVal xXMLResponseDataBuff As String, _
ByVal xXMLResponseDataBuffLen As Integer, _
ByRef xvStatus As Integer)
Private Const C_Ok As Integer = 1
Private Const C_AppName As String = "Demo"
Private Const C_ErrorDescSize As Integer = 1024
Private Const C_DataBuffSize As Integer = 1024
rem *** XML containing the request for CmtGetFieldAttributesByRecId with the requested Field ID
Private Function GetFldAttrRequstXml(xcDicId)
GetFldAttrRequstXml = "<?xml version=""1.0"" ?>" & _
"<?crmxmlgetfieldattributesrequest version = ""1.0"" ?>" & _
"<CRMGetRecDataRequest>" & _
"<ExternalApplicationName>" & C_AppName & "</ExternalApplicationName>" & _
"<GetRecordByRecId>" & xcDicId & "</GetRecordByRecId>" & _
"</CRMGetRecDataRequest>"
End Function
rem *************************************************************************************************
rem *** This code shows how to retrieve field attributes (e.g Field Label, Field Name, etc.)
rem *** from the RangerMSP database dictionary.
rem *** It performs the following steps:
rem *** 1. Initialized a connection with the database
rem *** 2. Calls CmtGetFieldAttributesByRecId to retrieve the details of a specific field according to the field ID defined
rem *** in aRequestXml
rem *************************************************************************************************
Public Sub DbQry()
Dim nStatus As Integer
Dim aXMLResponseDataBuff As String * C_DataBuffSize
Dim aErrorDescSize As String * C_ErrorDescSize
Dim aRequestXml as String
Call CmtInitDbQryDll(C_AppName, "c:\DemoVBA\DB\", nStatus)
If nStatus <> C_Ok Then
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
MsgBox ("RangerMSP Init failed. Status Error code: " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
Else
aRequestXml = GetFldAttrRequstXml("FLDCRDCITY")
Call CmtGetFieldAttributesByRecId(aRequestXml, Len(aRequestXml), aXMLResponseDataBuff, C_DataBuffSize, nStatus)
If nStatus <> C_Ok Then
MsgBox (aXMLResponseDataBuff )
Call CmtGetDescriptionByStatus(nStatus, C_ErrorDescSize, aErrorDescSize)
MsgBox ("Failed. Status Error : " & nStatus & CHR(13) & CHR(10) & aErrorDescSize )
rem *** ADD YOUR CODE HERE: parse the XML Buffer -> aXMLResponseDataBuff. Extract the error code that was return from the api***
rem *** Call CmtGetDescriptionByCode(ErrorCodeFromXml , C_ErrorDescSize, aErrorDescSize)
rem *** MsgBox ("Failed. XML Error : " & ErrorCodeFromXml & CHR(13) & CHR(10) & aErrorDescSize )
Else
MsgBox (aXMLResponseDataBuff)
rem *** ADD YOUR CODE HERE: parse the XML Buffer -> aXMLResponseDataBuff ***
End If
End If
Call CmtTerminateDbQryDll
End Sub
Data Update API Samples
The following code samples demonstrate how to add and update a record in RangerMSP from VBA, C++ or Delphi programs.
Make sure to read RangerMSP API Developers Guide before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used.
To test samples, it is recommended that you download a trial version of RangerMSP from our web site and install it on a new computer that is not running RangerMSP. Then, modify the paths in the source code to point to folder <testcomputer>\RangerMSP\LastVer (and to the same files it already points to).
When developing your programs please make sure you work under the <testcomputer>\RangerMSP\ThirdParty\UserDev folder (or at least call the dlls in this location). Do not copy the dll’s to any other location.
These samples create a connection to RangerMSP's database, add a new Account record into the database, and update it. Each transaction should specify the database table to be updated by the transaction. See more details in the API Reference Manual.
VB Sample
Private Declare Sub CmtInitDbEngDll Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbEng.dll" (ByVal xSoftWareName As String, _
ByVal xDbPath As String, ByRef xvStatus As Integer)
Private Declare Sub InitCommonControls Lib "comctl32.dll" ()
Private Declare Sub CmtInsUpdRec Lib "C:\DemoVBA\ThirdParty\UserDev\CmtDbEng.dll" (ByVal xSoftWareName As String, _
ByVal xDataKind As Integer, _
ByVal xDataBuff As String, _
ByVal xMapBuff As String, _
ByVal xContWhenInvalidData As Integer, _
ByVal xFlags As Integer, _
ByVal xRecIDBuffLen As Integer, _
ByVal xLogErrCodesBuffLen As Integer, _
ByVal xLogErrMsgBuffLen As Integer, _
ByVal xvRecIDBuff As String, _
ByVal xvErrCodesLogBuff As String, _
ByVal xvErrMsgLogBuff As String, _
ByRef xvStatus As Integer)
Private Const C_DataBuffSize As Integer = 1024
Private Const C_MapBufSize As Integer = 1024
Private Const C_ErrMsgBuffSize As Integer = 1024
Private Const C_ErrCodeBuffSize As Integer = 64
Private Const C_RecIDBuffSize As Integer = 20
Private Const C_Flag As Integer = 1
Private Const C_Ok As Integer = 1
Private Const C_AccountsTable As Integer = 10
Private Const C_AppName As String = "Demo"
Public Sub DBEng()
Dim nStatus As Integer
Dim l As Long
Dim S As String
Dim pStr As Long
Dim MapBuff As String
Dim DataBuff As String
Dim RecIdBuff As String * C_RecIDBuffSize
Dim ErrCodesLogBuff As String * C_ErrCodeBuffSize
Dim ErrMsgLogBuff As String * C_ErrMsgBuffSize
Call CmtInitDbEngDll(C_AppName, "c:\DemoVBA\DB\", nStatus)
If nStatus <> C_Ok Then
MsgBox ("RangerMSP Init failed. Error code: " & nStatus)
Else
Rem ******************** Establishing connection with RangerMSP, Should be called only once for the entire session ******
MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDFULLNAME" + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDCONTACT"
DataBuff = "'Bart De Hantsetters','De Hantsetters','Hantsetters'"
Call CmtInsUpdRec(C_AppName, _
C_AccountsTable, _
DataBuff, _
MapBuff, _
C_Flag, _
0, _
C_RecIDBuffSize, _
C_ErrCodeBuffSize, _
C_ErrMsgBuffSize, _
RecIdBuff, _
ErrCodesLogBuff, _
ErrMsgLogBuff, _
nStatus)
If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
If nStatus <> C_Ok Then
MsgBox ("Insert new Account. Error code: " & nStatus)
Else
Rem ******************** Updating the Account record we've just created *******************
MapBuff = "'" + Chr(13) + "," + Chr(13) + "FLDCRDDEAR" + Chr(13) + "FLDCRDRECID"
DataBuff = "'Doctor','" + RecIdBuff + "'"
ErrCodesBuff = ""
ErrMsgBuff = ""
Call CmtInsUpdRec(C_AppName, _
C_AccountsTable, _
DataBuff, _
MapBuff, _
C_Flag, _
0, _
C_RecIDBuffSize, _
C_ErrCodeBuffSize, _
C_ErrMsgBuffSize, _
RecIdBuff, _
ErrCodesLogBuff, _
ErrMsgLogBuff, _
nStatus)
If nStatus <> C_Ok Then MsgBox ("Update Account. Error code: " & nStatus)
If (ErrMsgBuff <> "") Then MsgBox ("Error Message: " + ErrMsgBuff)
End If
End If
End Sub
C++ Sample
For all field description see the API Reference Manual.
// Demo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "CmtDBEng.h"
#include <string.h>
#include <stdlib.h>
int ErrCodesParsing (char* ErrCodeBuff)
{
// Demo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "CmtDBEng.h"
#include <string.h>
#include <stdlib.h>
int ErrCodesParsing (char* ErrCodeBuff)
{
const int C_DescSize = 1024;
char desc[C_DescSize];
char Delimiter[] = "\n";
int Code;
char* pch;
pch = strtok (ErrCodeBuff,Delimiter);
while (pch != NULL)
{
Code = atoi(pch);
CmtGetDescriptionByCode(Code, C_DescSize, desc);
printf ("%s\n",desc);
pch = strtok (NULL, Delimiter);
}
return 0;
}
int main(int argc, char* argv[])
{
const int C_DataBuffSize = 1024;
const int C_MapBufSize = 1024;
const int C_ErrMsgBuffSize = 1024;
const int C_ErrCodeBuffSize = 64;
const int C_RecIDBuffSize = 64;
const int C_Flag = 1;
const int C_Ok = 1;
const int C_AccountsTable = 10;
const int C_ExampleCode = 54000;
int Status;
char DataBuff[C_DataBuffSize] = "";
char MapBuff[C_MapBufSize] = "";
char RecIdBuff[C_RecIDBuffSize];
char ErrCodesBuff[C_ErrCodeBuffSize];
char ErrMsgBuff[C_ErrMsgBuffSize];
char* C_AppName = "Demo";
//* Establishing connection with RangerMSP, Should be called only once for the entire session **
CmtInitDbEngDll(C_AppName, // Your application name. This will be used for all functions of the
// package.
// Specify a meaningful value.
"C:\\Demo\\DB\\", //Path to the database folder where RangerMSP the server is
// installed <server>\RangerMSP\Db
&Status); //Returned connection status
if (Status == C_Ok) {
//***Insert New Account into that Accounts table *******************
strcpy (DataBuff,"'Bart De Hantsetters','De Hantsetters','Hantsetters'");
strcat (MapBuff, "'\n,\nFLDCRDFULLNAME\nFLDCRDDEAR\nFLDCRDCONTACT");
strcat (RecIdBuff, "");
strcat (ErrCodesBuff, "");
strcat (ErrMsgBuff, "");
CmtInsUpdRec(C_AppName, //String for your selection.
C_AccountsTable, //Desired Table Code
DataBuff, //This string contains the values which we want to add to the database
MapBuff, //List of database fields where we want to add data
C_Flag,//Flag - stop(0) continue(1) the input process is data
//value(s) is invalid
0, //Not used
C_RecIDBuffSize, //Length of REC ID Buffer
C_ErrCodeBuffSize, //Length of Error Code Buffer
C_ErrMsgBuffSize, //Length of Error Message Buffer
RecIdBuff, //Buffer for returned REC ID
ErrCodesBuff, //Buffer for returned Error Codes
ErrMsgBuff, //Bufer for returned Error Messages
&Status //Returned status
);
if (ErrMsgBuff == "")
printf("Error Message: %s", ErrMsgBuff);
ErrCodesParsing(ErrCodesBuff);
if (Status == C_Ok) {
//***** Updating the Account record we've just created *************
strcpy (MapBuff, "'\n,\nFLDCRDDEAR\nFLDCRDRECID"); // Map file for the update
// transaction - the Dear field and the record id
strcpy (DataBuff,"'Doctor','");
strcat (DataBuff, RecIdBuff);
strcat (DataBuff, "'");
strcat (ErrCodesBuff, "");
strcat (ErrMsgBuff, "");
CmtInsUpdRec(C_AppName, // string for your selection.
C_AccountsTable, // Desired Table Code
DataBuff, // string contains the values, which we want to add into the Database
MapBuff, // list of the Database Fields in which we want to add data
C_Flag, // Flag - stop(0)/continue(1) the input process is some data
// value(s) is invalid
0, // Not used
C_RecIDBuffSize, // length of RecID Buffer
C_ErrCodeBuffSize, // length of Error Code Buffer
C_ErrMsgBuffSize, // length of Error Message Buffer
RecIdBuff, // buffer for returned RecID
ErrCodesBuff, // buffer for returned Error Codes
ErrMsgBuff, // bufer for returned Error Messages
&Status // returned status
);
if (ErrMsgBuff == "")
printf("Error Message: %s", ErrMsgBuff);
ErrCodesParsing(ErrCodesBuff);
}
else
{
printf("Insert new Account. Error code: %d\n", Status);
};
//****Terminate connection with RangerMSP*******************
CmtTerminateDbEngDll();
}
else
{
printf("RangerMSP Init failed. Error code: %d\n", Status);
};
return 0;
}
Delphi Sample
For all field description see the API Reference Manual.
program Demo;
{$APPTYPE CONSOLE}
uses
SysUtils, Classes;
const
C_DataBuffSize = 1024;
C_MapBufSize = 1024;
C_ErrMsgBuffSize = 1024;
C_DescSize = 1024;
C_ErrCodeBuffSize = 64;
C_RecIDBuffSize = 64;
C_Flag = 1;
C_Ok = 1;
C_AccountsTable = 10;
C_AppName = 'Demo';
CmtDbEngDll = 'CmtDbEng.DLL';
var
Status: integer;
DataBuff: array [0..C_DataBuffSize] of Char;
MapBuff: array [0..C_MapBufSize] of Char;
RecIdBuff: array [0..C_RecIDBuffSize] of Char;
ErrCodesBuff: array [0..C_ErrCodeBuffSize] of Char;
ErrMsgBuff: array [0..C_ErrMsgBuffSize] of Char;
s: string;
//** Establishing connection with RangerMSP, Should be called only once for the entire session *
Procedure CmtInitDbEngDll (
xSoftWareName : PChar; // Your application name. Once selected this string
// will be used for all
// functions of the package. Specify a meaningful value.
xDbPath : PChar; // Path to the DB folder under where RangerMSP server is
// installed <server>\RangerMSP\Db
var xvStatus : integer // Returned connection status
); stdcall; external CmtDbEngDll;
//**** Insert/Update record
Procedure CmtInsUpdRec(
xSoftWareName : pChar; // See above
xDataKind : integer; // Desired Table Code
xDataBuff : pChar; // String containing the values, which we want
// to add into the Database
xMapBuff : pChar; // List of the database fields into
//which we want to add data
xContWhenInvalidData : Integer; //Flag - stop(0)/continue(1) the input process
// is some data value(s) is invalid
xFlags : Integer; // Not used
xRecIDBuffLen : Integer; // Length of REC ID Buffer
xLogErrCodesBuffLen : Integer; // Length of Error Code Buffer
xLogErrMsgBuffLen : Integer; // Length of Error Message Buffer
xvRecIDBuff : pChar; // Buffer for returned REC ID
xvErrCodesLogBuff : pChar; // Buffer for returned Error Codes
xvErrMsgLogBuff : pChar; // Buffer for returned Error Messages
var xvStatus : Integer // Returned status
); stdcall; external CmtDbEngDll;
//**** Terminate connection with RangerMSP ****
procedure CmtTerminateDbEngDll; stdcall; external CmtDbEngDll;
procedure CmtGetDescriptionByCode(
xCode : Integer;
xDescLen : Integer;
xvDesc : pChar); stdcall; external CmtDbEngDll;
procedure CmtGetDescriptionByStatus(
xCode : Integer;
xDescLen : Integer;
xvDesc : pChar); stdcall; external CmtDbEngDll;
procedure ErrCodesParsing (ErrCodeBuff: string);
var
lList: TStringList;
i: integer;
aDescErrCode : Pchar;
begin
try
lList := TStringList.Create;
lList.Text := ErrCodeBuff;
GetMem(aDescErrCode,C_DescSize);
for i := 0 to lList.Count - 1 do
begin
CmtGetDescriptionByCode(StrToInt(lList[i]), C_DescSize, aDescErrCode);
writeln('Error Code: '+lList[i]+' Desc: '+string(aDescErrCode));
end;
finally
FreeMem(aDescErrCode);
lList.Destroy;
end;
end;
procedure DisplayErrStatusCode(xCode : Integer);
var
aStatusErrCode : Pchar;
begin
try
GetMem(aStatusErrCode,C_DescSize);
CmtGetDescriptionByStatus(xCode,C_DescSize, aStatusErrCode);
writeln('RangerMSP Init failed. Error code: '+Inttostr(xCode)+' Desc: '+string(aStatusErrCode));
finally
FreeMem(aStatusErrCode);
end;
end;
begin
//**** Establishing connection with RangerMSP, Should be called only once for the entire session
CmtInitDbEngDll(C_AppName, // Your application name. Once selected this string will be used
// for all functions of the package. Specify a meaningful value.
'C:\DemoDelphi\db\', // Path to the DB folder under where RangerMSP server is
// installed <server>\RangerMSP\Db
Status // Returned connection status
);
if Status = C_Ok then
begin
//**** Insert a new Account into the Accounts table ****
s := '"Bart De Hantsetters","De Hantsetters","Hantsetters"';
StrPCopy(DataBuff, s);
s := '"'+#13','+#13+'FLDCRDFULLNAME'+#13+'FLDCRDDEAR'+#13+'FLDCRDCONTACT'+#0;
StrPCopy(MapBuff, s);
CmtInsUpdRec(C_AppName, // Your application name
C_AccountsTable, // Desired Table Code
DataBuff, // String containing the values, which we want to add into
// the Database
MapBuff, // List of the Database Fields in which we want to add data
C_Flag, // Flag - stop(0)/continue(1) the input process is some data
// value(s) is invalid
0, // Not used
C_RecIDBuffSize, // Llength of REC ID Buffer
C_ErrCodeBuffSize, // Length of Error Code Buffer
C_ErrMsgBuffSize, // Length of Error Message Buffer
RecIdBuff, // Buffer for returned REC ID
ErrCodesBuff, // Buffer for returned Error Codes
ErrMsgBuff, // Buffer for returned Error Messages
Status // Returned status
);
if (ErrMsgBuff[0] <> #0) then
writeln('Error Message: '+ ErrMsgBuff);
ErrCodesParsing(ErrCodesBuff);
if Status = C_Ok then
begin
//**** Updating the Account record we've just created *****
// Map file for the update transaction - the Dear field and the record id
s := '"'+#13+','+#13+'FLDCRDDEAR'+#13'FLDCRDRECID';
StrPCopy(MapBuff, s);
s := '"Doctor","'+RecIdBuff+'"';
StrPCopy(DataBuff, s);
CmtInsUpdRec(C_AppName, // Your application name
C_AccountsTable, // Desired Table Code
DataBuff, // String containing the values, which we want
// to add into the Database
MapBuff, // List of the database fields into which we want to add
//data
C_Flag, // Flag - stop(0)/continue(1) the input process is some
// data value(s) is invalid
0, // Not used
C_RecIDBuffSize, // Length of REC ID Buffer
C_ErrCodeBuffSize, // Length of Error Code Buffer
C_ErrMsgBuffSize, // Length of Error Message Buffer
RecIdBuff, // Buffer for returned RECID
ErrCodesBuff, // Buffer for returned Error Codes
ErrMsgBuff, // Buffer for returned Error Messages
Status // Returned status
);
if ((ErrMsgBuff[0] <> #0)) then
writeln('Error Message: '+ ErrMsgBuff);
ErrCodesParsing(ErrCodesBuff);
if Status = C_Ok then
Writeln('Completed Successfully');
end
else
begin
try
s := IntToStr(Status);
except
s := 'ill-defined';
end;
writeln('Insert new Account. Error code: '+ s);
end;
//**** Terminate connection with RangerMSP****
CmtTerminateDbEngDll();
end
else
begin
DisplayErrStatusCode(Status);
end;
writeln(#13#10+'press Enter to quit');
readln;
end.
Python Sample 1
For all field description see the API Reference Manual.
Contributed by: Joe Kogut
Note: The example was tested on Python 3.5, but will work with Python 2.7 with minor modifications.
import os
from ctypes import *
CRMEntity = {
"Account" : 10,
"Accounts" : 10,
"Opportunitity" : 20,
"Opportunities" : 20,
"Document" : 30,
"Documents" : 30,
"Charge" : 40,
"Charges" : 40,
"Event" : 50,
"Events" : 50,
"HistoryNote" : 60,
"HistoryNotes" : 60,
"Ticket" : 70,
"Tickets" : 70,
"Item" : 80,
"Items" : 80,
"Asset" : 90,
"Assets" : 90,
"KBArticle" : 100,
"KBArticles" : 100
}
class CRMRecord:
def __init__(self, tableID, dataBuff, mapBuff, recID = ""):
self.tableID = tableID
self.dataBuff = create_string_buffer(bytes(dataBuff, "ascii"))
self.mapBuff = create_string_buffer(bytes(mapBuff, "ascii"))
self.recIDBuffSize = 20
self.errCodesBuffSize = 64
self.errMsgBuffSize = 1024
self.recIDBuff = create_string_buffer(bytes(recID, "ascii"), self.recIDBuffSize)
self.errCodesBuff = create_string_buffer(self.errCodesBuffSize)
self.errMsgBuff = create_string_buffer(self.errMsgBuffSize)
def getRecID(self):
return str(self.recIDBuff.raw, encoding='ascii')
class CRMDB:
def __init__(self, appName = 'CRMAgent', CRMPath = r'C:\RangerMSP'):
self.CRMPath = CRMPath
self.serverPath = CRMPath + r'\Server'
self.DBPath = CRMPath + r'\Db'
self.DBPath_bytes = create_string_buffer(bytes(self.DBPath, 'ascii'))
self.appName = appName
os.environ['PATH'] = self.serverPath + ';' + os.environ['PATH']
self.CmDBEngDll = windll.LoadLibrary(self.serverPath + r'\cmtdbeng.dll')
self.status = c_int()
def InitDbEngDll(self):
self.CmDBEngDll.CmtInitDbEngDll(self.appName, self.DBPath_bytes, byref(self.status))
def InsUpdRec(self, record):
flag = 1
tbd = 0
self.CmDBEngDll.CmtInsUpdRec(create_string_buffer(bytes(self.appName, "ascii")),
record.tableID,
record.dataBuff,
record.mapBuff,
flag, tbd,
record.recIDBuffSize,
record.errCodesBuffSize,
record.errMsgBuffSize,
record.recIDBuff,
record.errCodesBuff,
record.errMsgBuff,
byref(self.status))
def TerminateDbEngDll(self):
self.CmDBEngDll.CmtTerminateDbEngDll()
if __name__ == '__main__':
# db.status should be 1 if library initialized properly
db = CRMDB()
db.InitDbEngDll()
# Add an account to the database
dataStr = "'Bart De Hantsetters','Hantsetters'"
mapStr = "'\n,\nFLDCRDFULLNAME\nFLDCRDCONTACT"
rec = CRMRecord(tableID = CRMEntity["Account"],
dataBuff = dataStr,
mapBuff = mapStr)
# db.status should be 1 if operation was successful
db.InsUpdRec(rec)
print("Insert status: ", db.status)
print("RecID: ", rec.getRecID())
# Update the existing record
dataStr = "'De Hantsetters','" + rec.getRecID() + "'"
mapStr = "'\n,\nFLDCRDLASTNAME\nFLDCRDRECID"
rec = CRMRecord(tableID = CRMEntity["Account"],
dataBuff = dataStr,
mapBuff = mapStr)
db.InsUpdRec(rec)
print("Update status: ", db.status)
db.TerminateDbEngDll()
Python Sample 2
For all field description see the API Reference Manual.
Contributed by: Ilja Christensen
import clr
from System import String, Char, Int32
CRMLib = clr.AddReference(R'\\RangerMSP\ThirdParty\UserDev\CRMLib.dll')
import CRM
MSP = CRM.Application
MSPConfig = CRM.Config()
MSPConfig.AppName = "CRMAgent"
MSPConfig.DllFolder = R"\\RangerMSP\ThirdParty\UserDev"
MSPConfig.DbFolder = R"\\RangerMSP\Db"
MSP.Initialize(MSPConfig)
print(f"Database initialized: {MSP.instance().initialized_}")
# Search account by name, the list has to be initialized before using it.
accountlist=[]
accountSearch = CRM.ObjectQuery[CRM.Account]()
accountSearch.AddCriteria(CRM.Account.Fields.FileAs, CRM.OperatorEnum.opEqual, 'ACME Cool Company')
accountlist=accountSearch.FetchObjects()
# Display results
print (f"Number of accounts: {len(accountlist)}")
for x in range(len(accountlist)):
print (f"Found REC_ID: {accountlist[x].AccountREC_ID}")
# If we find exactly one record then we update it (otherwise a new record is created)
if (len(accountlist) == 1):
account = CRM.Account(accountlist[0].AccountREC_ID)
else:
account = CRM.Account()
account.FileAs = "ACME Cool Company"
account.Dear = "Mr."
account.Contact = "Johnny Doe"
account.Save()
RecID = account.AccountREC_ID
print (f"Updated: {RecID}")
# Close Database connection
MSP.Terminate()
print(f"Database initialized: {MSP.instance().initialized_}")
XML samples
Following are samples for adding a new Ticket and a new Charge to the RangerMSP database using XML formatted messages.
Make sure to go over the Email Connector setup guide, and perform the XML API setup steps prior to testing the XML API.
Also please read RangerMSP API Reference Manual before going through the samples, as it provides an overview of the RangerMSP API work-flow and how it should be used.
Notes on API by Email Activation:
- Error Handling - Should the system fail to perform the XML transaction, an error message will be sent to the email address specified in the XML.
- Using a Password - If you wish to use a verification password for the XML transactions, define the password using the ServerConfig.exe utility. To do so, go to the XML tab, enable the API by Email option and set a password (as specified in the XML - see General XML Tokens). Make sure to set the same Password in ServerConfig and in the XML email itself.
You can read more about the ServerConfig and how to setup the API by Email configuration in the RangerMSP Email Connector Setup guide.
General XML Tokens
The sample and table demonstrates general parameters which should be used for any XML transaction.
For all field description see the API Reference Manual.
<?xml version="1.0" ?> <?crmxml version = "1.0" ?> <crmTransaction> <ExternalApplicationName>N-Able</ExternalApplicationName> <SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail> <Password>the-predefined-api-password</Password> <ReturnTransactionID>data from external application (will be returned as-is in the response) </ReturnTransactionID> <DataKind>TICKET</DataKind> <RecordData> ... the transaction goes here ... </RecordData> </crmTransaction>
| Token | Comment |
|---|---|
| <?xml version="1.0" ?> | The XML version - Always 1.0 |
| <?crmxml version ="1.0" ?> | The RangerMSP API XML version - Always 1.0 |
| <crmTransaction> | Start and end transactions with this token (may have more than one in a single email) |
| <ExternalApplicationName> | The sender application name, can contain any text |
| <SendResponseToEmail> | When set with an email address, then a response email will be sent after processing this transaction by the Email Connector |
| <Password> | Optional Password - Only emails with a password that matches the password set in the Email Connector Settings will be processed (to prevent SPAM email from being processed and added to your RangerMSP database). |
| <DataKind> | What is the Entity you wish to create/update. Possible values: |
Adding new Ticket
In this sample, we add a new Ticket, and set some additional fields to it, such as Notes, Source, Due Date and Dispatcher flag.
<?xml version="1.0" ?>
<?crmxml version = "1.0" ?>
<crmTransaction>
<ExternalApplicationName>N-Able</ExternalApplicationName>
<SendResponseToEmail>youremail@yourdomain.com</SendResponseToEmail>
<Password>the-predefined-api-password</Password>
<ReturnTransactionID>data from external application (will be returned as-is in the response)
</ReturnTransactionID>
<DataKind>TICKET</DataKind>
<RecordData>
<FLDTKTCARDID> CUSTOMER-RECORD-ID-GOES-HERE-20-CHARS </FLDTKTCARDID>
<FLDTKTPROBLEM>ticket description...</FLDTKTPROBLEM>
<FLDTKTSTATUS>100</FLDTKTSTATUS>
<FLDTKTKIND>General</FLDTKTKIND>
<FLDTKTNOTES>Notes</FLDTKTNOTES>
<FLDTKTSOURCE>Source</FLDTKTSOURCE>
<FLDTKTSCHEDLENESTIM>60</FLDTKTSCHEDLENESTIM>
<FLDTKTDUEDATETIME>02/04/08</FLDTKTDUEDATETIME>
<FLDTKTFORDISPATCH>Y</FLDTKTFORDISPATCH>
</RecordData>
</crmTransaction>
Adding new Charges
<?xml version="1.0" ?>
<?crmxml version = "1.0" ?>
<crmTransaction>
<ExternalApplicationName>Alert</ExternalApplicationName>
<SendResponseToEmail>your email address for responses</SendResponseToEmail>
<Password>12345</Password> >> Should be the same in the ServerConfig!
<ReturnTransactionID>data from external application (will be returned as-is in the response)
</ReturnTransactionID>
<DataKind>CHARGE</DataKind>
<RecordData>
<FLDSLPWORKERID> CRDLS71RGU747TLHTFOR </FLDSLPWORKERID>
<FLDSLPCARDID> CRDLQXDL43BP5YCMSGM3</FLDSLPCARDID>
<FLDSLPITEMID> ITM1Q3GUI05ANBQGVY8D </FLDSLPITEMID>
<FLDSLPDESC> Charge Description... </FLDSLPDESC>
<FLDSLPQUANTITY> 10 </FLDSLPQUANTITY>
<FLDSLPSLIPDATE> 31/01/2008 </FLDSLPSLIPDATE>
<FLDSLPSTARTTIME> 12:06 </FLDSLPSTARTTIME>
<FLDSLPENDTIME> 14:50 </FLDSLPENDTIME>
<FLDSLPBCRECID> BCTMA51KBA925J7G0V67 </FLDSLPBCRECID>
<FLDSLPPRICE> 125.3 </FLDSLPPRICE>
<FLDSLPADJUSTAMOUNT> 10 </FLDSLPADJUSTAMOUNT>
<FLDSLPUSER1> Field 1... </FLDSLPUSER1>
</RecordData>
</crmTransaction>
Receiving Response
When adding or updating data via the XML API, the system can send a response (if the XML transaction specifies this in the SendResponseToEmail token). The format of the XML response is as follow:
Response in case of success:
<?xml version="1.0" ?> <?crmxml version="1.0" ?> <crmResponse> <Status>SUCCESS</Status> <AffectedRecId>TKTN1NIQEYYQ8PBJMDAX</AffectedRecId> <ReturnTransactionID>data from external application (as-is)</ReturnTransactionID> </crmResponse>
Response in case of error:
<?xml version="1.0" ?>
<?crmxml version="1.0" ?>
<crmResponse>
<Status>FAILURE</Status>
<AffectedRecId></AffectedRecId>
<ReturnTransactionID>data from external application (as-is)</ReturnTransactionID>
<ResultCodes>50109</ResultCodes>
<ResultMessage>
Fields with illegal values: Operation canceled. Field: Account has invalid data -
TKTN1NIQEYYQ8PBJMDAX
</ResultMessage>
</crmResponse>
| Token | Comment |
|---|---|
| <?xml version="1.0" ?> | The XML version - Always 1.0 |
| <?crmxml version ="1.0" ?> | The RangerMSP API XML version - Always 1.0 |
| <crmResponse> | The response starts and ends with this token |
| <Status> | The transaction status. Possible values: FAILURE, SUCCESS |
| <SendResponseToEmail> | When set with an email address, then a response email will be sent after processing this transaction by the Email Connector |
| <AffectedRecId> | The REC ID of the entity which was added or updated when processing the transaction. |
| <ResultCodes> <ResultMessage> |
In case of a failure, this will contain the error code and description. You can find more information about error codes here. |