Discord js v13 Command Argument Options - discord.js

Atm I can't find it in the docs so before I continuous searching I think I better ask in here.
I want to use a dropdown menu roles but it has 2 command.
Command 1: /addmessage channel text to create the dropdown menu text and add's it to a channel.
Command 2: /addrole messageId roleId to create that text made above into a dropdown menu role.
but 1 want to make it into 1 command.
So that the first argument will be a choices argument build with 2 choices to make. (addmessage / addrole)
Based on what choice they make, different next arguments will be used.
Like for example.
If addmessage = add then the next arguments to fill in are channel and text
if addrole = role then the next arguments will be text id and role id?
Or is this not possible and it's best to leave them as 2 commands?

Assuming you are using slash commands and the slash command builders, there is a sub command option. In your case, the command might look something like this:
const { SlashCommandBuilder } = require("#discordjs/builders");
const command = new SlashCommandBuilder()
.setName("add")
.addSubcommand(sub =>
sub
.setName("message")
.addChannelOption(opt => opt.setName("channel"))
.addStringOption(opt => opt.setName("text"))
)
.addSubcommand(sub =>
sub
.setName("role")
.addStringOption(opt => opt.setName("message id"))
.addRoleOption(opt => opt.setName("role"))
)
/*
/add message <channel> <text>
/add role <message id> <role>
*/
More Resources:
https://discord.js.org/#/docs/builders/stable/class/SlashCommandBuilder
https://discordjs.guide/popular-topics/builders.html

Related

Alternative Ways to Define Users in Discord.JS

So to define users for things like displaying avatars, etc. i've been using this;
var user = message.mentions.users.first() || message.author;
But i've been trying to figure out how people have been able to define users without mentions. Example - my command requires me to tag someone whereas Dyno can do it with partial names. Any tips would be great, thanks!
An easy way to do so would probably be using the .find() function, where you can search for a certain object based on a method.
For example, if we were to have an args variable in our callback (Very easy to do so using a proper command handler - I'd suggest looking for tutorials if you aren't familiar with command handlers), and we were to ask a user to pass in a member's name, we could very easily get the user object using:
const user = message.guild.users.cache.find(user => user.username === args[0]);
// Keep in mind, 'user' is just a variable I've defined. It could also be 'monke => monke.username' if you wish.
Or, if we were to ask for their ID, we could use the .get() function to get the user object by ID:
const user = message.guild.users.cache.get(args[0]);
Do keep in mind it's not the greatest to have these kinds of object getting functions, as there are always multiple conflicts that could occur whilst getting the object, such as if there are multiple users with the same name/tag. I'd highly recommend sticking to your mention-based user objects, as it's the most accurate and non-conflicting method.
Every guild has a list of members which you can search through by enabling the Server Members Intent for your bot via the Discord Developer Portal. Once you have done that, you can fetch a collection of all members of a guild by doing
guild.members.cache;
You can then search this collection to find a member based on a search query using .includes(), .filter() or something similar. For example:
let query = "something";
let list = guild.members.cache.filter(member => member.user.username.includes(query));
console.log(Object.entries(list));
// expected output: list of all server members who's usernames contain "something"
You could also use the .find() method (since a collection is a map) to return a member with an exact username:
let member = guild.members.cache.find(member => member.user.username === query);
console.log(member.tag);
// expected output: tag of the user who's username is "something"
This is as simple as that:
var user = message.guild.members.cache.find(u => u.user.username.toUpperCase() === args.join(" ") || u.user.username.toLowerCase() === args.join(" ") || u.user.username === args.join(" "))
This will find the user on the current guild but you can also search your bot for this user by doing:
var user = client.users.cache.find(u => u.username.toUpperCase() === args.join(" ") || u.username.toLowerCase() === args.join(" ") || u.username === args.join(" "))
I have to assume that you already defined args and client. The example above will find users just by typing their name. toUpperCase means if you type the username in uppercase letters it will find the users anyways. toLowerCase means if you type the username in lowercase letters it will find the user as well. And you could also just type the username as it is. || means or so you can decide how you write the username, it will be found anyways.

How to check if user has a specific role from a specific server then give them a badge in an embed

So I have an economy system in my bot and I want staff members, beta testers, etc in my support server to get this special badge on their profile(embed) command!
So far this is my idea:
let badge = '';
if(message.member.roles.has(<role>.id)) badge = "badge here"
I am using discord.js v11.5.1
Once you've created the image of the badge, just use the .setThumbnail() method to point to the image or a link of that image so that you can show the badge on their embed.
const member = client.guilds.get(GUILD_ID).members.get(message.author.id);
if (member.roles.has(role)) embed.setThumbnail('link_to_badge_img')
If however you'd rather just have a list of badges in the embed's description then you can just list them like so:
const member = client.guilds.get(GUILD_ID).members.get(message.author.id);
if (member.roles.has(role)) embed.setDescription('BadgeTitle')
Or in case the user has multiple badges you can create an array of badges and push the badges they have to it before finally adding it to the embed description like so:
const member = client.guilds.get(GUILD_ID).members.get(message.author.id);
if (member.roles.has(role)) badges.push('BadgeTitle') //Do this for each badge
if (badges.length) embed.setDescription(`**Badges**\n${badges.join('\n')}`)

?members command for my discord bot - discord.js

So I've been trying to create a ?members command which lists all the users with a role.
So far I've got this:
if (message.content.startsWith("?members")) {
let roleName = message.content.split(" ").slice(1).join(" ");
let membersWithRole = message.guild.members.filter(member => {
return member.roles.find("name", roleName);
}).map(member => {
return member.user.username;
})
const embed = new Discord.RichEmbed({
"title": `Members in ${roleName}`,
"description": membersWithRole.join("\n"),
"color": 0xFFFF
});
return message.channel.send(embed);
}
So, it works if you type the exact name of the role, but not when you ping it or type the first word. I've been trying for hours to figure out how to do it, and I figured I should ask for help.
Thanks in advance!
Pings get translated into a code as they come through, there is a lot of information on how to parse them in the official guide After it's parsed into a role id you can just use members.roles.get() because that is what they are indexed by.
As for finding a partial name, for that you are going to have to run a function on your find and use String.includes.
return member.roles.find(role => role.name.includes(roleName));
This will also work for find the whole name of course, so it can replace your existing line.
However, this may result in more than one role. This is also true for searching by the entire role name, however, as there are no restrictions on duplicate named roles. For this you may want to invert you design and search through message.guild.roles first for any matching roles, then search for members with the roles found.

How can I programmatically set the value for a field in a Commerce Product custom Line Item Type?

I've set up a product which uses a custom line item type called "Custom Notes" (created through the UI at Configuration > Line Item Types). One of the fields in "Custom Notes", that is exposed at checkout, is a "field_notes" textarea field. It works as intended... in a product display I can add some custom text, click ORDER and the note carries through to checkout.
However, I need to create these orders programmatically. I've gotten to the point where i'm using a hook_menu to submit an order and it works great. The only problem is that I can't seem to set the value for the "field_notes".
// Load whatever product represents the item the customer will be
// paying for and create a line item for it.
$line_item = commerce_product_line_item_new($product, $quantity, $order->order_id);
// Save the line item to get its ID.
commerce_line_item_save($line_item);
//***this is the part that's not working. trying to set the field_notes field***
$line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
$line_item_wrapper->field_notes->set("Does this work??");
// Save the line item to get its ID.
commerce_line_item_save($line_item);
// Add the line item to the order using fago's rockin' wrapper.
$order_wrapper = entity_metadata_wrapper('commerce_order', $order);
$order_wrapper->commerce_line_items[] = $line_item;
// Save the order again to update its line item reference field.
commerce_order_save($order);
What am i doing wrong? Thanks!
I think it could be because you are not passing the correct line item type to commerce_product_line_item_new. For example, this is how I would do it:
$line_item = commerce_product_line_item_new(
$product,
$quantity = 1,
$order_id = 0,
$data = array(),
$line_item_type = 'my_custom_line_item_type'
);

Drupal 7 load profile2 programmatically

I have two profile2 profiles defined - main and customer_profile. Also, I have a node type called Customer.
When creating a new Customer node, I would like to load the custom_profile form. The idea is to create a node and a profile simultaneously.
I know it's definately a hook_form_alter solution but can someone tell me how to programmatically load a profile while creating or editing a Customer node.
You can load profile type and data by using these function
$types = profile2_get_types();
profile2_load_by_user($account, $type_name = NULL)
For Example :
$types = profile2_get_types();
if (!empty($types)) {
foreach ($types as $type) {
$profile = profile2_load_by_user($uid, $type->type);
}
}
Even if you are able to load the customer_profile form, you will need to handle the values separately as they are two different nodes.
I would suggest capturing those fields in the customer node form, and then create a customer_profile programmatically from the values.
If you want to get the profile2 form itself then you can use something like
module_load_include('inc', 'profile2_page', 'profile2_page');
$profile2 = profile2_by_uid_load($uid, 'seeker_profile');
$entity_form = entity_ui_get_form('profile2', $profile2, 'edit');
and then add that to the form you want to place it in.
You can load full profile data using profile2_load_by_user();
params like:-
profile2_load_by_user($account,$type_name)
$account: The user account to load profiles for, or its uid.
$type_name: To load a single profile, pass the type name of the profile to load
So code like bellow
$account->uid = $existingUser->uid;
$type_name = 'user_about';
$profile = profile2_load_by_user($account, $type_name);
//$profile variable have full data of profile fields
//changing data profile2 fields
if(isset($_POST['field_user_first_name'])&& !empty($_POST['field_user_first_name'])){
$profile->field_user_first_name['und'][0]['value'] = $_POST['field_user_first_name'];
}
profile2_save($profile);
Well When creating a new Profile , Profile2 fields are not visible until a manual save is done.
To Automatically create the profile2 object , We use rules Module
Step
1) Go to Drupal admin/config/workflow/rules
2) create new rule
3) Give a name and Select in react/event "After saving a new user account"
4) Action,>> Add Action >> Execute custom PHP code
5) insert php code
$profile = profile_create(array('type' => 'profile2 type machine name', 'uid' => $account->uid));
profile2_save($profile);
6)Save >> Save changes.
This will create profile2 field when a new user is Created.
I had a similar need for creating a custom tab at the user page and loading the user profile2 form in it.
Here is a snap code of how I managed to accomplish just that:
MYMODULE.module https://gist.github.com/4223234
MYMODULE_profile2_MYPROFILE2TYPE.inc https://gist.github.com/4223201
Hope it helps.

Resources