Get Discord user current game AND custom status? - discord.js

Currently, using Discord.js, member.user.presence.game.name will return the game name IF said user doesn't have a custom status set, but if they do, this returns "Custom Status". Not their actual status, or their game name, just... "Custom status". I'd like to be able to return the game name and custom status both independently if they are set. Currently my code looks like:
const embed = new RichEmbed()
let statusField
if (member.user.presence.status)
statusField = statusField + `\n**► Status:** ${member.user.presence.status}`
if (member.user.presence.game.name)
statusField = statusField + `\n**► ${gameTypeToString(member.user.presence.game.type)}:** ${member.user.presence.game.name}`
embed.addField("User Status", statusField)
message.channel.send(embed);
Notes:
As a side note for context, my embed is bigger and has more
information in it, I'm just only showing the relevant pieces.
I'm aware that member.user.presence.status is the online/idle/dnd/offline status, I am also displaying that in the embed, but along with the custom status and/or current game.
gameTypeToString is a simple function that looks like this:
gameTypeToString: function(gameType) {
switch (gameType) {
case 0:
return "Playing"
case 1:
return "Streaming"
case 2:
return "Listening to"
case 3:
return "Watching"
default:
return "Doing"
}
}

Related

how to trigger a command from another file

I am trying to create a music bot, but i have an issue with the loop command, I want to trigger loop.js when the user clicks on a certain react emoji on the playing menu, for now, the command runs independently in both play.js and loop.js. The reason I want to do this is because in case a user selects the reaction and then does the command itself, the bot would say the opposite if it was either on or off.
Here is my loop.js
module.exports = {
name: "loop",
aliases: ['l'],
description: "Toggle music loop",
execute(message) {
const queue = message.client.queue.get(message.guild.id);
if (!queue) return message.reply("There is nothing playing.").catch(console.error);
if (!canModifyQueue(message.member)) return;
let loopembed = new MessageEmbed()
.setTitle("Loop settings")
.setDescription(`Loop is now ${queue.loop ? "**on**" : "**off**"}`)
.setColor(message.guild.me.displayColor)
.setFooter(`Action performed by ${message.author.tag}`)
// toggle from false to true and reverse
queue.loop = !queue.loop;
return queue.textChannel
.send(loopembed)
.catch(console.error);
}
};
And here is my loop reaction command from play.js
case "🔁":
reaction.users.remove(user).catch(console.error);
if (!canModifyQueue(member)) return;
queue.loop = !queue.loop;
queue.textChannel.send(`Loop is now ${queue.loop ? "**on**" : "**off**"}`).catch(console.error);
break;
I'm trying to make loop.js run instead of it being run independently in case of the reacted emoji.
Thank you for helping in advance

Alexa Skills Dialog Management: how to repeat last intent without specifing its utterances again

I'm developing my first Alexa skill and I want to try to improve its dialog management.
My skill has several intents: one to get the temperature indoor, one to get the humidity and so on. Every intent has one slot that represents the floor/room of my house so the typical question to Alexa is "What's the temperature on the first floor?"
Every time intent is executed it stores the slot in a session attribute so I can handle a conversation like this:
me: "Alexa what's the temperature on the first floor?"
Alexa: "The temperature on the first floor is 24 degrees"
me: "and the humidity?"
Alexa: "The humidity on the first floor is 50%"
The next step that I'm trying to implement is this type of dialog:
me: "Alexa what's the temperature on the first floor?"
Alexa: "The temperature on the first floor is 24 degrees"
me: "and on the second floor?"
Alexa: "The temperature on the second floor is 26 degrees"
In practice, I need to launch the last executed intent without saying its utterances.
I was thinking of creating a new generic intent that receives only the slot and then dispatches the request to the last executed intent.
I can keep track of the last intent executed saving its ID in a session attribute.
Is there a better way to do this?
Every suggestion is welcome because I am developing Alexa skills since last Monday! :-)
Thanks a lot.
You're on the right track. The thing to remember is you can have one intent for multiple slots and NOT require them all.
Here's how you can create a single intent for all of it.
The sample utterances are:
How are things on the {floor}
And on the {floor}
What is the {condition}
What is the {condition} on the {floor}
Then you create the "condition" and "floor" slot types, filling them with appropriate sample values like "temperature" for condition and "first floor" for floor. Then make sure to assign those slot types to the slots in your intent.
Then your handler code looks like this...
const conditionIntentHandler = {
canHandle(handlerInput) {
return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
&& Alexa.getIntentName(handlerInput.requestEnvelope) === 'conditionIntent';
},
handle(handlerInput) {
var speakOutput = "";
var condition = "";
var floor = "";
const attributesManager = handlerInput.attributesManager;
const attributes = attributesManager.getSessionAttributes();
if (handlerInput.requestEnvelope.request.intent.slots.condition.hasOwnProperty('value')) {
condition = handlerInput.requestEnvelope.request.intent.slots.condition.value;
} else if (attributes.hasOwnProperty('condition')) {
if(attributes.condition !== "") condition = attributes.condition;
}
if (handlerInput.requestEnvelope.request.intent.slots.floor.hasOwnProperty('value')) {
floor = handlerInput.requestEnvelope.request.intent.slots.floor.value;
} else if (attributes.hasOwnProperty('floor')) {
if(attributes.floor !== "") floor = attributes.floor;
}
if (floor !== "" && condition === ""){
speakOutput = "Here's the conditions for the " + floor;
} else if (floor === "" && condition !== ""){
speakOutput = "Here's the " + condition + " throughout the house";
} else if (floor !== "" && condition !== ""){
speakOutput = "Here's the " + condition + " on the " + floor;
} else {
speakOutput = "I have no idea what you're saying. Are you okay?"
}
attributes.floor = floor;
attributes.condition = condition;
attributesManager.setSessionAttributes(attributes);
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt('What else can I tell you?')
.getResponse();
}
};
I haven't written the actual code to present the values, just placeholder responses, but you should get the idea. Add more carrier phrases that contain one or both slot types to make this handle more ways people might ask for this info.

Is there any way to fetch only city and country from user input on googleplacesautocomplete api using react?

I can not get only city and country as an output from googleautocomplete component using react.
The way to do this would be to specify the types parameter on the Google Places Autocomplete component. However, the limitation there is that you can only really specify one of the options for types:
You may restrict results from a Place Autocomplete request to be of a
certain type by passing a types parameter. The parameter specifies a
type or a type collection, as listed in the supported types below. If
nothing is specified, all types are returned. In general only a single
type is allowed. The exception is that you can safely mix the geocode
and establishment types, but note that this will have the same effect
as specifying no types.
source: https://developers.google.com/places/web-service/autocomplete#place_types
So the best option for your situation would probably be to use the (regions) type collection, but this will include more than just cities and countries such as neighborhoods. Another option would be to use the (cities) type collection which will include only cities.
I also highly recommend the react-geosuggest library if you want something pre-made to accomplish this as you can pass those as parameters and style it yourself.
<Geosuggest
types={['(regions)']}
/>
EDIT
I think I might have misunderstood the question a bit. If you're trying to figure out how to get the street address, city, and country out of the response you get from the Places API, you're going to have to submit an additional request.
Once the user selects the place from the list, you will have to get the place_id out of the original request and submit a Place Details request. One of the fields in the response will be address_component which has this very strange format. I posted an example of what this full format looks like here.
I made a simple converter function that will return the basic components of an address in a manageable format:
// ---------------------------------------------------------------------- //
// https://developers.google.com/maps/documentation/geocoding/intro#Types //
// ---------------------------------------------------------------------- //
// returns:
// {
// address_1
// address_2
// city
// state_code
// zip_code
// country
// }
function convertAddressComponents(addrComp) {
let newAddr = {};
let address_1 = [];
addrComp.forEach((el, i) => {
if (el.types.includes("post_box")) {
address_1.push(el.long_name);
} else if (el.types.includes("street_number")) {
address_1.push(el.long_name);
} else if (el.types.includes("route")) {
address_1.push(el.long_name);
} else if (el.types.includes("subpremise")) {
newAddr.address_2 = el.long_name;
} else if (el.types.includes("locality")) {
newAddr.city = el.long_name;
} else if (el.types.includes("administrative_area_level_1")) {
newAddr.state_code = el.short_name;
} else if (el.types.includes("postal_code")) {
newAddr.zip_code = el.short_name;
} else if (el.types.includes("country")) {
newAddr.country = el.long_name;
}
});
newAddr.address_1 = address_1.join(" ");
return newAddr;
}
Feel free to modify this to suite your needs.

angular JS select first instance of this item

So my question is: how do I scan the JSON in angular to find the first instance of isPrimary:true and then launch a function with the GUID that is in that item.
I have a webservice whos JSON defines available Accounts with a display name and a GUID this generates a dropdown select list that calls a function with the GUID included to return full data from a web service.
In the scenario where theres only 1 OPTION I dont show the SELECT and simply call the function with the single GUID to return the data from the service. If theres no options I dont show anything other than a message.
Code below shows what I currently have.
The Spec has now changed and the data they are sending me in the first service call which defines that select list is now including a property isPrimary:true on one of the JSON object along with its GUID as per the rest
I now need to change my interface to no longer use the SELECT list and instead fire the function call to the service for the item that contains the isPrimary:true property. However there may be multiple instances where isPrimary:true exists in the returning JSON so I just want to fire the function on the first found instance of isPrimary:true
Equally if that property isnt in any of the JSON items then just fire the function on the first item in the JSON.
My current Code is below - you can see the call to retrieve the full details is from function:
vm.retrieveAccount(GUID);
Where the GUID is supplied with each JSON object
Code is:
if (data.Accounts.length > 1) {
vm.hideAcc = false;
setBusyState(false);
//wait for the user to make a selection
} else if (data.Accounts.length == 1){
vm.hideAcc = true;
// Only 1 acc - no need for drop down get first item
vm.accSelected = data.Accounts[0].UniqueIdentifier;
vm.retrieveAccount(vm.accSelected);
} else {
// Theres no accounts
// Hide Drop down and show message
setBusyState(false);
vm.hideAcc = true;
setMessageState(false, true, "There are no Accounts")
}
Sample of new JSON structure
accName: "My Acc",
isPrimary: true,
GUID: "bg111010101"
Still think that's a weird spec, but simple enough to solve. Just step through the array and return the first isPrimary match. If none are found, return the first element of the array.
var findPrimary = function(data) {
if (!(Array.isArray(data)) || data.length == 0) {
return false; // not an array, or empty array
}
for (var i=0; i<data.length; i++) {
if (data[i].isPrimary) {
return data[i]; // first isPrimary match
}
}
// nothing had isPrimary, so return the first one:
return data[0];
}

Mass update case Status - Salesforce

I am looking for a way to mass update case Status and leave a success message or failure message with failed case ID.
I currently have validation rules and triggers for update or cases. But I need to keep show at least the first failed case ID in the error message.
Is there a way to put a variable in the validation rule error message? Or its explicitly string?
I currently use a validation rule but I cant show the failed case in my error message because I cant put a variable in the error message.
Check this Link it might help you http://appexchange.salesforce.com/listingDetail?listingId=a0N30000003IleFEAS
You need to use a before trigger in this case and compare the list of selected cases before and after the update.
Or you can create a custom button and add it to the page and run the desired javascript to check what changed before and after.
something like this :
{!REQUIRESCRIPT("/soap/ajax/13.0/connection.js")}
var idArray = {!GETRECORDIDS($ObjectType.Case)};
var err = [];
var caseObj;
for (i=0; i< idArray.length ; i++){
caseObj = new sforce.SObject("Case");
caseObj.Id = idArray[i];
caseObj.Status = *** //change status here;
var result = sforce.connection.update([caseObj]);
if (result[0].success=='false') {
err.push("\n"+result[0].errors.message + " Case ID "+idArray[i]);
}
}
if(err.length >0)
{
alert(" The following cases have failed to change status: \n\n" +err);
}
location.reload(true);

Resources