Related
Sails v1.x stores empty properties in database mongoDb, when POST api call is made with request having few properties only from actual model defined in sails model, such properties which are not available in request is saved with empty values in database collection which was not the case in sails v0.12
Since I have migrated project from sails v0.12 to sails v1.x, I am facing this issue which is leading to code breakage on api response.
I am using JOI library to validate the request properties and below is the data that is being sent to <ModelName>.create(topic).fetch()
topic = {
published: false,
closed: false,
name: 'Topic G -01',
communityId: '57d640b3-cda6-4703-8080-2ef604de2086',
activityId: '23ef04f4-699d-47c7-94ad-3fb5b1c18889',
createdByUserId: '3cc6dddd-9425-42b8-83fc-4ba3f068128d',
board: '5f7cc128c2380d00172225ee'
}
Data getting saved in database collection as below:
{
_id: ObjectId("61c9d4ec5ceca05c4b0016cb"),
published: false,
closed: false,
name: 'Topic G -01',
communityId: '57d640b3-cda6-4703-8080-2ef604de2086',
activityId: '23ef04f4-699d-47c7-94ad-3fb5b1c18889',
createdByUserId: '3cc6dddd-9425-42b8-83fc-4ba3f068128d',
board: '5f7cc128c2380d00172225ee',
createdAt: '2021-12-28T16:11:07.229Z',
updatedAt: '2021-12-28T16:11:07.229Z',
description: '',
content: null,
official: false,
locked: false,
singleResponses: false,
responseTierLimit: 0,
deleteOwnResponses: false,
showQuantResults: false,
probeQuantResponse: false,
ratingSystem: '',
responseVisibility: '',
allowParticipantQuestions: false,
qIndexVisibility: false,
disablePostReplies: false,
publishedAt: null,
questionIds: null,
updatedByUserId: '',
includedRoles: null,
}
However in sails v0.12, on the contrary it used to store as below:
{
_id: ObjectId("61c9d4ec5ceca05c4b0016cb"),
published: false,
closed: false,
name: 'Topic G -01',
communityId: '57d640b3-cda6-4703-8080-2ef604de2086',
activityId: '23ef04f4-699d-47c7-94ad-3fb5b1c18889',
createdByUserId: '3cc6dddd-9425-42b8-83fc-4ba3f068128d',
board: '5f7cc128c2380d00172225ee',
createdAt: '2021-12-28T16:11:07.229Z',
updatedAt: '2021-12-28T16:11:07.229Z',
}
I've built a few functions to table channel & category information, one of which runs when the bot starts to make sure everything is synced.
The problem I've run into is that bot.channels.cache contains channels that no longer exist, or states of a channel that no longer exists. For example, I only have one channel in the server called "general". Yet, there are 3 separate entries for that channel by name, and only one contains the ID (711043006781849686) of the current "general" channel:
import Discord from 'discord.js'
import config from '../config.js'
const bot = new Discord.Client({ partials: ['MESSAGE', 'CHANNEL', 'REACTION'] })
bot.login(config.botToken)
bot.on('ready', async () => {
console.log(bot.channels.cache)
}
-- returns --
Collection(46) [Map] {
...
'711043006781849686' => <ref *16> TextChannel {
type: 'text',
deleted: false,
id: '711043006781849686',
name: 'general',
rawPosition: 10,
parentID: '711043007197216880',
permissionOverwrites: Collection(3) [Map] {
'711043006253367426' => [PermissionOverwrites],
'711043006295179347' => [PermissionOverwrites],
'861109585930747934' => [PermissionOverwrites]
},
topic: 'General chat channel.',
nsfw: false,
lastMessageID: '860794574707752980',
rateLimitPerUser: 0,
lastPinTimestamp: null,
guild: Guild {
members: [GuildMemberManager],
channels: [GuildChannelManager],
roles: [RoleManager],
presences: [PresenceManager],
voiceStates: [VoiceStateManager],
deleted: false,
available: true,
id: '711043006253367426',
shardID: 0,
name: 'Omegabox',
icon: null,
splash: null,
discoverySplash: null,
region: 'us-central',
memberCount: 5,
large: false,
features: [Array],
applicationID: null,
afkTimeout: 900,
afkChannelID: '711043009944223832',
systemChannelID: '711043006781849686',
embedEnabled: undefined,
premiumTier: 0,
premiumSubscriptionCount: 0,
verificationLevel: 'NONE',
explicitContentFilter: 'DISABLED',
mfaLevel: 0,
joinedTimestamp: 1589597389528,
defaultMessageNotifications: 'ALL',
systemChannelFlags: [SystemChannelFlags],
maximumMembers: 100000,
maximumPresences: null,
approximateMemberCount: null,
approximatePresenceCount: null,
vanityURLCode: null,
vanityURLUses: null,
description: null,
banner: null,
rulesChannelID: null,
publicUpdatesChannelID: null,
preferredLocale: 'en-US',
ownerID: '598729034867933195',
emojis: [GuildEmojiManager]
},
messages: MessageManager {
cacheType: [class LimitedCollection extends Collection],
cache: [LimitedCollection [Map]],
channel: [Circular *16]
},
_typing: Map(0) {}
},
...
'827343616678559757' => <ref *33> TextChannel {
type: 'text',
deleted: false,
id: '827343616678559757',
name: 'general',
rawPosition: 0,
parentID: '827343616678559755',
permissionOverwrites: Collection(0) [Map] {},
topic: null,
lastMessageID: '830245759152291860',
rateLimitPerUser: 0,
lastPinTimestamp: null,
guild: Guild {
members: [GuildMemberManager],
channels: [GuildChannelManager],
roles: [RoleManager],
presences: [PresenceManager],
voiceStates: [VoiceStateManager],
deleted: false,
available: true,
id: '827343616678559754',
shardID: 0,
name: 'Megabox Emojis 1',
icon: null,
splash: null,
discoverySplash: null,
region: 'us-west',
memberCount: 3,
large: false,
features: [],
applicationID: null,
afkTimeout: 300,
afkChannelID: null,
systemChannelID: '827343616678559757',
embedEnabled: undefined,
premiumTier: 0,
premiumSubscriptionCount: 0,
verificationLevel: 'NONE',
explicitContentFilter: 'DISABLED',
mfaLevel: 0,
joinedTimestamp: 1617380998194,
defaultMessageNotifications: 'ALL',
systemChannelFlags: [SystemChannelFlags],
maximumMembers: 100000,
maximumPresences: null,
approximateMemberCount: null,
approximatePresenceCount: null,
vanityURLCode: null,
vanityURLUses: null,
description: null,
banner: null,
rulesChannelID: null,
publicUpdatesChannelID: null,
preferredLocale: 'en-US',
ownerID: '598729034867933195',
emojis: [GuildEmojiManager]
},
messages: MessageManager {
cacheType: [class LimitedCollection extends Collection],
cache: [LimitedCollection [Map]],
channel: [Circular *33]
},
nsfw: false,
_typing: Map(0) {}
},
...
'827344454259703842' => <ref *34> TextChannel {
type: 'text',
deleted: false,
id: '827344454259703842',
name: 'general',
rawPosition: 0,
parentID: '827344454259703840',
permissionOverwrites: Collection(0) [Map] {},
topic: null,
lastMessageID: '827580681730261032',
rateLimitPerUser: 0,
lastPinTimestamp: null,
guild: Guild {
members: [GuildMemberManager],
channels: [GuildChannelManager],
roles: [RoleManager],
presences: [PresenceManager],
voiceStates: [VoiceStateManager],
deleted: false,
available: true,
id: '827344454259703838',
shardID: 0,
name: 'Megabox Emojis 2',
icon: null,
splash: null,
discoverySplash: null,
region: 'us-west',
memberCount: 3,
large: false,
features: [],
applicationID: null,
afkTimeout: 300,
afkChannelID: null,
systemChannelID: '827344454259703842',
embedEnabled: undefined,
premiumTier: 0,
premiumSubscriptionCount: 0,
verificationLevel: 'NONE',
explicitContentFilter: 'DISABLED',
mfaLevel: 0,
joinedTimestamp: 1617381010142,
defaultMessageNotifications: 'ALL',
systemChannelFlags: [SystemChannelFlags],
maximumMembers: 100000,
maximumPresences: null,
approximateMemberCount: null,
approximatePresenceCount: null,
vanityURLCode: null,
vanityURLUses: null,
description: null,
banner: null,
rulesChannelID: null,
publicUpdatesChannelID: null,
preferredLocale: 'en-US',
ownerID: '598729034867933195',
emojis: [GuildEmojiManager]
},
messages: MessageManager {
cacheType: [class LimitedCollection extends Collection],
cache: [LimitedCollection [Map]],
channel: [Circular *34]
},
nsfw: false,
_typing: Map(0) {}
}
}
I'm aware that there is a category named "General" (ID: 711043007197216880), but the casing is different which is maintained in an entry. I've filtered that one out, along with everything else that isn't "general" from the above block.
What am I missing here? Possible to sync things up?
Always have an epiphany right after finally making a post.
Been at this for hours and never realized that in this specific call I'm not specifying what guild, or rather what server. The bot is in multiple servers, and I've already got the current server's ID in the config I'm working with.
Changed bot.channels.cache to bot.guilds.cache.get(config.guildId).channels.cache.
I am trying to make my discord bot mass give everyone in my server a role. Whenever I do -giveall it only gives me the role. I have tried using map and array. Using message.guild.members.filter(member => member.roles.array().length > 1).forEach(member => member.addRole(role)); with no luck.
if (command === 'giveall') {
let role = message.guild.roles.cache.find(r => r.name == 'cool')
if (!role) return message.channel.send(`**${message.author.username}**, role not found`)
message.guild.members.cache.filter(m => !m.user.bot).forEach(member => member.roles.add(role))
message.channel.send(`**${message.author.username}**, role **${role.name}** was added to all members`)
}
Here is the log I received with console.log(message.guild.members.cache.filter(m => !m.user.bot));:
Collection [Map] {
'759457326251114536' => GuildMember {
guild: Guild {
members: [GuildMemberManager],
channels: [GuildChannelManager],
roles: [RoleManager],
presences: [PresenceManager],
voiceStates: [VoiceStateManager],
deleted: false,
available: true,
id: '760015259619819550',
shardID: 0,
name: 'GoodGameBTWâ„¢',
icon: '5c364ec985a0706a27c31b89953d01e4',
splash: null,
discoverySplash: null,
region: 'india',
memberCount: 10,
large: false,
features: [Array],
applicationID: null,
afkTimeout: 300,
afkChannelID: null,
systemChannelID: null,
embedEnabled: undefined,
premiumTier: 0,
premiumSubscriptionCount: 0,
verificationLevel: 'LOW',
explicitContentFilter: 'ALL_MEMBERS',
mfaLevel: 0,
joinedTimestamp: 1603042420216,
defaultMessageNotifications: 'MENTIONS',
systemChannelFlags: [SystemChannelFlags],
maximumMembers: 100000,
vanityURLCode: null,
vanityURLUses: null,
description: null,
banner: null,
rulesChannelID: '771729349632196608',
publicUpdatesChannelID: '768502471676788777',
preferredLocale: 'en-US',
ownerID: '759457326251114536',
emojis: [GuildEmojiManager]
},
joinedTimestamp: 1601272158336,
lastMessageID: '773102408938029056',
lastMessageChannelID: '760778837612822558',
premiumSinceTimestamp: 0,
deleted: false,
nickname: null,
_roles: [ '760763514402111488', '760759896232296468' ],
user: User {
id: '759457326251114536',
username: 'Prof. MineKraft',
bot: false,
discriminator: '6612',
avatar: '97ee817e5098d3e6ee4c174a449d1779',
flags: [UserFlags],
lastMessageID: '773102408938029056',
lastMessageChannelID: '760778837612822558'
}
}
}
From the log, you can see that the cache has only two users, the bot and you. So when you filter the bot out, only you get the role.
This can be because you have gateway intents disabled. Please go to the discord developer portal and enable the Server member intent. That should fix your problem.
I am doing stripe subscription using node js Api's when i go to subscription under dashboard its created subscription but it gives status incomplete,no payment deduction occurs
if i am doing through dashboard its create the subscription with active status
id: 'sub_INTyoOKF5bt1ib',
object: 'subscription',
application_fee_percent: null,
billing_cycle_anchor: 1605199862,
billing_thresholds: null,
cancel_at: null,
cancel_at_period_end: false,
canceled_at: null,
collection_method: 'charge_automatically',
created: 1605199862,
current_period_end: 1605286262,
current_period_start: 1605199862,
customer: 'cus_INTyfeuOhg9XDC',
days_until_due: null,
default_payment_method: null,
default_source: null,
default_tax_rates: [],
discount: null,
ended_at: null,
items: {
object: 'list',
data: [ [Object] ],
has_more: false,
total_count: 1,
url: '/v1/subscription_items?subscription=sub_INTyoOKF5bt1ib'
},
latest_invoice: 'in_1Hmj0lLm4uTMGNUSyogmK9TA',
livemode: true,
metadata: {},
next_pending_invoice_item_invoice: null,
pause_collection: null,
pending_invoice_item_interval: null,
pending_setup_intent: null,
pending_update: null,
plan: {
id: 'price_1HlYMvLm4uTMGNUSarJML52T',
object: 'plan',
active: true,
aggregate_usage: null,
amount: 100,
amount_decimal: '100',
billing_scheme: 'per_unit',
created: 1604920625,
currency: 'inr',
interval: 'day',
interval_count: 1,
livemode: true,
metadata: {},
nickname: null,
product: 'prod_IMGu6PI2mJbBCi',
tiers_mode: null,
transform_usage: null,
trial_period_days: null,
usage_type: 'licensed'
},
quantity: 1,
schedule: null,
start_date: 1605199862,
status: 'incomplete',
transfer_data: null,
trial_end: null,
trial_start: null
}
*********latest invoice and payment intent
id: 'sub_INkoNdFnS5DaZR',
object: 'subscription',
application_fee_percent: null,
billing_cycle_anchor: 1605262511,
billing_thresholds: null,
cancel_at: null,
cancel_at_period_end: false,
canceled_at: null,
collection_method: 'charge_automatically',
created: 1605262511,
current_period_end: 1605348911,
current_period_start: 1605262511,
customer: 'cus_INkoPwPjgIyGbV',
days_until_due: null,
default_payment_method: null,
default_source: null,
default_tax_rates: [],
discount: null,
ended_at: null,
items: {
object: 'list',
data: [ [Object] ],
has_more: false,
total_count: 1,
url: '/v1/subscription_items?subscription=sub_INkoNdFnS5DaZR'
},
latest_invoice: {
id: 'in_1HmzJDLm4uTMGNUSmbbqqwR7',
object: 'invoice',
account_country: 'IN',
account_name: 'Walkify',
account_tax_ids: null,
amount_due: 100,
amount_paid: 0,
amount_remaining: 100,
application_fee_amount: null,
attempt_count: 0,
attempted: true,
auto_advance: true,
billing_reason: 'subscription_create',
charge: null,
collection_method: 'charge_automatically',
created: 1605262511,
currency: 'inr',
custom_fields: null,
customer: 'cus_INkoPwPjgIyGbV',
customer_address: {
city: 'Mangaliya,Indore',
country: 'IN',
line1: '',
line2: '',
postal_code: null,
state: 'India'
},
customer_email: 'abc#gmail.com',
customer_name: 'Ravi R',
customer_phone: '',
customer_shipping: null,
customer_tax_exempt: 'none',
customer_tax_ids: [],
default_payment_method: null,
default_source: null,
default_tax_rates: [],
description: null,
discount: null,
discounts: [],
due_date: null,
ending_balance: 0,
footer: null,
hosted_invoice_url: 'https://invoice.stripe.com/i/acct_1HZVL5Lm4uTMGNUS/invst_INkotPj0f800RnPxEA5u8Lzw7IR6Dvy',
invoice_pdf: 'https://pay.stripe.com/invoice/acct_1HZVL5Lm4uTMGNUS/invst_INkotPj0f800RnPxEA5u8Lzw7IR6Dvy/pdf',
last_finalization_error: null,
lines: {
object: 'list',
data: [Array],
has_more: false,
total_count: 1,
url: '/v1/invoices/in_1HmzJDLm4uTMGNUSmbbqqwR7/lines'
},
livemode: true,
metadata: {},
next_payment_attempt: null,
number: 'A77E89AD-0001',
paid: false,
payment_intent: {
id: 'pi_1HmzJDLm4uTMGNUSRu34ggsq',
object: 'payment_intent',
amount: 100,
amount_capturable: 0,
amount_received: 0,
application: null,
application_fee_amount: null,
canceled_at: null,
cancellation_reason: null,
capture_method: 'automatic',
charges: [Object],
client_secret: 'pi_1HmzJDLm4uTMGNUSRu34ggsq_secret_7Sk56e79TEjpt3EQSI4a7CS5a',
confirmation_method: 'automatic',
created: 1605262511,
currency: 'inr',
customer: 'cus_INkoPwPjgIyGbV',
description: 'Subscription creation',
invoice: 'in_1HmzJDLm4uTMGNUSmbbqqwR7',
last_payment_error: null,
livemode: true,
metadata: {},
next_action: [Object],
on_behalf_of: null,
payment_method: 'pm_1HmzJBLm4uTMGNUSeROzE4C9',
payment_method_options: [Object],
payment_method_types: [Array],
receipt_email: null,
review: null,
setup_future_usage: 'off_session',
shipping: null,
source: null,
statement_descriptor: null,
statement_descriptor_suffix: null,
status: 'requires_action',
transfer_data: null,
transfer_group: null
},
period_end: 1605262511,
period_start: 1605262511,
post_payment_credit_notes_amount: 0,
pre_payment_credit_notes_amount: 0,
receipt_number: null,
starting_balance: 0,
statement_descriptor: null,
status: 'open',
status_transitions: {
finalized_at: 1605262511,
marked_uncollectible_at: null,
paid_at: null,
voided_at: null
},
subscription: 'sub_INkoNdFnS5DaZR',
subtotal: 100,
tax: null,
total: 100,
total_discount_amounts: [],
total_tax_amounts: [],
transfer_data: null,
webhooks_delivered_at: 1605262511
},
livemode: true,
metadata: {},
next_pending_invoice_item_invoice: null,
pause_collection: null,
pending_invoice_item_interval: null,
pending_setup_intent: null,
pending_update: null,
plan: {
id: 'price_1HlYMvLm4uTMGNUSarJML52T',
object: 'plan',
active: true,
aggregate_usage: null,
amount: 100,
amount_decimal: '100',
billing_scheme: 'per_unit',
created: 1604920625,
currency: 'inr',
interval: 'day',
interval_count: 1,
livemode: true,
metadata: {},
nickname: null,
product: 'prod_IMGu6PI2mJbBCi',
tiers_mode: null,
transform_usage: null,
trial_period_days: null,
usage_type: 'licensed'
},
quantity: 1,
schedule: null,
start_date: 1605262511,
status: 'incomplete',
transfer_data: null,
trial_end: null,
trial_start: null
}
Stripe account country is india and card is also india
This question already has answers here:
Can we add text field dynamically
(2 answers)
Closed 2 years ago.
I'm having a problem retrieving the activityID of a Choice prompt once the selection has been made within a waterfall dialog. Im currently making use of a Teams channel.
An example my code can be found below. In the step after the selection, if I have a look at the stepContext object(found further below), there is reference of an Activity.id, but this id is infact the Activity id for the current step. I'm sure I'm missing something simple, but cant figure it out.
async step1(step) {
const choice1 = await step.prompt(CHOICE_PROMPT, {
prompt: 'Please select one of the following:',
choices: ChoiceFactory.toChoices(['Option1', 'Option2', 'Option3'])
});
return choice1
}
async step2(step) {
console.log(step)
console.log("...........................................................................")
return await step.prompt(NAME_PROMPT, 'Please insert your name')
}
WaterfallStepContext {
dialogs:
DialogSet {
dialogs:
{ NAME_PROMPT: [Object],
CHOICE_PROMPT: [Object],
CONFIRM_PROMPT: [Object],
ATTACHMENT_PROMPT: [Object],
WATERFALL_DIALOG: [Object] },
dialogState: undefined },
context:
TurnContext {
_respondedRef: { responded: false },
_turnState:
Map {
Symbol(BotIdentity) => [Object],
Symbol(ConnectorClient) => [Object],
Symbol(OAuthScope) => 'https://api.botframework.com',
'botCallbackHandler' => [AsyncFunction],
Symbol(state) => [Object],
Symbol(ActivityReceivedEmitted) => true },
_onSendActivities: [],
_onUpdateActivity: [],
_onDeleteActivity: [],
bufferedReplyActivities: [],
_adapter:
BotFrameworkAdapter {
middleware: [Object],
BotIdentityKey: Symbol(BotIdentity),
OAuthScopeKey: Symbol(OAuthScope),
ConnectorClientKey: Symbol(ConnectorClient),
TokenApiClientCredentialsKey: Symbol(TokenApiClientCredentials),
settings: [Object],
credentials: [Object],
credentialsProvider: [Object],
isEmulatingOAuthCards: false,
authConfiguration: [Object],
turnError: [AsyncFunction] },
_activity:
{ text: 'Option1',
textFormat: 'plain',
type: 'message',
timestamp: 2020-05-05T13:32:42.187Z,
localTimestamp: 2020-05-05T13:32:42.187Z,
id: '1588685562137',
channelId: 'msteams',
serviceUrl: 'https://smba.trafficmanager.net/za/',
from: [Object],
conversation: [Object],
recipient: [Object],
entities: [Array],
channelData: [Object],
locale: 'en-US' } },
stack: [ { id: 'WATERFALL_DIALOG', state: [Object] } ],
state: DialogStateManager { dialogContext: [Circular] },
_info:
{ index: 1,
options: {},
reason: 'endCalled',
result: { value: 'Option1', index: 0, score: 1, synonym: 'Option1' },
values: { instanceId: 'b5bef7ce-1c43-e1db-abc0-651ed2b5bb8f' },
onNext: [Function: onNext] },
parent:
DialogContext {
dialogs: DialogSet { dialogs: [Object], dialogState: [Object] },
context:
TurnContext {
_respondedRef: [Object],
_turnState: [Object],
_onSendActivities: [],
_onUpdateActivity: [],
_onDeleteActivity: [],
bufferedReplyActivities: [],
_adapter: [Object],
_activity: [Object] },
stack: [ [Object] ],
You're not missing anything simple. This is actually sort of difficult to do because Microsoft Teams does not include any information about the button that sent an action to your bot.
In order to get the activity ID that an action came from, you have to save the ID in bot state on the turn that you send the activity. The ID can be found in the resource response returned by whichever method you use to send the activity. Unfortunately, this means you can't let the prompt send the card for you because then you wouldn't be able to access the resource response.
If you want to save more than one activity ID at a time, you'll need a way of knowing which one is associated with each incoming action. This means you'll have to include metadata in the actions you put in your cards and save that metadata along with the activity ID in your bot state.
If you'd like an easier or even an automatic way of doing all this, please voice your support for the cards library that I'm currently working on: https://github.com/BotBuilderCommunity/botbuilder-community-dotnet/issues/137