actionConfig = (a) -> {
183 | };
184 |
185 | /**
186 | * Sets the channel that the message will be sent to
187 | *
188 | * @param channel
189 | * the channel that the message will be sent to
190 | *
191 | * @return The builder instance, useful for chaining
192 | *
193 | * @see #setChannel(MessageChannel)
194 | */
195 | public Builder setChannel(@Nonnull MessageChannelUnion channel) {
196 | Checks.notNull(channel, "channel");
197 |
198 | this.channel = channel;
199 | return this;
200 | }
201 |
202 | /**
203 | * Sets the channel that the message will be sent to
204 | *
205 | * @param channel
206 | * the channel that the message will be sent to
207 | *
208 | * @return The builder instance, useful for chaining
209 | *
210 | * @see #setChannel(MessageChannelUnion)
211 | */
212 | public Builder setChannel(@Nonnull MessageChannel channel) {
213 | Checks.notNull(channel, "channel");
214 |
215 | this.channel = channel;
216 | return this;
217 | }
218 |
219 | /**
220 | * Sets the message content for the message that will be sent.
221 | * THIS WILL REPLACE THE CURRENT MESSAGE BUILDER
222 | * This method will also attempt to extract the channel and any possible embeds if this information is
223 | * present.
224 | *
225 | * @param message
226 | * The message to extract the content from
227 | *
228 | * @return The builder instance, useful for chaining
229 | *
230 | * @see #setMessage(String)
231 | * @see #setMessageFormat(String, Object...)
232 | */
233 | public Builder setMessage(Message message) {
234 | this.messageBuilder = MessageCreateBuilder.fromMessage(message);
235 | // clear the embeds
236 | this.messageBuilder.setEmbeds();
237 |
238 | // set the channel if we have one
239 | if (message.getType() == MessageType.DEFAULT && message.isFromGuild()) {
240 | this.setChannel(message.getChannel());
241 | }
242 |
243 | // set the embeds on our own config, this will always use the raw preset
244 | if (!message.getEmbeds().isEmpty()) {
245 | this.setEmbeds(message.getEmbeds());
246 | }
247 |
248 | return this;
249 | }
250 |
251 | /**
252 | * Sets the content of the message that will be sent
253 | *
254 | * @param message
255 | * The content for the message
256 | *
257 | * @return The builder instance, useful for chaining
258 | *
259 | * @see #setMessage(Message)
260 | * @see #setMessageFormat(String, Object...)
261 | */
262 | public Builder setMessage(String message) {
263 | this.messageBuilder.setContent(StringUtils.abbreviate(message, Message.MAX_CONTENT_LENGTH));
264 | return this;
265 | }
266 |
267 | /**
268 | * Sets the content for the message and applies a format, this is a shortcut for using {@link String#format}
269 | * with {@link #setMessage(String)}
270 | *
271 | * @param message
272 | * The content for the message
273 | * @param args
274 | * the arguments to format the message with
275 | *
276 | * @return The builder instance, useful for chaining
277 | *
278 | * @see #setMessage(Message)
279 | * @see #setMessage(String)
280 | */
281 | public Builder setMessageFormat(String message, Object... args) {
282 | this.messageBuilder.setContent(String.format(message, args));
283 | return this;
284 | }
285 |
286 | /**
287 | * Sets the embed for the message
288 | *
289 | * @param embeds
290 | * The embeds to set on the message
291 | *
292 | * @return The builder instance, useful for chaining
293 | *
294 | * @see #addEmbed(EmbedBuilder)
295 | * @see #addEmbed(boolean, EmbedBuilder)
296 | * @see #setEmbeds(boolean, EmbedBuilder...)
297 | * @see #setEmbeds(Collection)
298 | * @see #setEmbeds(boolean, Collection)
299 | */
300 | public Builder setEmbeds(@Nonnull EmbedBuilder... embeds) {
301 | return this.setEmbeds(false, embeds);
302 | }
303 |
304 | /**
305 | * Sets the embed for the message.
306 | * NOTE: Parsing of colors will never happen if the text channel is null at the time of calling this
307 | * method
308 | *
309 | * @param raw
310 | * {@code true} to skip parsing of the guild-colors and other future items, default value is {@code false}
311 | * @param embeds
312 | * The embeds on the message
313 | *
314 | * @return The builder instance, useful for chaining
315 | *
316 | * @see #addEmbed(EmbedBuilder)
317 | * @see #addEmbed(boolean, EmbedBuilder)
318 | * @see #setEmbeds(EmbedBuilder...)
319 | * @see #setEmbeds(Collection)
320 | * @see #setEmbeds(boolean, Collection)
321 | */
322 | public Builder setEmbeds(boolean raw, @Nonnull EmbedBuilder... embeds) {
323 | Checks.noneNull(embeds, "MessageEmbeds");
324 |
325 | return this.setEmbeds(raw, Arrays.asList(embeds));
326 | }
327 |
328 | /**
329 | * Sets the embeds that the message should have
330 | *
331 | * @param embeds
332 | * The embeds to attach to the message
333 | *
334 | * @return The builder instance, useful for chaining
335 | *
336 | * @see #addEmbed(EmbedBuilder)
337 | * @see #addEmbed(boolean, EmbedBuilder)
338 | * @see #setEmbeds(EmbedBuilder...)
339 | * @see #setEmbeds(boolean, EmbedBuilder...)
340 | * @see #setEmbeds(boolean, Collection)
341 | */
342 | public Builder setEmbeds(@Nonnull Collection extends EmbedBuilder> embeds) {
343 | return this.setEmbeds(false, embeds);
344 | }
345 |
346 | /**
347 | * Please don't use this method
348 | *
349 | * @param embeds
350 | * The embeds to set
351 | *
352 | * @return The builder instance, useful for chaining
353 | *
354 | * @see #addEmbed(EmbedBuilder)
355 | * @see #addEmbed(boolean, EmbedBuilder)
356 | * @see #setEmbeds(EmbedBuilder...)
357 | * @see #setEmbeds(boolean, EmbedBuilder...)
358 | * @see #setEmbeds(Collection)
359 | * @see #setEmbeds(boolean, Collection)
360 | */
361 | public Builder setEmbeds(@Nonnull List embeds) {
362 | return this.setEmbeds(
363 | true,
364 | embeds.stream().map(EmbedBuilder::new).collect(Collectors.toList())
365 | );
366 | }
367 |
368 | /**
369 | * Sets the embeds for the message
370 | *
371 | * @param raw
372 | * {@code true} to skip parsing of the guild-colors and other future items, default value is {@code false}
373 | * @param embeds
374 | * The embeds to set on the message
375 | *
376 | * @return The builder instance, useful for chaining
377 | *
378 | * @see #addEmbed(EmbedBuilder)
379 | * @see #addEmbed(boolean, EmbedBuilder)
380 | * @see #setEmbeds(EmbedBuilder...)
381 | * @see #setEmbeds(boolean, EmbedBuilder...)
382 | * @see #setEmbeds(Collection)
383 | */
384 | public Builder setEmbeds(boolean raw, @Nonnull Collection extends EmbedBuilder> embeds) {
385 | Checks.noneNull(embeds, "MessageEmbeds");
386 |
387 | Checks.check(embeds.size() <= 10, "Cannot have more than 10 embeds in a message!");
388 |
389 | // Use raw to skip this parsing
390 | if (!raw && this.channel != null && this.channel instanceof GuildMessageChannel) {
391 | final long guild = ((GuildMessageChannel) this.channel).getGuild().getIdLong();
392 |
393 | for (final EmbedBuilder embedBuilder : embeds) {
394 | embedBuilder.setColor(EmbedUtils.getColorOrDefault(guild));
395 | }
396 | }
397 |
398 | this.embeds.clear();
399 | this.embeds.addAll(embeds);
400 |
401 | return this;
402 | }
403 |
404 | /**
405 | * Adds a single embed to the current embed list
406 | *
407 | * @param embed
408 | * The embed to add
409 | *
410 | * @return The builder instance, useful for chaining
411 | *
412 | * @see #addEmbed(boolean, EmbedBuilder)
413 | * @see #setEmbeds(EmbedBuilder...)
414 | * @see #setEmbeds(boolean, EmbedBuilder...)
415 | * @see #setEmbeds(Collection)
416 | * @see #setEmbeds(boolean, Collection)
417 | */
418 | public Builder addEmbed(@Nonnull EmbedBuilder embed) {
419 | return this.addEmbed(false, embed);
420 | }
421 |
422 | /**
423 | * Adds a single embed to the current embed list
424 | *
425 | * @param raw
426 | * {@code true} to skip parsing of the guild-colors and other future items, default value is {@code false}
427 | * @param embed
428 | * The embed to add
429 | *
430 | * @return The builder instance, useful for chaining
431 | *
432 | * @see #addEmbed(EmbedBuilder)
433 | * @see #setEmbeds(EmbedBuilder...)
434 | * @see #setEmbeds(boolean, EmbedBuilder...)
435 | * @see #setEmbeds(Collection)
436 | * @see #setEmbeds(boolean, Collection)
437 | */
438 | public Builder addEmbed(boolean raw, @Nonnull EmbedBuilder embed) {
439 | Checks.notNull(embed, "embed");
440 | Checks.check(this.embeds.size() <= 10, "Cannot have more than 10 embeds in a message!");
441 |
442 | // Use raw to skip this parsing
443 | if (!raw && this.channel != null && this.channel instanceof GuildMessageChannel) {
444 | final long guild = ((GuildMessageChannel) this.channel).getGuild().getIdLong();
445 |
446 | embed.setColor(EmbedUtils.getColorOrDefault(guild));
447 | }
448 |
449 | this.embeds.add(embed);
450 |
451 | return this;
452 | }
453 |
454 | /**
455 | * Returns the current message builder instance for you to modify
456 | *
457 | * @return The message builder instance that you can modify
458 | *
459 | * @see #configureMessageBuilder(Consumer)
460 | */
461 | public MessageCreateBuilder getMessageBuilder() {
462 | return this.messageBuilder;
463 | }
464 |
465 | /**
466 | * Allows you to override the message builder
467 | *
468 | * @param messageBuilder
469 | * the new message builder to use
470 | *
471 | * @return The builder instance, useful for chaining
472 | */
473 | public Builder setMessageBuilder(MessageCreateBuilder messageBuilder) {
474 | this.messageBuilder = messageBuilder;
475 |
476 | return this;
477 | }
478 |
479 | /**
480 | * Applies a configuration to the message builder
481 | *
482 | * @param consumer
483 | * the builder that you can modify
484 | *
485 | * @return The builder instance, useful for chaining
486 | *
487 | * @see #getMessageBuilder()
488 | */
489 | public Builder configureMessageBuilder(@Nonnull Consumer consumer) {
490 | Checks.notNull(consumer, "consumer");
491 |
492 | consumer.accept(this.messageBuilder);
493 | return this;
494 | }
495 |
496 | /**
497 | * Sets the action that is called when the {@link RestAction} fails
498 | *
499 | * @param failureAction
500 | * the action that is called when the {@link RestAction} fails, Defaults to {@link
501 | * RestAction#getDefaultFailure()}
502 | *
503 | * @return The builder instance, useful for chaining
504 | */
505 | public Builder setFailureAction(Consumer super Throwable> failureAction) {
506 | this.failureAction = failureAction;
507 | return this;
508 | }
509 |
510 | /**
511 | * Sets the action that is called when the {@link RestAction} succeeds
512 | *
513 | * @param successAction
514 | * the action that is called when the {@link RestAction} succeeds, Defaults to {@link
515 | * RestAction#getDefaultSuccess()}
516 | *
517 | * @return The builder instance, useful for chaining
518 | */
519 | public Builder setSuccessAction(Consumer super Message> successAction) {
520 | this.successAction = successAction;
521 | return this;
522 | }
523 |
524 | /**
525 | * Sets the {@link MessageCreateAction} for you to configure (eg append some content or override the nonce)
526 | *
527 | * @param actionConfig
528 | * the {@link MessageCreateAction} for you to configure (eg append some content or override the nonce)
529 | *
530 | * @return The builder instance, useful for chaining
531 | *
532 | * @see MessageCreateAction
533 | */
534 | public Builder setActionConfig(@Nonnull Consumer actionConfig) {
535 | Checks.notNull(actionConfig, "actionConfig");
536 |
537 | this.actionConfig = actionConfig;
538 | return this;
539 | }
540 |
541 | /**
542 | * Replies to the given {@link Message}
543 | * THIS WILL ONLY WORK IF THE BOT HAS READ HISTORY PERMISSION IN THE CHANNEL
544 | *
545 | * @param message
546 | * The {@link Message} on discord that you want to reply to, or {@code null} to disable
547 | *
548 | * @return The builder instance, useful for chaining
549 | *
550 | * @see #replyTo(long)
551 | * @see #replyTo(long, boolean)
552 | * @see #replyTo(Message, boolean)
553 | */
554 | public Builder replyTo(@Nullable Message message) {
555 | if (message == null) {
556 | this.replyToId = 0;
557 | } else {
558 | this.replyToId = message.getIdLong();
559 | }
560 |
561 | return this;
562 | }
563 |
564 | /**
565 | * Replies to the given {@link Message}
566 | * THIS WILL ONLY WORK IF THE BOT HAS READ HISTORY PERMISSION IN THE CHANNEL
567 | *
568 | * @param message
569 | * The {@link Message} on discord that you want to reply to, or {@code null} to disable
570 | * @param mentionRepliedUser
571 | * Set to {@code false} to not ping the user in the reply (Default: {@link
572 | * MessageRequest#isDefaultMentionRepliedUser()})
573 | *
574 | * @return The builder instance, useful for chaining
575 | *
576 | * @see #replyTo(long)
577 | * @see #replyTo(long, boolean)
578 | * @see #replyTo(Message)
579 | */
580 | public Builder replyTo(@Nullable Message message, boolean mentionRepliedUser) {
581 | if (message == null) {
582 | this.replyToId = 0;
583 | } else {
584 | this.replyToId = message.getIdLong();
585 | }
586 |
587 | this.mentionRepliedUser = mentionRepliedUser;
588 | return this;
589 | }
590 |
591 | /**
592 | * Replies to the given message with the specified id
593 | * THIS WILL ONLY WORK IF THE BOT HAS READ HISTORY PERMISSION IN THE CHANNEL
594 | *
595 | * @param messageId
596 | * The message id from a message on discord, set to {@code 0} to disable
597 | *
598 | * @return The builder instance, useful for chaining
599 | *
600 | * @see #replyTo(long, boolean)
601 | * @see #replyTo(Message)
602 | * @see #replyTo(Message, boolean)
603 | */
604 | public Builder replyTo(long messageId) {
605 | this.replyToId = messageId;
606 | return this;
607 | }
608 |
609 | /**
610 | * Replies to the given message with the specified id
611 | * THIS WILL ONLY WORK IF THE BOT HAS READ HISTORY PERMISSION IN THE CHANNEL
612 | *
613 | * @param messageId
614 | * The message id from a message on discord, set to {@code 0} to disable
615 | * @param mentionRepliedUser
616 | * Set to {@code false} to not ping the user in the reply (Default: {@link
617 | * MessageRequest#isDefaultMentionRepliedUser()})
618 | *
619 | * @return The builder instance, useful for chaining
620 | *
621 | * @see #replyTo(long)
622 | * @see #replyTo(Message)
623 | * @see #replyTo(Message, boolean)
624 | */
625 | public Builder replyTo(long messageId, boolean mentionRepliedUser) {
626 | this.replyToId = messageId;
627 | this.mentionRepliedUser = mentionRepliedUser;
628 | return this;
629 | }
630 |
631 | /**
632 | * Builds the message config and returns it.
633 | * NOTE: This method will return null when the text channel is null
634 | *
635 | * @return a message config instance
636 | */
637 | @Nonnull
638 | public MessageConfig build() {
639 | if (this.channel == null) {
640 | throw new IllegalArgumentException("No text channel has been set, set this with setChannel");
641 | }
642 |
643 | // we can send messages with just an embed
644 | if (this.messageBuilder.isEmpty() && this.embeds.isEmpty()) {
645 | throw new IllegalArgumentException("This message has no content, please add some content with setMessage or setEmbeds");
646 | }
647 |
648 | Checks.check(this.embeds.size() <= 10, "Cannot have more than 10 embeds in a message!");
649 |
650 | return new MessageConfig(
651 | this.channel,
652 | this.messageBuilder,
653 | this.embeds,
654 | this.replyToId,
655 | this.mentionRepliedUser,
656 | this.failureAction,
657 | this.successAction,
658 | this.actionConfig
659 | );
660 | }
661 |
662 | /**
663 | * Creates a config builder instance from a command context
664 | *
665 | * @param ctx
666 | * a command context instance to get the text channel from
667 | *
668 | * @return A builder instance that was created from a command context
669 | *
670 | * @see me.duncte123.botcommons.commands.DefaultCommandContext
671 | */
672 | public static Builder fromCtx(ICommandContext ctx) {
673 | return new Builder().setChannel(ctx.getChannel()).replyTo(ctx.getMessage());
674 | }
675 |
676 | /**
677 | * Creates a config builder instance from a JDA guild message received event
678 | *
679 | * @param event
680 | * A {@link MessageReceivedEvent} from JDA to get the text channel from
681 | *
682 | * @return A builder instance that was created from a {@link MessageReceivedEvent}
683 | */
684 | public static Builder fromEvent(MessageReceivedEvent event) {
685 | return new Builder().setChannel(event.getChannel()).replyTo(event.getMessage());
686 | }
687 | }
688 | }
689 |
--------------------------------------------------------------------------------