How do you delete roles in Parse.com using Cloud Code? I checked: https://parse.com/docs/js/symbols/Parse.Role.html, and it doesn't document any destroy method.
I am creating a role for every group of members, and I'd like to get rid of the role when the group is destroyed. What is the correct way of doing so?
Have you seen:
role.getUsers().remove(user);
This one works for me:
const roles = await new Parse.Query(Parse.Role).find();
await Parse.Object.destroyAll(roles, {useMasterKey: true}};
I played around with this for hours before getting it to work by fluke (no thanks to deficient and incorrect documentation)...
This is architecturally incorrect but the only way I could hack it together was using async function with await + promise... I do not understand Parse's weird mechanics sometimes. It's a love & hate relationship!
// Get user to delete object
let userToDeleteObject = await new Parse.Query(Parse.User)
.equalTo('objectId', userToDelete)
.find({useMasterKey: true});
// Remove user from group role
let roleDeleteQuery = new Parse.Query(Parse.Role);
roleDeleteQuery.contains("name", groupName);
roleDeleteQuery.first({useMasterKey: true})
.then(function(roleObject) {
roleObject.relation("users").remove(userToDeleteObject);
roleObject.save(null, {useMasterKey: true});
});
Related
I have viewed all the articles on here, and haven't done any javascript coding in the past. Hoping someone can help me.
I have a class called rank and of course the parse _User class. I have added a pointer to the _User class to the rank class (the column name is called user_rank, which allows me to give a user a rank - seems simple enough.
What I am trying to achieve, is to use Cloud Code to change a user's rank as the administrator of the app (so it's something I do in my admin app, not the user does in their app).
This is what I have, but all I get is an error 101 'Object not found'. I have no doubt I am doing this all wrong, but I have tried to piece together responses from other posts with no success.
Any help is greatly appreciated.
Updated code with Davi's change below - now throwing error schema mismatch for _User.user_rank; expected Pointer but got String
Parse.Cloud.define("setUserRank", async (request, response) => {
let { userObjectId, rankObjectId } = request.params;
const userQuery = new Parse.Query(Parse.User);
const rankQuery = new Parse.Query('rank');
// Get the user object to change the rank of
try{
let user = await userQuery.get(userObjectId, { useMasterKey: true});
let rank = await rankQuery.get(rankObjectId, { useMasterKey: true});
console.log(user);
console.log("Running");
const rankRelation = user.relation('user_rank');
rankRelation.add(user_rank);
user.save(null, { useMasterKey: true});
return ("User Rank Changed"));
} catch (err) {
throw new Error(err.message)
}
});
I think the problem happens because of this line:
const rankQuery = new Parse.Query(Parse.rank);
In the case of you custom classes, you need to pass the class name as a string:
const rankQuery = new Parse.Query('rank');
After I create my own token program I am thne minting some supply into another tokenaccount.
I notice the mintTo is a void function, is there any easy way to get the associated transaction signature ?
const token = new splToken.Token(
connection,
new web3.PublicKey(token_type.token_address),
splToken.TOKEN_PROGRAM_ID,
mint_authority_wallet
);
const destinationTokenAccount = await token.getOrCreateAssociatedAccountInfo(
new web3.PublicKey(to_public_address)
);
console.log("destinationTokenAccount>>", destinationTokenAccount);
const test = await token.mintTo(
destinationTokenAccount.address,
mint_authority_wallet.publicKey,
[],
100
);
console.log("test>>",test)
The fix for this is quite simple: you just need to return the result from sendAndConfirmTransaction. Check out the source code at https://github.com/solana-labs/solana-program-library/blob/ab05e4e597c0b538d855c18da3850df84ad6a49a/token/js/client/token.js#L1027
You could always hack your version to return the signature. Better yet, PRs are always welcome!
Working on a Teams chatbot (V4/Node) and need to address GDPR.
In short, users of the chatbot need to be able to export or delete their personal data stored by the chatbot. Personal data is any information which is related to an identified or identifiable natural person. So also a user-ID in a state object.
I read a blog about GDPR and bots but this one does not address the Teams channel. And it is about V3
The personal data given by the user in dialogs (written by me) is
the easy part. I will write some dialogs to show and delete them
(like Bill does in his answer).
The content in the actual conversations is part of the Teams platform and will\should be adressed in Teams itself.
The bit I don't know how to address is the data for the bot to actually run (Bot state etc). What if a user needs to delete the fact that he or she participated in a certain conversation. That is probably stored in some state objects (in my case in Blob storage). But which ones?
I would appreciate some ideas\guidance in how to address this.
Disclaimer: I'm not a GDPR expert but I believe the following to be sufficient.
From a bot standpoint the data stored is the same in Teams channel. You have the conversation state and user state data which is typically (and in most of the examples) set up using Blob storage. I use the conversationState and userState nomenclature for these items.
In my use case, I am storing account number in userState and user name/email in conversationState. Note that there are other things that the bot stores (particularly in conversationState I believe) around the state of the dialog and other bot specific things that are rather meaningless generally but I don't know if they would be considered part of GDPR. Regardless we will be wiping these entire objects out.
To do that, I created a dialog to manage the user profile which displays the key information stored (I'm specifically accessing account number, user name, and email) and then prompts the user for if they want to delete the information. It looks like this in nodejs.
const { ConfirmPrompt, ComponentDialog, WaterfallDialog } = require('botbuilder-dialogs');
const { ActivityTypes } = require('botbuilder');
const WATERFALL_DIALOG = 'waterfallDialog';
const CONFIRM_PROMPT = 'confirmPrompt';
class manageProfileDialog extends ComponentDialog {
constructor(dialogId, userDialogStateAccessor, userState, appInsightsClient, dialogState, conversationState) {
super(dialogId);
this.dialogs.add(new ConfirmPrompt(CONFIRM_PROMPT));
this.dialogs.add(new WaterfallDialog(WATERFALL_DIALOG, [
this.showInfoAndPrompt.bind(this),
this.confirmDelete.bind(this)
]));
this.initialDialogId = WATERFALL_DIALOG;
// State accessors
this.userDialogStateAccessor = userDialogStateAccessor;
this.userState = userState;
this.dialogState = dialogState;
this.conversationState = conversationState;
this.appInsightsClient = appInsightsClient;
} // End constructor
async showInfoAndPrompt(step) {
this.appInsightsClient.trackEvent({name:'manageProfileDialog', properties:{instanceId:step._info.values.instanceId, channel: step.context.activity.channelId}});
this.appInsightsClient.trackMetric({name: 'showInfoAndPrompt', value: 1});
const userProfile = await this.userDialogStateAccessor.get(step.context, {});
const conversationData = await this.dialogState.get(step.context, {});
if (!userProfile.accountNumber & !conversationData.userEmail & !conversationData.userFullName & !conversationData.orderType) {
this.appInsightsClient.trackEvent({name:'manageProfileDialogEnd', properties:{instanceId:step._info.values.instanceId, channel: step.context.activity.channelId}});
this.appInsightsClient.trackMetric({name: 'confirmDelete', value: 1});
await step.context.sendActivity(`I don't have any of your information stored.`);
return await step.endDialog();
} else {
var storedData = '';
if (userProfile.accountNumber) {
storedData += ` \n**Account Number:** ${userProfile.accountNumber}`;
}
if (conversationData.userFullName) {
storedData += ` \n**Name:** ${conversationData.userFullName}`;
}
if (conversationData.userEmail) {
storedData += ` \n**Email:** ${conversationData.userEmail}`;
}
if (conversationData.orderType) {
storedData += ` \n**Default order type:** ${conversationData.orderType}`;
}
await step.context.sendActivity(`Here is the informaiton I have stored: \n ${storedData} \n\n I will forget everything except your account number after the end of this conversation.`);
await step.context.sendActivity({ type: ActivityTypes.Typing });
await new Promise(resolve => setTimeout(resolve, process.env.DIALOG_DELAY));
return await step.prompt(CONFIRM_PROMPT, `I can clear your information if you don't want me to store it or if you want to reneter it. Would you like me to clear your information now?`,['Yes','No']);
}
}
async confirmDelete(step) {
this.appInsightsClient.trackEvent({name:'manageProfileDialogEnd', properties:{instanceId:step._info.values.instanceId, channel: step.context.activity.channelId}});
if (step.result) {
const userProfile = await this.userDialogStateAccessor.delete(step.context, {});
const conversationData = await this.dialogState.delete(step.context, {});
await step.context.sendActivity(`OK, I have cleared your information.`);
return await step.endDialog();
} else {
await step.context.sendActivity(`OK, I won't clear your information. You can ask again at any time.`);
this.appInsightsClient.trackMetric({name: 'confirmDelete', value: 1});
return await step.endDialog();
}
}
}
module.exports.ManageProfileDialog = manageProfileDialog;
One thing I am uncertain of regarding GDPR is if you are storing transcripts or activity data elsewhere in the course of running the bot. For example, I am storing conversation transcripts in CosmosDB, which could include things like names and email addresses if they were provided during the course of the conversation. I don't have a good way to clear this information even if I wanted to. Also, I am storing LUIS traces and other information in Application Insights, which in many cases includes the activity which may have things like user name or ID attached. I'm not even sure it would be possible to delete those traces from Application Insights. I do not know if these fall under the realm of GDPR since they are operational, but if that is a potential concern just be careful about what you are storing in your logging and/or transcript applications.
I want to retrieve row count in Supabase.
I am guessing it would be something like this:
const { data, error } = await supabase
.from('cities')
.select('name', 'COUNT(*)')
Is this possible with Supabase?
For future visitors, we are working on this functionality with the PostgREST maintainer:
https://github.com/supabase/postgrest-js/issues/94
(I'm a maintainer)
This is now released:
const { data, count } = supabase
.from('countries')
.select('*', { count: 'exact', head: true })
If you want to return the results simultaneously, remove head:
const { data, count } = supabase
.from('countries')
.select('*', { count: 'exact' })
As a workaround, you could write a standard Postgres stored procedure or function that returns the count then call that via the SB client.
https://supabase.io/docs/client/rpc
It is currently not supported yet, but there is a WIP issue on Github that would bring this feature to Supabase.
The code below has not been implemented in Supabase yet, but it might look something like this:
const { data, error, count } = await supabase
.from('table')
.select('*')
.gt('id', 10)
.count()
Edit 7.19.2021
As kiwicopple has answered, this feature has been added to Supabase with a slightly different form from what I have above. View the accepted answer for more.
I am trying to save the new questions asked by the user to my QnA maker bot into an Azure database so that I can add the answers to those questions to my knowledge base.
Currently, I am asking the users to write their question in a feedback form when they don't get a response from my bot. This is taking make time also the user is annoyed by writing. I want my bot to collect these questions and store it a database.
So, please guide how to achieve this, any links or suggestions appreciated.
I was able to achieve something similar using a SharePoint list.
https://stackoverflow.com/a/56612401/9611859
If you want to add a no answer to a SharePoint List, I managed to get it working using the csom-node package and Bot Framework v4 / NodeJS. Granted, it's not the most elegant solution, but it works.
Bot.JS
const csomapi = require('../node_modules/csom-node');
settings = require('../settings').settings;
// Set CSOM settings
csomapi.setLoaderOptions({url: settings.siteurl});
Bit further down the page...
// If no answers were returned from QnA Maker, reply with help.
} else {
await context.sendActivity("Er sorry, I don't seem to have an answer.");
console.log(context.activity.text);
var response = context.activity.text;
var authCtx = new AuthenticationContext(settings.siteurl);
authCtx.acquireTokenForApp(settings.clientId, settings.clientSecret, function (err, data) {
var ctx = new SP.ClientContext("/sites/yoursite"); //set root web
authCtx.setAuthenticationCookie(ctx); //authenticate
var web = ctx.get_web();
var list = web.get_lists().getByTitle('YourList');
var creationInfo = new SP.ListItemCreationInformation();
var listItem = list.addItem(creationInfo);
listItem.set_item('Title', response);
listItem.update();
ctx.load(listItem);
ctx.executeQueryAsync();
});
}