How to send a message when a trello card is moved to a certain list - api

I’m currently making a bot that informs me when a card is moved to the list titled Passed Applications.
I have already made the code and it basically sends a message once a card is moved to the specific list, however, it will randomly send a message and pull a card minutes/hours after it has already been pulled and sent the message.
What I’ve done so far is:
trello.js
var Trello = require("node-trello"),
EventEmitter = require("events").EventEmitter,
extend = require("extend"),
config,
trello,
timer,
e;
module.exports = function(options) {
var defaults = {
pollFrequency: 1000 * 60,
minId: 0,
trello: {
key: "",
token: "",
boards: []
},
start: true
};
e = new EventEmitter();
config = extend(true, defaults, options);
trello = new Trello(
process.env.TRELLO_API_KEY,
process.env.TRELLO_OAUTH_TOKEN
);
if (config.start) {
process.nextTick(function() {
start(config.pollFrequency, true);
});
}
function start(frequency, immediate) {
if (timer) {
return;
}
frequency = frequency || config.pollFrequency;
timer = setInterval(poll, frequency);
if (immediate) {
poll();
}
}
function poll() {
config.trello.boards.forEach(function(boardId) {
getBoardActivity(boardId);
});
}
function getBoardActivity(boardId) {
trello.get("/1/boards/" + boardId + "/actions", function(err, resp) {
if (err) {
return e.emit("trelloError", err);
}
var boardActions = resp.reverse();
var actionId;
for (var ix in boardActions) {
actionId = parseInt(boardActions[ix].id, 16);
if (actionId <= config.minId) {
continue;
}
var eventType = boardActions[ix].type;
e.emit(eventType, boardActions[ix], boardId);
}
config.minId = Math.max(config.minId, actionId);
e.emit("maxId", config.minId);
});
}
index.js
const conf = JSON.parse(fs.readFileSync("trelloconfig.json"));
let latestActivityID = fs.existsSync("./latestActivityID") ?
fs.readFileSync("./latestActivityID") :
0;
const eventEnabled = type =>
conf.enabledEvents.length > 0 ? conf.enabledEvents.includes(type) : true;
const TrelloEvents = require("./trello.js");
const events = new TrelloEvents({
pollFrequency: 60000,
minId: latestActivityID,
start: false,
trello: {
boards: conf.boardIDs,
key: process.env.TRELLO_API_KEY,
token: process.env.TRELLO_OAUTH_TOKEN
}
});
client.on("ready", () => {
events.start();
console.log(`[STATUS CHANGE] ${client.user.username} is now online.`);
client.user.setActivity("Cookout Grill");
});
events.on("updateCard", (event, board) => {
if (event.data.old.hasOwnProperty("idList")) {
if (!eventEnabled(`cardListChanged`)) return;
if (event.data.listAfter.name === "Passed Applications") {
let robloxId = event.data.card.name.split(" | ")[0];
client.channels.get("730839109236424756").send(robloxId);
if (database.find(x => x.RobloxUser === robloxId)) {
let data = database.find(x => x.RobloxUser === robloxId);
const person = client.users.get(data.DiscordID);
let embed = new discord.RichEmbed()
.setThumbnail(
"https://www.roblox.com/bust-thumbnail/image?userId=" +
data.RobloxID +
"&width=420&height=420&format=png"
)
.setTitle("APPLICATION RESULTS | Passed")
.setColor("3ef72d")
.setFooter("Cookout Grill", client.user.avatarURL)
.setDescription(
"Greetings, **" +
data.RobloxUser +
"**!\n\nAfter extensive review by our Management Team, we have decided to accept your Trainee Application at Cookout Grill. We believe that your application showed that you’re ready to become a staff member at our establishment.\n\nWe would like to congratulate you on passing your Trainee Application. Your application met our critical expectations and requirements in order to pass.\n\nIn order to work your way up throughout the staff ranks, you must attend a training at [Cookout Grill’s Training Center](https://www.roblox.com/groups/5634772/Cookout-Grill#!/about) during the specific session times. If you’re unable to attend one of our designated sessions, feel free to schedule a private session with a member of our Management Team.\n\nWe wish you the best of luck in continuing throughout the staff ranks at Cookout Grill. If you have any further questions, please do not hesitate to create a ticket in our main Discord Server."
)
.addField("**NEW RANK**", "`Trainee`");
person.send(embed);
roblox.message(
event.data.card.name.split(" | ")[1],
"APPLICATION RESULTS | Passed",
"Greetings, **" +
data.RobloxUser +
"**!\n\nAfter extensive review by our Management Team, we have decided to accept your Trainee Application at Cookout Grill.\n\nWe would like to congratulate you on passing your Trainee Application. Your application met our critical expectations and requirements in order to pass.\n\nIn order to work your way up throughout the staff ranks, you must attend a training at Cookout Grill’s Training Center during the specific session times. If you’re unable to attend one of our designated sessions, feel free to schedule a private session with a member of our Management Team.\n\nWe wish you the best of luck in continuing throughout the staff ranks at Cookout Grill."
);
}
let embed2 = new discord.RichEmbed()
.setTitle(`Card list changed!`)
.setDescription(
`**CARD:** ${
event.data.card.name
} — **[CARD LINK](https://trello.com/c/${
event.data.card.shortLink
})**\n\n**EVENT:** Card moved to list __${
event.data.listAfter.name
}__ from list __${event.data.listBefore.name}__ by **[${
conf.realNames
? event.memberCreator.fullName
: event.memberCreator.username
}](https://trello.com/${event.memberCreator.username})**`
);
client.channels.get("730839109236424756").send(embed2);
Trello.addCommentToCard(
event.data.card.id,
"User has been ranked.",
function(error, trelloCard) {
console.log(error);
}
);
} else return;
} else return;
});

Related

Get all transactions for an NFT on Solana

I want to collect all transactions for an NFT.
For example, you can display all transactions here:
https://explorer.solana.com/address/2Nzt8TYeAfgJDftKzkb7rgYShVvyXTR7cPVvpqaZ2a4V
or here:
https://solscan.io/token/2Nzt8TYeAfgJDftKzkb7rgYShVvyXTR7cPVvpqaZ2a4V#txs
But is there any way to do this with the API?
I checked
solana-py: https://michaelhly.github.io/solana-py/
and solscan api: https://public-api.solscan.io/docs/
But I could not find a way to do it.
You can use the getSignaturesForAddress RPC method on the mint address and walk backward to get all the transactions.
Here is an example in JS:
import {
Connection,
clusterApiUrl,
ConfirmedSignatureInfo,
PublicKey,
} from "#solana/web3.js";
const connection = new Connection(clusterApiUrl("mainnet-beta"));
export const getTxs = async (connection: Connection, pubkey: PublicKey) => {
const txs: ConfirmedSignatureInfo[] = [];
// Walk backward
let lastTransactions = await connection.getConfirmedSignaturesForAddress2(
pubkey
);
let before = lastTransactions[lastTransactions.length - 1].signature;
txs.push(...lastTransactions);
while (true) {
const newTransactions = await connection.getConfirmedSignaturesForAddress2(
pubkey,
{
before,
}
);
if (newTransactions.length === 0) break;
txs.push(...newTransactions);
before = newTransactions[newTransactions.length - 1].signature;
}
return txs;
};
getTxs(
connection,
new PublicKey("2Nzt8TYeAfgJDftKzkb7rgYShVvyXTR7cPVvpqaZ2a4V")
);
The equivalent method in Solana.py is this one https://michaelhly.github.io/solana-py/rpc/api/#solana.rpc.api.Client.get_signatures_for_address

How to fix InvalidStateError: Cannot add ICE candidate when there is no remote SDP

I am creating a webRTC video chat that shows a caller all active members when initiating a call from firefox and the receiver is using chrome this error is displayed "Uncaught (in promise) DOMException: Failed to execute 'addIceCandidate' on 'RTCPeerConnection': Error processing ICE candidate". And when a call is initiated from firefox and receiver uses firefox I get two errors Invalidstate: cannot add ICE candidate when there is no remote SDP and ICE failed, add a STUN and see about:webrtc for details
I dont know where I am making a mistake
/ define all data here
var usersOnline,id,currentCaller,room,caller,localUser,media,memberInfo;
// All subscribed members.
var users = [];
var token = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
// create random user id
var userId = Math.random().toString(36).substring(2, 15);
// create random username
var username = token;
// authonticating user
var currentUser = {
username: token,
userId: userId
}
// stringify user data
currentUser = JSON.stringify(currentUser);
var pusher = new Pusher('KEY', {
authEndpoint: '../auth.php',
auth: {
params: JSON.parse(currentUser)
},
cluster: 'ap2',
forceTLS: true
});
var state = pusher.connection.state;
var channel = pusher.subscribe('presence-conference');
channel.bind("pusher:subscription_succeeded", function (members) {
console.log(members);
id = channel.members.me.id;
document.getElementById('mydetails').innerHTML = 'Online Now: ' + ' ( ' + (members.count - 1) +')';
members.each(member => {
if (member.id != channel.members.me.id) {
users.push(member.id);
}
});
renderOnline();
});
// Add user online
channel.bind("pusher:member_added", member => {
users.push(member.id);
renderOnline();
});
channel.bind("pusher:member_removed", member => {
// for remove member from list:
var index = users.indexOf(member.id);
users.splice(index, 1);
if (member.id == room) {
endCall();
}
renderOnline();
});
function renderOnline(){
var list = "";
users.forEach(function(user) {
list +=
`<li>` +
user +//this will call user
` <input type="button" style="float:right;" value="Call" onclick="callUser('` +
user +
`')" id="makeCall" /></li>`;
});
document.getElementById("userDetails").innerHTML = list;
}
//To iron over browser implementation anomalies like prefixes
GetRTCPeerConnection();
GetRTCSessionDescription();
GetRTCIceCandidate();
prepareCaller();
function prepareCaller() {
//Initializing a peer connection
caller = new window.RTCPeerConnection();
//Listen for ICE Candidates and send them to remote peers
caller.onicecandidate = function(evt) {
if (!evt.candidate) return;
console.log("onicecandidate called");
onIceCandidate(caller, evt);
};
//onaddstream handler to receive remote feed and show in remoteview video element
caller.onaddstream = function(evt) {
console.log("onaddstream called");
if("srcObject" in document.getElementById("selfview")){
document.getElementById("selfview").srcObject = evt.stream;
}else{
if (window.URL) {
document.getElementById("remoteview").src = window.URL.createObjectURL(
evt.stream
);
} else {
document.getElementById("remoteview").src = evt.stream;
}
}
};
}
function getCam() {
//Get local audio/video feed and show it in selfview video element
return navigator.mediaDevices.getUserMedia({
audio: {
echoCancellation: true,
sampleSize:8
},
video: {
width: 1080,
height: 720,
aspectRatio: { ideal: 1.777778 }
}
});
}
function GetRTCIceCandidate() {
window.RTCIceCandidate =
window.RTCIceCandidate ||
window.webkitRTCIceCandidate ||
window.mozRTCIceCandidate ||
window.msRTCIceCandidate;
return window.RTCIceCandidate;
}
function GetRTCPeerConnection() {
window.RTCPeerConnection =
window.RTCPeerConnection ||
window.webkitRTCPeerConnection ||
window.mozRTCPeerConnection ||
window.msRTCPeerConnection;
return window.RTCPeerConnection;
}
function GetRTCSessionDescription() {
window.RTCSessionDescription =
window.RTCSessionDescription ||
window.webkitRTCSessionDescription ||
window.mozRTCSessionDescription ||
window.msRTCSessionDescription;
return window.RTCSessionDescription;
}
//Create and send offer to remote peer on button click
function callUser(user) {
getCam()
.then(stream => {
if("srcObject" in document.getElementById("selfview")){
document.getElementById("selfview").srcObject = stream;
}else{
if (window.URL) {
document.getElementById("selfview").src = window.URL.createObjectURL(
stream
);
} else {
document.getElementById("selfview").src = stream;
}
}
toggleEndCallButton();
caller.addStream(stream);
localUserMedia = stream;
caller.createOffer().then(function(desc) {
caller.setLocalDescription(new RTCSessionDescription(desc));
channel.trigger("client-sdp", {
sdp: desc,
room: user,
from: id
});
room = user;
});
})
.catch(error => {
console.log("an error occured", error);
});
}
function endCall() {
room = undefined;
caller.close();
for (let track of localUserMedia.getTracks()) {
track.stop();
}
prepareCaller();
toggleEndCallButton();
}
function endCurrentCall() {
channel.trigger("client-endcall", {
room: room
});
endCall();
}
//Send the ICE Candidate to the remote peer
function onIceCandidate(peer, evt) {
if (evt.candidate) {
channel.trigger("client-candidate", {
candidate: evt.candidate,
room: room
});
}
}
function toggleEndCallButton() {
if (document.getElementById("endCall").style.display == "block") {
document.getElementById("endCall").style.display = "none";
} else {
document.getElementById("endCall").style.display = "block";
}
}
//Listening for the candidate message from a peer sent from onicecandidate handler
channel.bind("client-candidate", function(msg) {
if (msg.room == room) {
console.log("candidate received");
caller.addIceCandidate(new RTCIceCandidate(msg.candidate));
}
});
//Listening for Session Description Protocol message with session details from remote peer
channel.bind("client-sdp", function(msg) {
if (msg.room == id) {
console.log("sdp received");
var answer = confirm(
"You have a call from: " + msg.from + "Would you like to answer?"
);
if (!answer) {
return channel.trigger("client-reject", { room: msg.room, rejected: id });
}
room = msg.room;
getCam()
.then(stream => {
localUserMedia = stream;
toggleEndCallButton();
if("srcObject" in document.getElementById("selfview")){
document.getElementById("selfview").srcObject = stream;
}else{
if (window.URL) {
document.getElementById("selfview").src = window.URL.createObjectURL(
stream
);
} else {
document.getElementById("selfview").src = stream;
}
}
caller.addStream(stream);
var sessionDesc = new RTCSessionDescription(msg.sdp);
caller.setRemoteDescription(sessionDesc);
caller.createAnswer().then(function(sdp) {
caller.setLocalDescription(new RTCSessionDescription(sdp));
channel.trigger("client-answer", {
sdp: sdp,
room: room
});
});
})
.catch(error => {
console.log("an error occured", error);
});
}
});
//Listening for answer to offer sent to remote peer
channel.bind("client-answer", function(answer) {
if (answer.room == room) {
console.log("answer received");
caller.setRemoteDescription(new RTCSessionDescription(answer.sdp));
}
});
channel.bind("client-reject", function(answer) {
if (answer.room == room) {
console.log("Call declined");
alert("call to " + answer.rejected + "was politely declined");
endCall();
}
});
channel.bind("client-endcall", function(answer) {
if (answer.room == room) {
console.log("Call Ended");
endCall();
}
});
I EXPECTED that the video call will work don't want to use any API, help me see where I went wrong.
Call setRemoteDescription(offer) before requesting the camera.
This puts the RTCPeerConnection in the right signaling state ("have-remote-offer") to receive and process remote ICE candidates correctly.
There's no time to request the camera first when an offer comes in. Incoming offers are typically followed closely by trickled ICE candidates on your signaling channel. addIceCandidate won't know what to do with those if it hasn't seen an offer.
Move the setRemoteDescription call ahead of the getMedia call in the promise chain to fix it. You have more time then before returning an answer.
Though that's still not great, since this approach often ends up blocking initial WebRTC negotiation on a user permission prompt for the camera. This is called tight coupling. Sadly, the current state of WebRTC encourages it, since getting the best IP mode is gated on getUserMedia in most browsers.
Lastly, there's a lot of old API usage here. See my other answer for newer APIs to use.

How to make a flag counter with react-native-beacons-manager

Scenario
Our app aims to detect beacons placed inside the restaurants our app
uses react-native-beacons-manager
When our app detects a beacon, I have developed a cloud function that accepts the beacon's major key and use it to query data of that restaurant from my database
The Cloud function then sends a push notification on the user about the restaurant details.
The Problem
The way I detect the beacons is not stable. this is my flow. I created a function located at
this.beaconsDidRangeEvent = Beacons.BeaconsEventEmitter.addListener(
//function-here
);
I can receive the beacons information like uuid, major and minor key and proximity (immediate, near, far, unknown) . Now inside that function I use the major key to determine the individuality of each beacons. Now, I've made a condition like this:
let beaconArr = data.beacons;
console.log(beaconArr);
console.log(count);
if (beaconArr.length > 0) {
console.log("beacons detected!");
let major = data.beacons[0].major;
let prox = data.beacons[0].proximity;
if ((prox === "near" || prox === "far") && beaconFlag === false && count === 0) {
console.log("beacon Action");
this.props.beaconAction(major);
this.props.createCheckInHistory(user.uid);
beaconFlag = true;
count++;
} else {
console.log("counter turned to 1!");
console.log(data);
beaconFlag = true;
}
} else {
console.log("no beacons detected!");
count = 0;
beaconFlag = false;
}
Expected Result
I expect that the functions inside the condition is true will only fire once.
Actual Result
Sometimes, its ok sometimes its not. even if im still at the range of the beacon, suddenly the beacon's array got 0. Then suddenly i'll receive a push notification again and again.
componentDidMount() Code
componentDidMount() {
this.props.selectedIcon('map');
firebase
.messaging()
.getInitialNotification()
.then(notification => {
console.log("Notification which opened the app: ", notification);
});
const user = firebase.auth().currentUser;
let count = 0;
let beaconFlag = false;
// will be set as a reference to "regionDidEnter" event:
this.beaconsDidRangeEvent = Beacons.BeaconsEventEmitter.addListener(
"beaconsDidRange",
_.throttle(data => {
let beaconArr = data.beacons;
console.log(beaconArr);
console.log(count);
if (beaconArr.length > 0) {
console.log("beacons detected!");
let major = data.beacons[0].major;
let prox = data.beacons[0].proximity;
if ((prox === "near" || prox === "far") && beaconFlag === false && count === 0) {
console.log("beacon Action");
this.props.beaconAction(major);
this.props.createCheckInHistory(user.uid);
beaconFlag = true;
count++;
} else {
console.log("counter turned to 1!");
console.log(data);
beaconFlag = true;
}
} else {
console.log("no beacons detected!");
count = 0;
beaconFlag = false;
}
}, 3000)
);
// monitoring events
this.regionDidEnterEvent = Beacons.BeaconsEventEmitter.addListener(
"regionDidEnter",
data => {
console.log("monitoring - regionDidEnter data: ", data);
}
);
// Monitoring: Listen for device leaving the defined region
this.regionDidExitEvent = Beacons.BeaconsEventEmitter.addListener(
"regionDidExit",
data => {
console.log("monitoring - regionDidExit data: ", data);
}
);
}
This is a common problem when ranging in beacon apps. Sometimes the detected beacons will briefly drop out then come back again. This can be solved by a software filter where you keep track of all beacons you have recently seen, and only perform an operation of it has not happened recently. In your case, you may use the major as the key to the index into the filter object.
// scope this globally
var minimumRetriggerMillis = 3600 * 1000; // 1hr
var recentTriggers = {};
// Before executing your trigger action:
var now = new Date().getTime();
if (recentTriggers[minor] == null || now-recentTriggers[minor] > minimumRetriggerMillis) {
recentTriggers[minor] = now;
// TODO: execute trigger logic here
}

Unable to record again after stopping record in Kurento

I am working on this Kurento application and there is a strange problem i am facing where once I start recording the video and stop the recording, I cant start another recording again. The event goes to the server but nothing seems to be happening! PFB the code:
room.pipeline.create('WebRtcEndpoint', function (error, outgoingMedia) {
if (error) {
console.error('no participant in room');
// no participants in room yet release pipeline
if (Object.keys(room.participants).length == 0) {
room.pipeline.release();
}
return callback(error);
}
outgoingMedia.setMaxVideoRecvBandwidth(256);
userSession.outgoingMedia = outgoingMedia;
// add ice candidate the get sent before endpoint is established
var iceCandidateQueue = userSession.iceCandidateQueue[socket.id];
if (iceCandidateQueue) {
while (iceCandidateQueue.length) {
var message = iceCandidateQueue.shift();
console.error('user : ' + userSession.id + ' collect candidate for outgoing media');
userSession.outgoingMedia.addIceCandidate(message.candidate);
}
}
userSession.outgoingMedia.on('OnIceCandidate', function (event) {
console.log("generate outgoing candidate : " + userSession.id);
var candidate = kurento.register.complexTypes.IceCandidate(event.candidate);
userSession.sendMessage({
id: 'iceCandidate',
sessionId: userSession.id,
candidate: candidate
});
});
// notify other user that new user is joining
var usersInRoom = room.participants;
var data = {
id: 'newParticipantArrived',
new_user_id: userSession.id,
receiveVid: receiveVid
};
// notify existing user
for (var i in usersInRoom) {
usersInRoom[i].sendMessage(data);
}
var existingUserIds = [];
for (var i in room.participants) {
existingUserIds.push({id: usersInRoom[i].id, receiveVid: usersInRoom[i].receiveVid});
}
// send list of current user in the room to current participant
userSession.sendMessage({
id: 'existingParticipants',
data: existingUserIds,
roomName: room.name,
receiveVid: receiveVid
});
// register user to room
room.participants[userSession.id] = userSession;
var recorderParams = {
mediaProfile: 'WEBM',
uri: "file:///tmp/Room_"+room.name+"_file"+userSession.id +".webm"
};
//make recorder endpoint
room.pipeline.create('RecorderEndpoint', recorderParams, function(error, recorderEndpoint){
userSession.outgoingMedia.recorderEndpoint = recorderEndpoint;
outgoingMedia.connect(recorderEndpoint);
});
On the screen when I click the record button, the function on the server is:
function startRecord(socket) {
console.log("in func");
var userSession = userRegistry.getById(socket.id);
if (!userSession) {
return;
}
var room = rooms[userSession.roomName];
if(!room){
return;
}
var usersInRoom = room.participants;
var data = {
id: 'startRecording'
};
for (var i in usersInRoom) {
console.log("in loop");
var user = usersInRoom[i];
// release viewer from this
user.outgoingMedia.recorderEndpoint.record();
// notify all user in the room
user.sendMessage(data);
console.log(user.id);
}}
The thing is, for the very 1st time, it records properly i.e. file created on server and video&audio recorded properly.
When I press stop to stop recording, the intended effect is seen i.e. recording stops.
NOW, when I press record again, a video file is not made. The event reaches the server properly (console.log says so)
Can anyone help me pls?!
Thanks.

JSON store hangs while retrieving data

We have observed that at certain times accessing the JSONStore API's hangs for long time, to make it work we have to call the function again or app has to be taken to background & bring to foreground again.
NOTE : when application faces this issue, behaviour is same until we reinstall the app or reboot the device.
There doesn't appear to be any proper scenarios for this, we have searched many articles but did not find any solution, any solutions are welcome.
We observed this issue on Android devices like S5 and S4.
Here is my code Snippet:
function getWidgets(w_id, getWidgetsSuccessCallback, getWidgetsFailureCallback) {
var query = { user_id : w_id };
var options = {};
WL.JSONStore.get(StorageCollections.widgets).find(query, options)
.then(function(arrayResults) {
var count = arrayResults.length;
Logger.debug("getWidgets: success, count: " + count);
...
getWidgetsSuccessCallback(widgets);
})
.fail(function(errorObject) {
Logger.error("getWidgets: failed, error: " + JSON.stringify(errorObject));
getWidgetsFailureCallback(errorObject);
});}
Logs when everything works fine http://pastebin.com/NVP8ycTG
Logs when accessing JSON store hangs, it will work only when app taken to background & bring back to foreground again http://pastebin.com/eYzx57qC
JSON store is initialised as below
var collections = {
// User
user: {
searchFields: {
user_id : 'string',
user_name : 'string',
first_name : 'string',
last_name : 'string',
}
}
}};
// Storage encryption
var options = {};
if (key) {
options.password = key;
options.localKeyGen = true;
}
// Open the collection
var promise = WL.JSONStore.init(collections, options)
.then(function() {
Logger.debug("initializeAppStorage: " + JSON.stringify(collections) + " completed");
initAppStorageSuccessCallback(true);
return true;
})
// Handle failure
.fail(function(errorObject) {
Logger.error("initializeAppStorage: failed, error: " + errorObject.toString());
initAppStorageFailureCallback(errorObject.toString());
return false;
});
return promise;
Thanks.
Try this one :
function getWidgets(w_id, getWidgetsSuccessCallback, getWidgetsFailureCallback) {
var query = { key : w_id };
var options = {};
WL.JSONStore.get(StorageCollections.widgets).find(query, options)
.then(function(arrayResults) {
var count = arrayResults.length;
Logger.debug("getWidgets: success, count: " + count);
...
getWidgetsSuccessCallback(widgets);
})
.fail(function(errorObject) {
Logger.error("getWidgets: failed, error: " + JSON.stringify(errorObject));
getWidgetsFailureCallback(errorObject);
});}