batch rest call in sharepoint online - javascript

I am trying to understand how the batch rest calls work.
I could not find any simple example on the internet. I have found the examples from https://github.com/andrewconnell/sp-o365-rest but can't run these examples or I have no idea how yet. I am guessing you have to deploy the app to a sharepoint site.
Given that, I am just looking for the simplest example of a add list item and update list item in bulk/batch. Also if anyone knows how I can make the app from that git to run will be really appreciated.
Thanks.

The github project is a add-in project so you need deploy the add-in project, then you can use it.
You could check below script from here.
My test result in this thread
(function () {
jQuery(document).ready(function () {
jQuery("#btnFetchEmployees").click(function () {
addEmployees();
});
});
})();
function addEmployees() {
var employeesAsJson = undefined;
employeesAsJson = [
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetanjali',
LastName: 'Arora',
Technology: 'SharePoint'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Geetika',
LastName: 'Arora',
Technology: 'Graphics'
},
{
__metadata: {
type: 'SP.Data.EmployeeInfoListItem'
},
Title: 'Ashish',
LastName: 'Brajesh',
Technology: 'Oracle'
}
];
addEmployeeInfoBatchRequest(employeesAsJson);
}
function generateUUID() {
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = (d + Math.random() * 16) % 16 | 0;
d = Math.floor(d / 16);
return (c == 'x' ? r : (r & 0x7 | 0x8)).toString(16);
});
return uuid;
};
function addEmployeeInfoBatchRequest(employeesAsJson) {
// generate a batch boundary
var batchGuid = generateUUID();
// creating the body
var batchContents = new Array();
var changeSetId = generateUUID();
// get current host
var temp = document.createElement('a');
temp.href = _spPageContextInfo.webAbsoluteUrl;
var host = temp.hostname;
// iterate through each employee
for (var employeeIndex = 0; employeeIndex < employeesAsJson.length; employeeIndex++) {
var employee = employeesAsJson[employeeIndex];
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items';
// create the changeset
batchContents.push('--changeset_' + changeSetId);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('POST ' + endpoint + ' HTTP/1.1');
batchContents.push('Content-Type: application/json;odata=verbose');
batchContents.push('');
batchContents.push(JSON.stringify(employee));
batchContents.push('');
}
// END changeset to create data
batchContents.push('--changeset_' + changeSetId + '--');
// batch body
var batchBody = batchContents.join('\r\n');
batchContents = new Array();
// create batch for creating items
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: multipart/mixed; boundary="changeset_' + changeSetId + '"');
batchContents.push('Content-Length: ' + batchBody.length);
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push(batchBody);
batchContents.push('');
// create request in batch to get all items after all are created
endpoint = _spPageContextInfo.webAbsoluteUrl
+ '/_api/web/lists/getbytitle(\'EmployeeInfo\')'
+ '/items?$orderby=Title';
batchContents.push('--batch_' + batchGuid);
batchContents.push('Content-Type: application/http');
batchContents.push('Content-Transfer-Encoding: binary');
batchContents.push('');
batchContents.push('GET ' + endpoint + ' HTTP/1.1');
batchContents.push('Accept: application/json;odata=verbose');
batchContents.push('');
batchContents.push('--batch_' + batchGuid + '--');
batchBody = batchContents.join('\r\n');
// create the request endpoint
var endpoint = _spPageContextInfo.webAbsoluteUrl + '/_api/$batch';
var batchRequestHeader = {
'X-RequestDigest': jQuery("#__REQUESTDIGEST").val(),
'Content-Type': 'multipart/mixed; boundary="batch_' + batchGuid + '"'
};
// create request
jQuery.ajax({
url: endpoint,
type: 'POST',
headers: batchRequestHeader,
data: batchBody,
success: function (response) {
var responseInLines = response.split('\n');
$("#tHead").append("<tr><th>First Name</th><th>Last Name</th><th>Technology</th></tr>");
for (var currentLine = 0; currentLine < responseInLines.length; currentLine++) {
try {
var tryParseJson = JSON.parse(responseInLines[currentLine]);
$.each(tryParseJson.d.results, function (index, item) {
$("#tBody").append("<tr><td>" + item.Title + "</td><td>" + item.LastName + "</td><td>" + item.Technology + "</td></tr>");
});
} catch (e) {
}
}
},
fail: function (error) {
}
});
}

Related

change API data depending on if statment

I'm trying to fetch data through API , and the URL contains two object and I targeted the quizzes , "quizzes": [2 items], "warnings": []
quizzes return me two objects with their details.
what I'm trying to achieve is to add if statement to retrieve the grades (another API) depends on quiz name and it is working well , but I want to add inside it another if to retrieve grades depends on the another quiz name, please see the code below how to target posttest inside pretest they have the same key and I want the data to be changed depends on quiz name.
var get_quiz = {
"url": "MyURL"
};
$.ajax(get_quiz).done(function (get_quiz_res) {
var reslength = Object.keys(get_quiz_res).length;
for (let b = 0; b < reslength; b++) {
var get_grade = {
"url": "*******&quizid="+get_quiz_res.quizzes[b].id"
};
$.ajax(get_grade).done(function (get_grade_res) {
var posttest=''
if (get_quiz_res.quizzes[b].name === "Post Test"){
posttest = get_grade_res.grade;
}
if (get_quiz_res.quizzes[b].name === "Pre Test"){
var row = $('<tr><td>' + userincourseres[i].fullname + '</td><td>' + get_grade_res.grade + '</td><td>' + posttest + '</td><td>');
$('#myTable').append(row);
}
});
}
});
the userincourseres[i].fullname from another api and it is working.
You can use async/await with $ajax if your JQuery version is 3+.
const get_quiz = {
url: "MyURL",
};
(async function run() {
const get_quiz_res = await $.ajax(get_quiz);
const reslength = Object.keys(get_quiz_res).length;
for (let b = 0; b < reslength; b++) {
const get_grade = {
url: "*******&quizid=" + get_quiz_res.quizzes[b].id,
};
let posttest = "";
const get_grade_res = await $.ajax(get_grade);
if (get_quiz_res.quizzes[b].name === "Post Test") {
posttest = get_grade_res.grade;
}
if (get_quiz_res.quizzes[b].name === "Pre Test") {
var row = $(
"<tr><td>" +
userincourseres[i].fullname +
"</td><td>" +
get_grade_res.grade +
"</td><td>" +
posttest +
"</td><td>"
);
$("#myTable").append(row);
}
}
})();

ServiceNow - Change a file name in Midserver

I am currently trying to replace the name of a file in the Mid Server after a scheduled export.
The idea here is that the file goes with the name in the format "file_name_datetime" and the customer needs "datetime_file_name" for the file to be correctly read by another system.
My main idea was to rename the file after the export to the correct format, but if there is a way of changing the file name to the required one I could do that also.
I would love to hear from you guys as I have no idea how can I do this.
Thanks in advance.
If anyone is interested in the answer, see below:
Script include:
initialize: function() {
this.filePath = gs.getProperty('directory_path');
this.midServer = gs.getProperty('midserver');
this.authMidServerBase64 = gs.getProperty('authmidserver');
},
nameChange: function(exportSetName) {
var exportGr = new GlideRecord("sys_export_set_run");
exportGr.addEncodedQuery("set.nameSTARTSWITH" + exportSetName);
exportGr.orderByDesc("completed");
exportGr.query();
if (exportGr.next()) {
var attachSysID = exportGr.ecc_agent_attachment.sys_id;
}
var attachGr = new GlideRecord("sys_attachment");
attachGr.addEncodedQuery("table_sys_idSTARTSWITH" + attachSysID);
attachGr.query();
if (attachGr.next()) {
var attachName = attachGr.file_name;
var attachDate = attachName.match((/\d+/));
var newName = attachDate + '_' + exportSetName + '.csv';
}
var jspr = new JavascriptProbe(this.midServer);
jspr.setName('FileNameChange'); // This can be any name
jspr.setJavascript('var ddr = new MidServer_script_include(); res = ddr.execute();');
jspr.addParameter("verbose", "true");
jspr.addParameter("skip_sensor", "true"); // prevent Discovery sensors running for the ECC input
jspr.addParameter("filename", this.filePath + "\\" + attachName);
jspr.addParameter("filePath", this.filePath);
jspr.addParameter("newName", this.filePath + "\\" + newName);
jspr.addParameter("operation", "rename");
return jspr.create();
},
Mid Server Script include:
initialize: function() {
/**
*** Set up the Packages references
**/
this.File = Packages.java.io.File;
this.FileOutputStream = Packages.java.io.FileOutputStream;
this.FileInputStream = Packages.java.io.FileInputStream;
this.Path = Packages.java.nio.file.Path;
this.Paths = Packages.java.nio.file.Paths;
this.Files = Packages.java.nio.file.Files;
this.StandardCopyOption = Packages.java.nio.file.StandardCopyOption;
/**
/* Set up the parameters
**/
this.verbose = probe.getParameter("verbose");
this.filePath = probe.getParameter("filePath");
this.filename = probe.getParameter("filename");
this.operation = probe.getParameter("operation");
this.newName = probe.getParameter("newName");
result = "initialize complete";
},
execute: function() {
if (this.operation == 'rename') {
this.fileRename(this.filename, this.newName);
}
return result;
},
fileRename: function(fileName, newName) {
result+= "\r\n Renaming file.";
this._debug(result);
try {
var res = this._moveFile(fileName, newName);
} catch (e) {
result += "\r\n Erro no renomeamento do ficheiro: " + e;
this._debug(result);
}
},
_moveFile: function(initialPath, targetPath) {
try {
this._debug("Initiating file move function");
var inPath = this.Paths.get(initialPath);
var tgPath = this.Paths.get(targetPath);
var res = this.Files.move(inPath, tgPath, this.StandardCopyOption.REPLACE_EXISTING);
result += "File successfully moved from: " + initialPath + " to: " + targetPath + " \r\n Result: " + res;
this._debug(result);
} catch (e) {
this._debug('Error:' + e);
}
},
_debug: function(m) {
if (this.verbose == "true") {
ms.log("::: Mid Server script include logger ::: " + m);
}
},
https://community.servicenow.com/community?id=community_question&sys_id=a56b38a6db326490fa192183ca961987

How can I use the Eclipse Paho JavaScript Client to connect to test.mosquitto.org?

I am new to the IOT world and have been confused why I have not been able to use the Eclipse Paho JavaScript Client to connect to test.mosquitto.org.
I have used Port: 8080 and Path: /mqtt as has been suggested in other paho-mqtt questions, but am met with a Failed to connect: AMQJS0007E Socket error:undefined when using this Eclipse web client.
I have used the HiveMQ WebClient and have been able to connect, publish and subscribe to both test.mosquitto.org (Port 8080) and iot.eclipse.org (Port 443).
I have noticed that HiveMQ sources mqttws31.js compared to Paho Eclipse's paho-mqtt.js, but am unsure of the significance.
I would say there are two parts to this question:
What am I missing to get the Eclipse Paho JavaScript Client to connect to test.mosquitto.org ?
What is the difference between mqttws31.js and paho-mqtt.js that allows one to connect to test.mosquitto.org relatively painlessly compared to the other?
Thanks !
Relevant Code:
The code below is taken directly from the page source of https://www.eclipse.org/paho/clients/js/utility/
paho-mqtt.js: https://www.eclipse.org/paho/js/paho-mqtt.js
utility.js (handles button callbacks):
/*******************************************************************************
* Copyright (c) 2015 IBM Corp.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* James Sutton - Initial Contribution
*******************************************************************************/
/*
Eclipse Paho MQTT-JS Utility
This utility can be used to test the Eclipse Paho MQTT Javascript client.
*/
// Create a client instance
var client = null;
var connected = false;
logMessage("INFO", "Starting Eclipse Paho JavaScript Utility.");
// Things to do as soon as the page loads
document.getElementById("clientIdInput").value = "js-utility-" + makeid();
// called when the client connects
function onConnect(context) {
// Once a connection has been made, make a subscription and send a message.
var connectionString = context.invocationContext.host + ":" + context.invocationContext.port + context.invocationContext.path;
logMessage("INFO", "Connection Success ", "[URI: ", connectionString, ", ID: ", context.invocationContext.clientId, "]");
var statusSpan = document.getElementById("connectionStatus");
statusSpan.innerHTML = "Connected to: " + connectionString + " as " + context.invocationContext.clientId;
connected = true;
setFormEnabledState(true);
}
function onConnected(reconnect, uri) {
// Once a connection has been made, make a subscription and send a message.
logMessage("INFO", "Client Has now connected: [Reconnected: ", reconnect, ", URI: ", uri, "]");
connected = true;
}
function onFail(context) {
logMessage("ERROR", "Failed to connect. [Error Message: ", context.errorMessage, "]");
var statusSpan = document.getElementById("connectionStatus");
statusSpan.innerHTML = "Failed to connect: " + context.errorMessage;
connected = false;
setFormEnabledState(false);
}
// called when the client loses its connection
function onConnectionLost(responseObject) {
if (responseObject.errorCode !== 0) {
logMessage("INFO", "Connection Lost. [Error Message: ", responseObject.errorMessage, "]");
}
connected = false;
}
// called when a message arrives
function onMessageArrived(message) {
logMessage("INFO", "Message Recieved: [Topic: ", message.destinationName, ", Payload: ", message.payloadString, ", QoS: ", message.qos, ", Retained: ", message.retained, ", Duplicate: ", message.duplicate, "]");
var messageTime = new Date().toISOString();
// Insert into History Table
var table = document.getElementById("incomingMessageTable").getElementsByTagName("tbody")[0];
var row = table.insertRow(0);
row.insertCell(0).innerHTML = message.destinationName;
row.insertCell(1).innerHTML = safeTagsRegex(message.payloadString);
row.insertCell(2).innerHTML = messageTime;
row.insertCell(3).innerHTML = message.qos;
if (!document.getElementById(message.destinationName)) {
var lastMessageTable = document.getElementById("lastMessageTable").getElementsByTagName("tbody")[0];
var newlastMessageRow = lastMessageTable.insertRow(0);
newlastMessageRow.id = message.destinationName;
newlastMessageRow.insertCell(0).innerHTML = message.destinationName;
newlastMessageRow.insertCell(1).innerHTML = safeTagsRegex(message.payloadString);
newlastMessageRow.insertCell(2).innerHTML = messageTime;
newlastMessageRow.insertCell(3).innerHTML = message.qos;
} else {
// Update Last Message Table
var lastMessageRow = document.getElementById(message.destinationName);
lastMessageRow.id = message.destinationName;
lastMessageRow.cells[0].innerHTML = message.destinationName;
lastMessageRow.cells[1].innerHTML = safeTagsRegex(message.payloadString);
lastMessageRow.cells[2].innerHTML = messageTime;
lastMessageRow.cells[3].innerHTML = message.qos;
}
}
function connectionToggle() {
if (connected) {
disconnect();
} else {
connect();
}
}
function connect() {
var hostname = document.getElementById("hostInput").value;
var port = document.getElementById("portInput").value;
var clientId = document.getElementById("clientIdInput").value;
var path = document.getElementById("pathInput").value;
var user = document.getElementById("userInput").value;
var pass = document.getElementById("passInput").value;
var keepAlive = Number(document.getElementById("keepAliveInput").value);
var timeout = Number(document.getElementById("timeoutInput").value);
var tls = document.getElementById("tlsInput").checked;
var automaticReconnect = document.getElementById("automaticReconnectInput").checked;
var cleanSession = document.getElementById("cleanSessionInput").checked;
var lastWillTopic = document.getElementById("lwtInput").value;
var lastWillQos = Number(document.getElementById("lwQosInput").value);
var lastWillRetain = document.getElementById("lwRetainInput").checked;
var lastWillMessageVal = document.getElementById("lwMInput").value;
if (path.length > 0) {
client = new Paho.Client(hostname, Number(port), path, clientId);
} else {
client = new Paho.Client(hostname, Number(port), clientId);
}
logMessage("INFO", "Connecting to Server: [Host: ", hostname, ", Port: ", port, ", Path: ", client.path, ", ID: ", clientId, "]");
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
client.onConnected = onConnected;
var options = {
invocationContext: { host: hostname, port: port, path: client.path, clientId: clientId },
timeout: timeout,
keepAliveInterval: keepAlive,
cleanSession: cleanSession,
useSSL: tls,
reconnect: automaticReconnect,
onSuccess: onConnect,
onFailure: onFail
};
if (user.length > 0) {
options.userName = user;
}
if (pass.length > 0) {
options.password = pass;
}
if (lastWillTopic.length > 0) {
var lastWillMessage = new Paho.Message(lastWillMessageVal);
lastWillMessage.destinationName = lastWillTopic;
lastWillMessage.qos = lastWillQos;
lastWillMessage.retained = lastWillRetain;
options.willMessage = lastWillMessage;
}
// connect the client
client.connect(options);
var statusSpan = document.getElementById("connectionStatus");
statusSpan.innerHTML = "Connecting...";
}
function disconnect() {
logMessage("INFO", "Disconnecting from Server.");
client.disconnect();
var statusSpan = document.getElementById("connectionStatus");
statusSpan.innerHTML = "Connection - Disconnected.";
connected = false;
setFormEnabledState(false);
}
// Sets various form controls to either enabled or disabled
function setFormEnabledState(enabled) {
// Connection Panel Elements
if (enabled) {
document.getElementById("clientConnectButton").innerHTML = "Disconnect";
} else {
document.getElementById("clientConnectButton").innerHTML = "Connect";
}
document.getElementById("hostInput").disabled = enabled;
document.getElementById("portInput").disabled = enabled;
document.getElementById("clientIdInput").disabled = enabled;
document.getElementById("pathInput").disabled = enabled;
document.getElementById("userInput").disabled = enabled;
document.getElementById("passInput").disabled = enabled;
document.getElementById("keepAliveInput").disabled = enabled;
document.getElementById("timeoutInput").disabled = enabled;
document.getElementById("tlsInput").disabled = enabled;
document.getElementById("automaticReconnectInput").disabled = enabled;
document.getElementById("cleanSessionInput").disabled = enabled;
document.getElementById("lwtInput").disabled = enabled;
document.getElementById("lwQosInput").disabled = enabled;
document.getElementById("lwRetainInput").disabled = enabled;
document.getElementById("lwMInput").disabled = enabled;
// Publish Panel Elements
document.getElementById("publishTopicInput").disabled = !enabled;
document.getElementById("publishQosInput").disabled = !enabled;
document.getElementById("publishMessageInput").disabled = !enabled;
document.getElementById("publishButton").disabled = !enabled;
document.getElementById("publishRetainInput").disabled = !enabled;
// Subscription Panel Elements
document.getElementById("subscribeTopicInput").disabled = !enabled;
document.getElementById("subscribeQosInput").disabled = !enabled;
document.getElementById("subscribeButton").disabled = !enabled;
document.getElementById("unsubscribeButton").disabled = !enabled;
}
function publish() {
var topic = document.getElementById("publishTopicInput").value;
var qos = document.getElementById("publishQosInput").value;
var message = document.getElementById("publishMessageInput").value;
var retain = document.getElementById("publishRetainInput").checked;
logMessage("INFO", "Publishing Message: [Topic: ", topic, ", Payload: ", message, ", QoS: ", qos, ", Retain: ", retain, "]");
message = new Paho.Message(message);
message.destinationName = topic;
message.qos = Number(qos);
message.retained = retain;
client.send(message);
}
function subscribe() {
var topic = document.getElementById("subscribeTopicInput").value;
var qos = document.getElementById("subscribeQosInput").value;
logMessage("INFO", "Subscribing to: [Topic: ", topic, ", QoS: ", qos, "]");
client.subscribe(topic, { qos: Number(qos) });
}
function unsubscribe() {
var topic = document.getElementById("subscribeTopicInput").value;
logMessage("INFO", "Unsubscribing: [Topic: ", topic, "]");
client.unsubscribe(topic, {
onSuccess: unsubscribeSuccess,
onFailure: unsubscribeFailure,
invocationContext: { topic: topic }
});
}
function unsubscribeSuccess(context) {
logMessage("INFO", "Unsubscribed. [Topic: ", context.invocationContext.topic, "]");
}
function unsubscribeFailure(context) {
logMessage("ERROR", "Failed to unsubscribe. [Topic: ", context.invocationContext.topic, ", Error: ", context.errorMessage, "]");
}
function clearHistory() {
var table = document.getElementById("incomingMessageTable");
//or use : var table = document.all.tableid;
for (var i = table.rows.length - 1; i > 0; i--) {
table.deleteRow(i);
}
}
// Just in case someone sends html
function safeTagsRegex(str) {
return str.replace(/&/g, "&").replace(/</g, "<").
replace(/>/g, ">");
}
function makeid() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 5; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
function logMessage(type, ...content) {
var consolePre = document.getElementById("consolePre");
var date = new Date();
var timeString = date.toUTCString();
var logMessage = timeString + " - " + type + " - " + content.join("");
consolePre.innerHTML += logMessage + "\n";
if (type === "INFO") {
console.info(logMessage);
} else if (type === "ERROR") {
console.error(logMessage);
} else {
console.log(logMessage);
}
}
The code below is taken directly from the page source of http://www.hivemq.com/demos/websocket-client/
mqttws31.js: http://www.hivemq.com/demos/websocket-client/js/mqttws31.js
app.js (handles app callbacks):
/**
* Copyright 2013 dc-square GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* #author: Christoph Schäbel
*/
var websocketclient = {
'client': null,
'lastMessageId': 1,
'lastSubId': 1,
'subscriptions': [],
'messages': [],
'connected': false,
'connect': function () {
var host = $('#urlInput').val();
var port = parseInt($('#portInput').val(), 10);
var clientId = $('#clientIdInput').val();
var username = $('#userInput').val();
var password = $('#pwInput').val();
var keepAlive = parseInt($('#keepAliveInput').val());
var cleanSession = $('#cleanSessionInput').is(':checked');
var lwTopic = $('#lwTopicInput').val();
var lwQos = parseInt($('#lwQosInput').val());
var lwRetain = $('#LWRInput').is(':checked');
var lwMessage = $('#LWMInput').val();
var ssl = $('#sslInput').is(':checked');
this.client = new Messaging.Client(host, port, clientId);
this.client.onConnectionLost = this.onConnectionLost;
this.client.onMessageArrived = this.onMessageArrived;
var options = {
timeout: 3,
keepAliveInterval: keepAlive,
cleanSession: cleanSession,
useSSL: ssl,
onSuccess: this.onConnect,
onFailure: this.onFail
};
if (username.length > 0) {
options.userName = username;
}
if (password.length > 0) {
options.password = password;
}
if (lwTopic.length > 0) {
var willmsg = new Messaging.Message(lwMessage);
willmsg.qos = lwQos;
willmsg.destinationName = lwTopic;
willmsg.retained = lwRetain;
options.willMessage = willmsg;
}
this.client.connect(options);
},
'onConnect': function () {
websocketclient.connected = true;
console.log("connected");
var body = $('body').addClass('connected').removeClass('notconnected').removeClass('connectionbroke');
websocketclient.render.hide('conni');
websocketclient.render.show('publish');
websocketclient.render.show('sub');
websocketclient.render.show('messages');
},
'onFail': function (message) {
websocketclient.connected = false;
console.log("error: " + message.errorMessage);
websocketclient.render.showError('Connect failed: ' + message.errorMessage);
},
'onConnectionLost': function (responseObject) {
websocketclient.connected = false;
if (responseObject.errorCode !== 0) {
console.log("onConnectionLost:" + responseObject.errorMessage);
}
$('body.connected').removeClass('connected').addClass('notconnected').addClass('connectionbroke');
websocketclient.render.show('conni');
websocketclient.render.hide('publish');
websocketclient.render.hide('sub');
websocketclient.render.hide('messages');
//Cleanup messages
websocketclient.messages = [];
websocketclient.render.clearMessages();
//Cleanup subscriptions
websocketclient.subscriptions = [];
websocketclient.render.clearSubscriptions();
},
'onMessageArrived': function (message) {
// console.log("onMessageArrived:" + message.payloadString + " qos: " + message.qos);
var subscription = websocketclient.getSubscriptionForTopic(message.destinationName);
var messageObj = {
'topic': message.destinationName,
'retained': message.retained,
'qos': message.qos,
'payload': message.payloadString,
'timestamp': moment(),
'subscriptionId': subscription.id,
'color': websocketclient.getColorForSubscription(subscription.id)
};
console.log(messageObj);
messageObj.id = websocketclient.render.message(messageObj);
websocketclient.messages.push(messageObj);
},
'disconnect': function () {
this.client.disconnect();
},
'publish': function (topic, payload, qos, retain) {
if (!websocketclient.connected) {
websocketclient.render.showError("Not connected");
return false;
}
var message = new Messaging.Message(payload);
message.destinationName = topic;
message.qos = qos;
message.retained = retain;
this.client.send(message);
},
'subscribe': function (topic, qosNr, color) {
if (!websocketclient.connected) {
websocketclient.render.showError("Not connected");
return false;
}
if (topic.length < 1) {
websocketclient.render.showError("Topic cannot be empty");
return false;
}
if (_.find(this.subscriptions, { 'topic': topic })) {
websocketclient.render.showError('You are already subscribed to this topic');
return false;
}
this.client.subscribe(topic, {qos: qosNr});
if (color.length < 1) {
color = '999999';
}
var subscription = {'topic': topic, 'qos': qosNr, 'color': color};
subscription.id = websocketclient.render.subscription(subscription);
this.subscriptions.push(subscription);
return true;
},
'unsubscribe': function (id) {
var subs = _.find(websocketclient.subscriptions, {'id': id});
this.client.unsubscribe(subs.topic);
websocketclient.subscriptions = _.filter(websocketclient.subscriptions, function (item) {
return item.id != id;
});
websocketclient.render.removeSubscriptionsMessages(id);
},
'deleteSubscription': function (id) {
var elem = $("#sub" + id);
if (confirm('Are you sure ?')) {
elem.remove();
this.unsubscribe(id);
}
},
'getRandomColor': function () {
var r = (Math.round(Math.random() * 255)).toString(16);
var g = (Math.round(Math.random() * 255)).toString(16);
var b = (Math.round(Math.random() * 255)).toString(16);
return r + g + b;
},
'getSubscriptionForTopic': function (topic) {
var i;
for (i = 0; i < this.subscriptions.length; i++) {
if (this.compareTopics(topic, this.subscriptions[i].topic)) {
return this.subscriptions[i];
}
}
return false;
},
'getColorForPublishTopic': function (topic) {
var id = this.getSubscriptionForTopic(topic);
return this.getColorForSubscription(id);
},
'getColorForSubscription': function (id) {
try {
if (!id) {
return '99999';
}
var sub = _.find(this.subscriptions, { 'id': id });
if (!sub) {
return '999999';
} else {
return sub.color;
}
} catch (e) {
return '999999';
}
},
'compareTopics': function (topic, subTopic) {
var pattern = subTopic.replace("+", "(.*?)").replace("#", "(.*)");
var regex = new RegExp("^" + pattern + "$");
return regex.test(topic);
},
'render': {
'showError': function (message) {
alert(message);
},
'messages': function () {
websocketclient.render.clearMessages();
_.forEach(websocketclient.messages, function (message) {
message.id = websocketclient.render.message(message);
});
},
'message': function (message) {
var largest = websocketclient.lastMessageId++;
var html = '<li class="messLine id="' + largest + '">' +
' <div class="row large-12 mess' + largest + '" style="border-left: solid 10px #' + message.color + '; ">' +
' <div class="large-12 columns messageText">' +
' <div class="large-3 columns date">' + message.timestamp.format("YYYY-MM-DD HH:mm:ss") + '</div>' +
' <div class="large-5 columns topicM truncate" id="topicM' + largest + '" title="' + Encoder.htmlEncode(message.topic, 0) + '">Topic: ' + Encoder.htmlEncode(message.topic) + '</div>' +
' <div class="large-2 columns qos">Qos: ' + message.qos + '</div>' +
' <div class="large-2 columns retain">';
if (message.retained) {
html += 'Retained';
}
html += ' </div>' +
' <div class="large-12 columns message break-words">' + Encoder.htmlEncode(message.payload) + '</div>' +
' </div>' +
' </div>' +
'</li>';
$("#messEdit").prepend(html);
return largest;
},
'subscriptions': function () {
websocketclient.render.clearSubscriptions();
_.forEach(websocketclient.subscriptions, function (subs) {
subs.id = websocketclient.render.subscription(subs);
});
},
'subscription': function (subscription) {
var largest = websocketclient.lastSubId++;
$("#innerEdit").append(
'<li class="subLine" id="sub' + largest + '">' +
' <div class="row large-12 subs' + largest + '" style="border-left: solid 10px #' + subscription.color + '; background-color: #ffffff">' +
' <div class="large-12 columns subText">' +
' <div class="large-1 columns right closer">' +
' x' +
' </div>' +
' <div class="qos">Qos: ' + subscription.qos + '</div>' +
' <div class="topic truncate" id="topic' + largest + '" title="' + Encoder.htmlEncode(subscription.topic, 0) + '">' + Encoder.htmlEncode(subscription.topic) + '</div>' +
' </div>' +
' </div>' +
'</li>');
return largest;
},
'toggleAll': function () {
websocketclient.render.toggle('conni');
websocketclient.render.toggle('publish');
websocketclient.render.toggle('messages');
websocketclient.render.toggle('sub');
},
'toggle': function (name) {
$('.' + name + 'Arrow').toggleClass("closed");
$('.' + name + 'Top').toggleClass("closed");
var elem = $('#' + name + 'Main');
elem.slideToggle();
},
'hide': function (name) {
$('.' + name + 'Arrow').addClass("closed");
$('.' + name + 'Top').addClass("closed");
var elem = $('#' + name + 'Main');
elem.slideUp();
},
'show': function (name) {
$('.' + name + 'Arrow').removeClass("closed");
$('.' + name + 'Top').removeClass("closed");
var elem = $('#' + name + 'Main');
elem.slideDown();
},
'removeSubscriptionsMessages': function (id) {
websocketclient.messages = _.filter(websocketclient.messages, function (item) {
return item.subscriptionId != id;
});
websocketclient.render.messages();
},
'clearMessages': function () {
$("#messEdit").empty();
},
'clearSubscriptions': function () {
$("#innerEdit").empty();
}
}
};
I think I am a bit late...but I leave here for posterity.
The Paho JS library has undergo a series of changes before release 1.0.3 and the last one 1.1.0.
If you refer to a mqttws31.js probably you was using a version earlier than 1.0.3, because from 1.0.3 the main js file was renamed to paho-mqtt.js.
Can be the reason why something in your code was working differently from HiveMQ version.
I tried to sum the situation here

Can't scrobble tracks (batch) to Last.fm API. Invalid method signature

I've been trying this for a while now, but I can't get my head around what's wrong. Maybe I've tried so many ways that I'm not even sure this piece of code is right anymore.
Basically I'm trying to use the track.scrobble method from the Last.fm API, sending a batch of tracks.
That's the code I have, and it's always returning Invalid method signature. Does anyone can give me some help here, please?
UPDATE
Based on mccannf answer, I've changed the code, but am still getting the error:
var apiUrl = "http://ws.audioscrobbler.com/2.0/";
var apiMethod = "track.scrobble";
var apiKey = "MY_API_KEY";
var apiSecret = "MY_API_SECRET";
var key = "MY_SESSION_KEY";
var apiSig = "";
var lastfmScrobble = function (data) {
var dataToScrobble = setTiming(data);
var albums = [];
var artists = [];;
var timestamps = [];
var tracks = [];
var dataToHash = "";
for (var i = 0; i < dataToScrobble.tracks.length; i++) {
albums["album["+ i.toString() + "]"] = dataToScrobble.album;
artists["artist[" + i.toString() + "]"] = dataToScrobble.artist;
timestamps["timestamp[" + i.toString() + "]"] = dataToScrobble.tracks[i].split("|")[1];
tracks["track[" + i.toString() + "]"] = dataToScrobble.tracks[i].split("|")[0];
}
dataToHash += albums.sort().join("");
dataToHash += "api_key" + apiKey;
dataToHash += artists.sort().join("");
dataToHash += "method" + apiMethod;
dataToHash += "sk" + key;
dataToHash += timestamps.sort().join("");
dataToHash += tracks.sort().join("");
dataToHash += apiSecret;
apiSig = $.md5(unescape(encodeURIComponent(dataToHash)));
var songsToScrobble = {};
$.extend(songsToScrobble,
albums.sort(),
{ api_key: apiKey },
{ api_sig: apiSig },
artists.sort(),
{ method: apiMethod },
{ sk: key },
timestamps.sort(),
tracks.sort());
$.ajax({
url: apiUrl,
type: "POST",
data: songsToScrobble,
success: function (data) {
console.log(data);
}
});
}
Now the object sent has the correct format (JSON). What can still be wrong?
I did a quick sample JS Fiddle of your code.
The dataToHash is like this:
album[0]Achtung Babyalbum[1]Achtung Babyapi_keyxxxBLAHxxxartist[0]U2artist[1]U2methodtrack.scrobbleskkkkFOOkkktimestamp[0]1379368800timestamp[1]1379369000track[0]Onetrack[1]The FlymmmySecrettt
The songsToScrobble variable in the code above looked like this:
{ "album": [
"album[0]Achtung Baby",
"album[1]Achtung Baby"
],
"api_key":"xxxBLAHxxx",
"api_sig":"8dbc147e533411a41ba9169f59e65b3a",
"artist":["artist[0]U2","artist[1]U2"],
"method": "track.scrobble",
"sk":"kkkFOOkkk"
"timestamp": [
"timestamp[0]1379368800",
"timestamp[1]1379369000"
],
"track": [
"track[0]One",
"track[1]The Fly"
]
}
I believe songsToScrobble should look like this:
{ "album[0]": "Achtung Baby",
"album[1]": "Achtung Baby",
"api_key":"xxxBLAHxxx",
"api_sig":"8dbc147e533411a41ba9169f59e65b3a",
"artist[0]": "U2",
"artist[1]": "U2",
"method": "track.scrobble",
"sk":"kkkFOOkkk"
"timestamp[0]": "1379368800",
"timestamp[1]": "1379369000",
"track[0]": "One",
"track[1]": "The Fly"
}
Only other minor point is to make sure dataToHash is UTF-8 encoded before you convert to MD5 hash.
Edit
This is how I created the data for the ajax call. NOTE: this is untested - I don't have a last.fm account.
var songsToScrobble = {};
function addDataToScrobble(parentElement, inputData) {
if ($.isArray(inputData)) {
$.each(inputData, function(index ,element) {
songsToScrobble[parentElement + "[" + index + "]"] = element;
dataToHash += parentElement + "[" + index + "]" + element;
});
} else {
songsToScrobble[parentElement] = inputData;
dataToHash += parentElement + inputData;
}
}
for (var i = 0; i < data.tracks.length; i++) {
albums.push(data.album);
artists.push(data.artist);
// The tracks are coming in the format: title|timestamp
timestamps.push(data.tracks[i].split("|")[1]);
tracks.push(data.tracks[i].split("|")[0]);
}
addDataToScrobble("album", albums);
addDataToScrobble("api_key", apiKey);
addDataToScrobble("artist", artists);
addDataToScrobble("method", apiMethod);
addDataToScrobble("sk", key);
addDataToScrobble("timestamp", timestamps);
addDataToScrobble("track", tracks);
apiSig = $.md5(unescape(encodeURIComponent(dataToHash+apiSecret)));
songsToScrobble["api_sig"] = apiSig;
$.ajax({
url: apiUrl,
type: "POST",
data: songsToScrobble,
success: function (data) {
console.log(data);
}
});

Merging JSON api Response using Javascript

I am trying get paged json responses from Topsy (http://code.google.com/p/otterapi/) and am having problems merging the objects. I want to do this in browser as the api rate limit is per ip/user and to low to do things server side.
Here is my code. Is there a better way? Of course there is because this doesn't work. I guess I want to get this working, but also to understand if there is a safer, and/or more efficient way.
The error message I get is ...
TypeError: Result of expression 'window.holdtweetslist.prototype' [undefined] is not an object.
Thanks in advance.
Cheers
Stephen
$("#gettweets").live('click', function(event){
event.preventDefault();
getTweets('stephenbaugh');
});
function getTweets(name) {
var MAX_TWEETS = 500;
var TWEETSPERPAGE = 50;
var BASE = 'http://otter.topsy.com/search.json?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + name + '&page=1';
var currentpage = 1;
alert(BASE);
$.ajax({
dataType: "json",
url: BASE,
success: function(data) {
window.responcesreceived = 1;
var response=data.response;
alert(response.total);
window.totalweets = response.total;
window.pagestoget = Math.ceil(window.totalweets/window.TWEETSPERPAGE);
window.holdtweetslist = response.list;
window.holdtweetslist.prototype.Merge = (function (ob) {var o = this;var i = 0;for (var z in ob) {if (ob.hasOwnProperty(z)) {o[z] = ob[z];}}return o;});
// alert(data);
;; gotTweets(data);
var loopcounter = 1;
do
{
currentpage = currentpage + 1;
pausecomp(1500);
var BASE = 'http://otter.topsy.com/search.json?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + name + '&page=' + currentpage;
alert(BASE);
$.ajax({dataType: "json", url: BASE, success: gotTweets(data)});
}
while (currentpage<pagestoget);
}
});
};
function gotTweets(data)
{
window.responcesreceived = window.responcesreceived + 1;
var response = data.response;
alert(response.total);
window.holdtweetslist.Merge(response.list);
window.tweetsfound = window.tweetsfound + response.total;
if (window.responcesreceived == window.pagestoget) {
// sendforprocessingsendtweetlist();
alert(window.tweetsfound);
}
}
You are calling Merge as an static method, but declared it as an "instance" method (for the prototype reserved word).
Remove prototype from Merge declaration, so you'll have:
window.holdtweetslist.Merge = (function(ob)...
This will fix the javascript error.
This is Vipul from Topsy. Would you share the literal JSON you are receiving? I want to ensure you are not receiving a broken response.
THanks to Edgar and Vipul for there help. Unfortunately they were able to answer my questions. I have managed to work out that the issue was a combination of jquery not parsing the json properly and needing to use jsonp with topsy.
Here is a little test I created that works.
Create a doc with this object on it ....
RUN TEST
You will need JQUERY
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
And put the following in a script too. The is cycle through the required number of tweets from Topsy.
Thanks again everyone.
$("#gettweets").live('click', function(event){
event.preventDefault();
getTweets('stephenbaugh');
});
var MAX_TWEETS = 500;
var TWEETSPERPAGE = 50;
var BASE = 'http://otter.topsy.com/search.json';
var currentpage;
var responcesreceived;
var totalweets;
var pagestoget;
var totalweets;
var TWEETSPERPAGE;
var holdtweetslist = [];
var requestssent;
var responcesreceived;
var tweetsfound;
var nametoget;
function getTweets(name) {
nametoget=name;
currentpage = 1;
responcesreceived = 0;
pagestoget = 0;
var BASE = 'http://otter.topsy.com/search.js?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + nametoget + '&page=1';
$('#gettweets').html(BASE);
$.ajax({url: BASE,
dataType: 'jsonp',
success : function(data) {
getalltweets(data);
}
});
};
function getalltweets(data) {
totalweets = data.response.total;
$('#gettweets').append('<p>'+"total tweets " + totalweets+'</p>');
$('#gettweets').append('<p>'+"max tweets " + MAX_TWEETS+'</p>');
if (MAX_TWEETS < totalweets) {
totalweets = 500
}
$('#gettweets').append('<p>'+"new total tweets " + totalweets+'</p>');
gotTweets(data);
pagestoget = Math.ceil(totalweets/TWEETSPERPAGE);
var getpagesint = self.setInterval(function() {
currentpage = ++currentpage;
var BASE = 'http://otter.topsy.com/search.js?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + nametoget + '&page=' + currentpage;
$.ajax({url: BASE,
dataType: 'jsonp',
success : function(data) {
gotTweets(data);
}
});
if (currentpage == pagestoget) {
$('#gettweets').append('<p>'+"finished sending " + currentpage+ ' of ' + pagestoget + '</p>');
clearInterval(getpagesint);
};
}, 2000);
};
function gotTweets(data)
{
responcesreceived = responcesreceived + 1;
holdlist = data.response.list;
for (x in holdlist)
{
holdtweetslist.push(holdlist[x]);
}
// var family = parents.concat(children);
$('#gettweets').append('<p>receipt # ' + responcesreceived+' - is page : ' +data.response.page+ ' array length = ' + holdtweetslist.length +'</p>');
// holdtweetslist.Merge(response.list);
tweetsfound = tweetsfound + data.response.total;
if (responcesreceived == pagestoget) {
// sendforprocessingsendtweetlist();
$('#gettweets').append('<p>'+"finished receiving " + responcesreceived + ' of ' + pagestoget + '</p>');
}
}

Categories

Resources