Avatar

Is it possible to create a record to a kintone app from outside of kintone?

Afief

Dear Developers

What I mean is, if for example you create a localhost javascript application, and from that javascript application you want to submit a record to a kintone app you have access to, although I know it can be provided by using API-TOKEN, but I still having doubt about the proper way to do it. Probably using something like kintone proxy, or I don't know.

Please help, any answer would be appreciated, thank you!

Follow 5 followers
1

5 comments

Avatar
Austin Do 2 votes

Afief,

You want to post a record from a non-Kintone domain to a Kintone one, correct? In this case, kintone.api() may not work as your JavaScript file will not be attached to your app. I would recommend using either Microsoft Azure or AWS Lambda to make a function app, then triggering that from your frontend script. I tried this out myself using an HTTPTrigger function with Azure. Here's code for the function app:

And you can just trigger the function with jQuery.get() or AngularJS $http from your JavaScript Application.

Hope this helped, and let me know if you have any follow-up questions.

 

2
Comment actions Permalink
Avatar
Junko Werner 0 votes

As Yuzo mentioned, when you want to add records from outside Kintone, you use the POST method.
However, JS samples in the website referred by Yuzo use kintone.api, so that the kintone.api cannot be used in environments outside Kintone.
Also, Curl cannot be used from JS.

Therefore, if you are running the Kintone API from an external JS,
you will need to use like XMLHttpRequest and jQuery.ajax to run the API.

Here is a sample coding to add a record using XMLHttpRequest.

var body = { 
"app": 1,
"record": {
"Text": {
"value": "ABC"
}
},
// CSRF TOKEN: It is necessary to set it when API (POST, PUT, DELETE) is executed from kintone.
"__REQUEST_TOKEN__": kintone.getRequestToken()
};


var url = 'https://{subdomain}.kintone.com/k/v1/record.json';
var xhr = new XMLHttpRequest();
xhr.open('POST', url);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
if (xhr.status === 200) {
// success
console.log(JSON.parse(xhr.responseText));
} else {
// error
console.log(JSON.parse(xhr.responseText));
}
};
xhr.send(JSON.stringify(body));

I found the following HTML sample using jQuery.ajax but for GET method.

(function() {
$.ajax({
type: 'GET',
url: 'https://subdomain.kintone.com/k/v1/records.json?app=appID',
success: function(data) {
console.log(data);
}
});
})();
0
Comment actions Permalink
Avatar
Austin Do 3 votes

Junko's answer is good for posting a record from one Kintone app to another (for example, kintone.getRequestToken() from the first snippet won’t work unless the JavaScript file is attached to a Kintone app), but both AJAX and XMLHttpRequest follow the same-origin policy (https://developer.mozilla.org/en-US/docs/Web/Security/Same-origin_policy) and ordinarily don't allow cross-domain requests -- this can be bypassed with Azure or AWS Lambda, which run code from the server side. Here is a tutorial on getting record data using Azure: https://developer.kintone.io/hc/en-us/articles/115008801168

3
Comment actions Permalink
Avatar
Dave Gilpin 2 votes

I had a heck of a time finding an example that worked for me, so here are a few I figured out.  Obviously, you need to replace the subDomain, apiToken, appId, and field details with your app info.  

 

VBA macro (Excel, Work, etc.):

Public Sub test()
    Dim myRecord1, myRecord2, myRecord3, response1, response2, subDomain, apiToken, appId
    Dim myData As New Collection

   'change these for your app/environment
    subDomain = "YourSubdomain"
    apiToken = "YourApiToken"
    appId = YourAppID

    Set myRecord1 = CreateObject("Scripting.Dictionary")
    myRecord1("NumberFieldCode") = 1
    myRecord1("TextFieldCode") = "text"

    Set myRecord2 = CreateObject("Scripting.Dictionary")
    myRecord2("NumberFieldCode") = 2
    myRecord2("TextFieldCode") = "more text"

    Set myRecord3 = CreateObject("Scripting.Dictionary")
    myRecord3("NumberFieldCode") = 3
    myRecord3("TextFieldCode") = "even more text"

    'first test sending one record as dictionary
    response1 = addKintoneRecords(subDomain, apiToken, appId, myRecord1)

    'next test sending multiple dictionary objects in a collection
    myData.Add myRecord2
    myData.Add myRecord3
    response2 = addKintoneRecords(subDomain, apiToken, appId, myData)

    'show results
    MsgBox response1 & Chr(10) & response2
End Sub

Public Function addKintoneRecords(ByVal subDomain As String, ByVal apiToken As String, ByVal appId As Integer, ByVal data)
    'use at your own risk. no warranty expressed or implied
    'initial 3/12/2020 Dave Gilpin

    Dim recordString, jsonString, recType, fieldType, rec, fieldCode, objRequest
    jsonString = ""

    For Each rec In data
        recordString = ""
        recType = VarType(rec)
        If recType <> 9 Then 'if the record type is not object set rec to data
            Set rec = data
        End If
        For Each fieldCode In rec
            fieldType = VarType(rec(fieldCode))

            If recordString <> "" Then recordString = recordString & "," 'more than one field
            recordString = recordString & """" & fieldCode & """:{""value"":" 'add field name
            If fieldType = 8 Then recordString = recordString & """" 'string so add quotes
            recordString = recordString & rec(fieldCode) 'add value
            If fieldType = 8 Then recordString = recordString & """" 'string so add quotes
            recordString = recordString & "}" 'close json record object
        Next
        If jsonString <> "" Then jsonString = jsonString & "," 'more than one record
        jsonString = jsonString & "{" & recordString & "}" 'add the recordString to the jsonString
        If recType = 8 Then Exit For 'if the record type is not object don't keep looping
    Next
    jsonString = "{""app"":" & appId & ",""records"":[" & jsonString & "]}" 'put it all together

    Set objRequest = CreateObject("MSXML2.XMLHTTP")
    With objRequest
        .Open "POST", "https://" & subDomain & ".kintone.com/k/v1/records.json", True
        .setRequestHeader "X-Cybozu-API-Token", apiToken
        .setRequestHeader "Content-Type", "application/json"
        .Send jsonString 'send to kintone
        While objRequest.readyState <> 4 'wait for response
            DoEvents
        Wend
        addKintoneRecords = .ResponseText 'return response
    End With
End Function



Javascript in local file: I didn’t put as much effort into this one, since I figure it might not be as useful.  You have to run it from IE, since Chrome can be strict.  

<html>
<head>
<script type="text/javascript">
function test() {
var subDomain = "YourSubdomain";
var apiToken = "YourApiToken";
var appId = YourAppID;

json = {
"app": appId, "records": [
{
"NumberFieldCode": { "value": 1 }, "TextFieldCode": { "value": "some test data" }
},
{
"NumberFieldCode": { "value": 2 }, "TextFieldCode": { "value": "some more test data" }
}
]
};
var req = new XMLHttpRequest();
req.addEventListener("load", requestResponse);
req.open("POST", "https://" + subDomain + ".kintone.com/k/v1/records.json", true);
req.setRequestHeader("X-Cybozu-API-Token", apiToken);
req.setRequestHeader("Content-Type", "application/json");
req.send(JSON.stringify(json));
}

function requestResponse() {
document.getElementById("response").innerText = this.responseText;
}
</script>
</head>
<body>
<input type="button" onclick="test();" value="test" />
<textarea id="response" cols="100" rows="20"> </textarea>
</body>
</html>

2
Comment actions Permalink