elynn-baileys 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +2372 -0
- package/WAProto/index.d.ts +15871 -0
- package/WAProto/index.js +115447 -0
- package/elynn/config.js +12 -0
- package/elynn/plugins/README.md +24 -0
- package/elynn/plugins/ai/deepseekr1.js +27 -0
- package/elynn/plugins/ai/gita.js +16 -0
- package/elynn/plugins/ai/glm47flash.js +27 -0
- package/elynn/plugins/ai/gptoss120b.js +27 -0
- package/elynn/plugins/ai/qwq32b.js +27 -0
- package/elynn/plugins/berita/antara.js +18 -0
- package/elynn/plugins/berita/cnbcindonesia.js +18 -0
- package/elynn/plugins/berita/cnn.js +18 -0
- package/elynn/plugins/berita/kompas.js +18 -0
- package/elynn/plugins/berita/liputan6.js +18 -0
- package/elynn/plugins/berita/merdeka.js +18 -0
- package/elynn/plugins/berita/sindonews.js +18 -0
- package/elynn/plugins/berita/tribunnews.js +18 -0
- package/elynn/plugins/downloader/douyin.js +19 -0
- package/elynn/plugins/downloader/facebook.js +19 -0
- package/elynn/plugins/downloader/github.js +25 -0
- package/elynn/plugins/downloader/lahelu.js +19 -0
- package/elynn/plugins/downloader/snackvideo.js +19 -0
- package/elynn/plugins/downloader/soundcloud.js +19 -0
- package/elynn/plugins/downloader/tiktok.js +19 -0
- package/elynn/plugins/downloader/tiktokhd.js +19 -0
- package/elynn/plugins/downloader/twitter.js +19 -0
- package/elynn/plugins/downloader/ummy.js +26 -0
- package/elynn/plugins/index.cjs +26 -0
- package/elynn/plugins/index.js +232 -0
- package/elynn/plugins/info/bmkg.js +25 -0
- package/elynn/plugins/info/cuaca.js +23 -0
- package/elynn/plugins/info/jadwaltv.js +21 -0
- package/elynn/plugins/maker/brat.js +45 -0
- package/elynn/plugins/maker/bratvid.js +52 -0
- package/elynn/plugins/search/8font.js +18 -0
- package/elynn/plugins/search/applemusic.js +18 -0
- package/elynn/plugins/search/bimg.js +19 -0
- package/elynn/plugins/search/brave.js +24 -0
- package/elynn/plugins/search/duckduckgo.js +18 -0
- package/elynn/plugins/search/lahelu.js +18 -0
- package/elynn/plugins/search/mangatoon.js +18 -0
- package/elynn/plugins/search/mcpedl.js +18 -0
- package/elynn/plugins/search/myinstants.js +18 -0
- package/elynn/plugins/search/otakotaku.js +18 -0
- package/elynn/plugins/search/pinterest.js +19 -0
- package/elynn/plugins/search/resep.js +18 -0
- package/elynn/plugins/search/seegore.js +19 -0
- package/elynn/plugins/search/soundcloud.js +18 -0
- package/elynn/plugins/search/youtube.js +18 -0
- package/elynn/plugins/stalk/github.js +28 -0
- package/elynn/plugins/stalk/pinterest.js +27 -0
- package/elynn/plugins/stalk/threads.js +24 -0
- package/elynn/plugins/stalk/tiktok.js +27 -0
- package/elynn/plugins/stalk/twitter.js +27 -0
- package/elynn/plugins/stalk/youtube.js +27 -0
- package/engine-requirements.js +45 -0
- package/lib/Defaults/index.d.ts +145 -0
- package/lib/Defaults/index.d.ts.map +1 -0
- package/lib/Defaults/index.js +152 -0
- package/lib/Defaults/index.js.map +1 -0
- package/lib/Discord/Client.cjs +274 -0
- package/lib/Discord/Client.d.ts +98 -0
- package/lib/Discord/Client.js +274 -0
- package/lib/Discord/Constants.cjs +1842 -0
- package/lib/Discord/Constants.d.ts +1514 -0
- package/lib/Discord/Constants.js +1842 -0
- package/lib/Discord/connect-dc.js +5 -0
- package/lib/Discord/esm-bridge.mjs +128 -0
- package/lib/Discord/gateway/Dispatcher.cjs +86 -0
- package/lib/Discord/gateway/Dispatcher.d.ts +17 -0
- package/lib/Discord/gateway/Dispatcher.js +86 -0
- package/lib/Discord/gateway/Shard.cjs +723 -0
- package/lib/Discord/gateway/Shard.d.ts +87 -0
- package/lib/Discord/gateway/Shard.js +723 -0
- package/lib/Discord/gateway/ShardManager.cjs +350 -0
- package/lib/Discord/gateway/ShardManager.d.ts +31 -0
- package/lib/Discord/gateway/ShardManager.js +350 -0
- package/lib/Discord/gateway/compression/base.cjs +14 -0
- package/lib/Discord/gateway/compression/base.d.ts +6 -0
- package/lib/Discord/gateway/compression/base.js +14 -0
- package/lib/Discord/gateway/compression/config.cjs +47 -0
- package/lib/Discord/gateway/compression/config.d.ts +17 -0
- package/lib/Discord/gateway/compression/config.js +47 -0
- package/lib/Discord/gateway/compression/pako.cjs +45 -0
- package/lib/Discord/gateway/compression/pako.d.ts +16 -0
- package/lib/Discord/gateway/compression/pako.js +45 -0
- package/lib/Discord/gateway/compression/zlib-native.cjs +50 -0
- package/lib/Discord/gateway/compression/zlib-native.d.ts +10 -0
- package/lib/Discord/gateway/compression/zlib-native.js +50 -0
- package/lib/Discord/gateway/compression/zlib-sync.cjs +32 -0
- package/lib/Discord/gateway/compression/zlib-sync.d.ts +8 -0
- package/lib/Discord/gateway/compression/zlib-sync.js +32 -0
- package/lib/Discord/gateway/compression/zstd-napi.cjs +74 -0
- package/lib/Discord/gateway/compression/zstd-napi.d.ts +9 -0
- package/lib/Discord/gateway/compression/zstd-napi.js +74 -0
- package/lib/Discord/gateway/compression/zstd-native.cjs +48 -0
- package/lib/Discord/gateway/compression/zstd-native.d.ts +9 -0
- package/lib/Discord/gateway/compression/zstd-native.js +48 -0
- package/lib/Discord/gateway/events.cjs +956 -0
- package/lib/Discord/gateway/events.d.ts +75 -0
- package/lib/Discord/gateway/events.js +956 -0
- package/lib/Discord/index.cjs +228 -0
- package/lib/Discord/index.d.ts +98 -0
- package/lib/Discord/index.js +228 -0
- package/lib/Discord/rest/Bucket.cjs +77 -0
- package/lib/Discord/rest/Bucket.d.ts +32 -0
- package/lib/Discord/rest/Bucket.js +77 -0
- package/lib/Discord/rest/DiscordHTTPError.cjs +66 -0
- package/lib/Discord/rest/DiscordHTTPError.d.ts +15 -0
- package/lib/Discord/rest/DiscordHTTPError.js +66 -0
- package/lib/Discord/rest/DiscordRESTError.cjs +88 -0
- package/lib/Discord/rest/DiscordRESTError.d.ts +18 -0
- package/lib/Discord/rest/DiscordRESTError.js +88 -0
- package/lib/Discord/rest/OAuthHelper.cjs +220 -0
- package/lib/Discord/rest/OAuthHelper.d.ts +61 -0
- package/lib/Discord/rest/OAuthHelper.js +220 -0
- package/lib/Discord/rest/RESTManager.cjs +119 -0
- package/lib/Discord/rest/RESTManager.d.ts +42 -0
- package/lib/Discord/rest/RESTManager.js +119 -0
- package/lib/Discord/rest/RequestHandler.cjs +323 -0
- package/lib/Discord/rest/RequestHandler.d.ts +27 -0
- package/lib/Discord/rest/RequestHandler.js +323 -0
- package/lib/Discord/rest/SequentialBucket.cjs +74 -0
- package/lib/Discord/rest/SequentialBucket.d.ts +24 -0
- package/lib/Discord/rest/SequentialBucket.js +74 -0
- package/lib/Discord/routes/Applications.cjs +618 -0
- package/lib/Discord/routes/Applications.d.ts +230 -0
- package/lib/Discord/routes/Applications.js +618 -0
- package/lib/Discord/routes/Channels.cjs +1191 -0
- package/lib/Discord/routes/Channels.d.ts +428 -0
- package/lib/Discord/routes/Channels.js +1192 -0
- package/lib/Discord/routes/Guilds.cjs +1785 -0
- package/lib/Discord/routes/Guilds.d.ts +644 -0
- package/lib/Discord/routes/Guilds.js +1785 -0
- package/lib/Discord/routes/Interactions.cjs +205 -0
- package/lib/Discord/routes/Interactions.d.ts +74 -0
- package/lib/Discord/routes/Interactions.js +205 -0
- package/lib/Discord/routes/Lobbies.cjs +190 -0
- package/lib/Discord/routes/Lobbies.d.ts +70 -0
- package/lib/Discord/routes/Lobbies.js +190 -0
- package/lib/Discord/routes/Miscellaneous.cjs +113 -0
- package/lib/Discord/routes/Miscellaneous.d.ts +36 -0
- package/lib/Discord/routes/Miscellaneous.js +113 -0
- package/lib/Discord/routes/OAuth.cjs +343 -0
- package/lib/Discord/routes/OAuth.d.ts +107 -0
- package/lib/Discord/routes/OAuth.js +343 -0
- package/lib/Discord/routes/Users.cjs +100 -0
- package/lib/Discord/routes/Users.d.ts +32 -0
- package/lib/Discord/routes/Users.js +100 -0
- package/lib/Discord/routes/Webhooks.cjs +301 -0
- package/lib/Discord/routes/Webhooks.d.ts +126 -0
- package/lib/Discord/routes/Webhooks.js +301 -0
- package/lib/Discord/structures/AnnouncementChannel.cjs +46 -0
- package/lib/Discord/structures/AnnouncementChannel.d.ts +34 -0
- package/lib/Discord/structures/AnnouncementChannel.js +46 -0
- package/lib/Discord/structures/AnnouncementThreadChannel.cjs +28 -0
- package/lib/Discord/structures/AnnouncementThreadChannel.d.ts +17 -0
- package/lib/Discord/structures/AnnouncementThreadChannel.js +28 -0
- package/lib/Discord/structures/Application.cjs +477 -0
- package/lib/Discord/structures/Application.d.ts +166 -0
- package/lib/Discord/structures/Application.js +477 -0
- package/lib/Discord/structures/ApplicationCommand.cjs +146 -0
- package/lib/Discord/structures/ApplicationCommand.d.ts +75 -0
- package/lib/Discord/structures/ApplicationCommand.js +146 -0
- package/lib/Discord/structures/Attachment.cjs +78 -0
- package/lib/Discord/structures/Attachment.d.ts +43 -0
- package/lib/Discord/structures/Attachment.js +78 -0
- package/lib/Discord/structures/AuditLogEntry.cjs +54 -0
- package/lib/Discord/structures/AuditLogEntry.d.ts +25 -0
- package/lib/Discord/structures/AuditLogEntry.js +54 -0
- package/lib/Discord/structures/AutoModerationRule.cjs +140 -0
- package/lib/Discord/structures/AutoModerationRule.d.ts +48 -0
- package/lib/Discord/structures/AutoModerationRule.js +140 -0
- package/lib/Discord/structures/AutocompleteInteraction.cjs +120 -0
- package/lib/Discord/structures/AutocompleteInteraction.d.ts +61 -0
- package/lib/Discord/structures/AutocompleteInteraction.js +120 -0
- package/lib/Discord/structures/Base.cjs +58 -0
- package/lib/Discord/structures/Base.d.ts +19 -0
- package/lib/Discord/structures/Base.js +58 -0
- package/lib/Discord/structures/BaseEntitlement.cjs +49 -0
- package/lib/Discord/structures/BaseEntitlement.d.ts +20 -0
- package/lib/Discord/structures/BaseEntitlement.js +49 -0
- package/lib/Discord/structures/CategoryChannel.cjs +106 -0
- package/lib/Discord/structures/CategoryChannel.d.ts +40 -0
- package/lib/Discord/structures/CategoryChannel.js +106 -0
- package/lib/Discord/structures/Channel.cjs +92 -0
- package/lib/Discord/structures/Channel.d.ts +19 -0
- package/lib/Discord/structures/Channel.js +92 -0
- package/lib/Discord/structures/ClientApplication.cjs +273 -0
- package/lib/Discord/structures/ClientApplication.d.ts +189 -0
- package/lib/Discord/structures/ClientApplication.js +273 -0
- package/lib/Discord/structures/CommandInteraction.cjs +324 -0
- package/lib/Discord/structures/CommandInteraction.d.ts +166 -0
- package/lib/Discord/structures/CommandInteraction.js +324 -0
- package/lib/Discord/structures/ComponentInteraction.cjs +338 -0
- package/lib/Discord/structures/ComponentInteraction.d.ts +180 -0
- package/lib/Discord/structures/ComponentInteraction.js +338 -0
- package/lib/Discord/structures/Entitlement.cjs +27 -0
- package/lib/Discord/structures/Entitlement.d.ts +11 -0
- package/lib/Discord/structures/Entitlement.js +27 -0
- package/lib/Discord/structures/ExtendedUser.cjs +58 -0
- package/lib/Discord/structures/ExtendedUser.d.ts +25 -0
- package/lib/Discord/structures/ExtendedUser.js +58 -0
- package/lib/Discord/structures/ForumChannel.cjs +20 -0
- package/lib/Discord/structures/ForumChannel.d.ts +11 -0
- package/lib/Discord/structures/ForumChannel.js +20 -0
- package/lib/Discord/structures/GroupChannel.cjs +172 -0
- package/lib/Discord/structures/GroupChannel.d.ts +60 -0
- package/lib/Discord/structures/GroupChannel.js +172 -0
- package/lib/Discord/structures/Guild.cjs +1415 -0
- package/lib/Discord/structures/Guild.d.ts +687 -0
- package/lib/Discord/structures/Guild.js +1415 -0
- package/lib/Discord/structures/GuildChannel.cjs +90 -0
- package/lib/Discord/structures/GuildChannel.d.ts +36 -0
- package/lib/Discord/structures/GuildChannel.js +90 -0
- package/lib/Discord/structures/GuildPreview.cjs +153 -0
- package/lib/Discord/structures/GuildPreview.d.ts +49 -0
- package/lib/Discord/structures/GuildPreview.js +153 -0
- package/lib/Discord/structures/GuildScheduledEvent.cjs +188 -0
- package/lib/Discord/structures/GuildScheduledEvent.d.ts +59 -0
- package/lib/Discord/structures/GuildScheduledEvent.js +188 -0
- package/lib/Discord/structures/GuildTemplate.cjs +118 -0
- package/lib/Discord/structures/GuildTemplate.d.ts +48 -0
- package/lib/Discord/structures/GuildTemplate.js +118 -0
- package/lib/Discord/structures/Integration.cjs +157 -0
- package/lib/Discord/structures/Integration.d.ts +53 -0
- package/lib/Discord/structures/Integration.js +157 -0
- package/lib/Discord/structures/Interaction.cjs +91 -0
- package/lib/Discord/structures/Interaction.d.ts +39 -0
- package/lib/Discord/structures/Interaction.js +91 -0
- package/lib/Discord/structures/InteractionResolvedChannel.cjs +46 -0
- package/lib/Discord/structures/InteractionResolvedChannel.d.ts +27 -0
- package/lib/Discord/structures/InteractionResolvedChannel.js +46 -0
- package/lib/Discord/structures/Invite.cjs +240 -0
- package/lib/Discord/structures/Invite.d.ts +132 -0
- package/lib/Discord/structures/Invite.js +240 -0
- package/lib/Discord/structures/InviteGuild.cjs +130 -0
- package/lib/Discord/structures/InviteGuild.d.ts +54 -0
- package/lib/Discord/structures/InviteGuild.js +130 -0
- package/lib/Discord/structures/InviteRole.cjs +110 -0
- package/lib/Discord/structures/InviteRole.d.ts +53 -0
- package/lib/Discord/structures/InviteRole.js +110 -0
- package/lib/Discord/structures/Lobby.cjs +88 -0
- package/lib/Discord/structures/Lobby.d.ts +54 -0
- package/lib/Discord/structures/Lobby.js +88 -0
- package/lib/Discord/structures/LobbyMember.cjs +33 -0
- package/lib/Discord/structures/LobbyMember.d.ts +15 -0
- package/lib/Discord/structures/LobbyMember.js +33 -0
- package/lib/Discord/structures/MediaChannel.cjs +20 -0
- package/lib/Discord/structures/MediaChannel.d.ts +11 -0
- package/lib/Discord/structures/MediaChannel.js +20 -0
- package/lib/Discord/structures/Member.cjs +325 -0
- package/lib/Discord/structures/Member.d.ts +140 -0
- package/lib/Discord/structures/Member.js +325 -0
- package/lib/Discord/structures/Message.cjs +627 -0
- package/lib/Discord/structures/Message.d.ts +223 -0
- package/lib/Discord/structures/Message.js +627 -0
- package/lib/Discord/structures/ModalSubmitInteraction.cjs +295 -0
- package/lib/Discord/structures/ModalSubmitInteraction.d.ts +138 -0
- package/lib/Discord/structures/ModalSubmitInteraction.js +295 -0
- package/lib/Discord/structures/OAuthApplication.cjs +244 -0
- package/lib/Discord/structures/OAuthApplication.d.ts +77 -0
- package/lib/Discord/structures/OAuthApplication.js +244 -0
- package/lib/Discord/structures/OAuthGuild.cjs +107 -0
- package/lib/Discord/structures/OAuthGuild.d.ts +43 -0
- package/lib/Discord/structures/OAuthGuild.js +107 -0
- package/lib/Discord/structures/PartialApplication.cjs +101 -0
- package/lib/Discord/structures/PartialApplication.d.ts +29 -0
- package/lib/Discord/structures/PartialApplication.js +101 -0
- package/lib/Discord/structures/Permission.cjs +66 -0
- package/lib/Discord/structures/Permission.d.ts +21 -0
- package/lib/Discord/structures/Permission.js +66 -0
- package/lib/Discord/structures/PermissionOverwrite.cjs +50 -0
- package/lib/Discord/structures/PermissionOverwrite.d.ts +25 -0
- package/lib/Discord/structures/PermissionOverwrite.js +50 -0
- package/lib/Discord/structures/PingInteraction.cjs +27 -0
- package/lib/Discord/structures/PingInteraction.d.ts +15 -0
- package/lib/Discord/structures/PingInteraction.js +27 -0
- package/lib/Discord/structures/Poll.cjs +77 -0
- package/lib/Discord/structures/Poll.d.ts +27 -0
- package/lib/Discord/structures/Poll.js +77 -0
- package/lib/Discord/structures/PrimaryGuild.cjs +92 -0
- package/lib/Discord/structures/PrimaryGuild.d.ts +23 -0
- package/lib/Discord/structures/PrimaryGuild.js +92 -0
- package/lib/Discord/structures/PrivateChannel.cjs +139 -0
- package/lib/Discord/structures/PrivateChannel.d.ts +102 -0
- package/lib/Discord/structures/PrivateChannel.js +139 -0
- package/lib/Discord/structures/PrivateThreadChannel.cjs +28 -0
- package/lib/Discord/structures/PrivateThreadChannel.d.ts +17 -0
- package/lib/Discord/structures/PrivateThreadChannel.js +28 -0
- package/lib/Discord/structures/PublicThreadChannel.cjs +38 -0
- package/lib/Discord/structures/PublicThreadChannel.d.ts +20 -0
- package/lib/Discord/structures/PublicThreadChannel.js +38 -0
- package/lib/Discord/structures/Role.cjs +156 -0
- package/lib/Discord/structures/Role.d.ts +56 -0
- package/lib/Discord/structures/Role.js +156 -0
- package/lib/Discord/structures/SKU.cjs +70 -0
- package/lib/Discord/structures/SKU.d.ts +33 -0
- package/lib/Discord/structures/SKU.js +70 -0
- package/lib/Discord/structures/Soundboard.cjs +74 -0
- package/lib/Discord/structures/Soundboard.d.ts +42 -0
- package/lib/Discord/structures/Soundboard.js +74 -0
- package/lib/Discord/structures/StageChannel.cjs +45 -0
- package/lib/Discord/structures/StageChannel.d.ts +31 -0
- package/lib/Discord/structures/StageChannel.js +45 -0
- package/lib/Discord/structures/StageInstance.cjs +95 -0
- package/lib/Discord/structures/StageInstance.d.ts +35 -0
- package/lib/Discord/structures/StageInstance.js +95 -0
- package/lib/Discord/structures/Subscription.cjs +39 -0
- package/lib/Discord/structures/Subscription.d.ts +25 -0
- package/lib/Discord/structures/Subscription.js +39 -0
- package/lib/Discord/structures/Team.cjs +86 -0
- package/lib/Discord/structures/Team.d.ts +28 -0
- package/lib/Discord/structures/Team.js +86 -0
- package/lib/Discord/structures/TestEntitlement.cjs +22 -0
- package/lib/Discord/structures/TestEntitlement.d.ts +10 -0
- package/lib/Discord/structures/TestEntitlement.js +22 -0
- package/lib/Discord/structures/TextChannel.cjs +48 -0
- package/lib/Discord/structures/TextChannel.d.ts +34 -0
- package/lib/Discord/structures/TextChannel.js +48 -0
- package/lib/Discord/structures/TextableChannel.cjs +281 -0
- package/lib/Discord/structures/TextableChannel.d.ts +167 -0
- package/lib/Discord/structures/TextableChannel.js +281 -0
- package/lib/Discord/structures/TextableVoiceChannel.cjs +79 -0
- package/lib/Discord/structures/TextableVoiceChannel.d.ts +34 -0
- package/lib/Discord/structures/TextableVoiceChannel.js +79 -0
- package/lib/Discord/structures/ThreadChannel.cjs +300 -0
- package/lib/Discord/structures/ThreadChannel.d.ts +170 -0
- package/lib/Discord/structures/ThreadChannel.js +300 -0
- package/lib/Discord/structures/ThreadOnlyChannel.cjs +231 -0
- package/lib/Discord/structures/ThreadOnlyChannel.d.ts +95 -0
- package/lib/Discord/structures/ThreadOnlyChannel.js +231 -0
- package/lib/Discord/structures/ThreadableChannel.cjs +59 -0
- package/lib/Discord/structures/ThreadableChannel.d.ts +35 -0
- package/lib/Discord/structures/ThreadableChannel.js +59 -0
- package/lib/Discord/structures/UnavailableGuild.cjs +22 -0
- package/lib/Discord/structures/UnavailableGuild.d.ts +10 -0
- package/lib/Discord/structures/UnavailableGuild.js +22 -0
- package/lib/Discord/structures/User.cjs +240 -0
- package/lib/Discord/structures/User.d.ts +90 -0
- package/lib/Discord/structures/User.js +240 -0
- package/lib/Discord/structures/VoiceChannel.cjs +36 -0
- package/lib/Discord/structures/VoiceChannel.d.ts +19 -0
- package/lib/Discord/structures/VoiceChannel.js +36 -0
- package/lib/Discord/structures/VoiceState.cjs +141 -0
- package/lib/Discord/structures/VoiceState.d.ts +49 -0
- package/lib/Discord/structures/VoiceState.js +141 -0
- package/lib/Discord/structures/Webhook.cjs +240 -0
- package/lib/Discord/structures/Webhook.d.ts +126 -0
- package/lib/Discord/structures/Webhook.js +240 -0
- package/lib/Discord/types/applications.d.ts +695 -0
- package/lib/Discord/types/audit-log.d.ts +116 -0
- package/lib/Discord/types/auto-moderation.d.ts +99 -0
- package/lib/Discord/types/channels.d.ts +1570 -0
- package/lib/Discord/types/client.d.ts +250 -0
- package/lib/Discord/types/events.d.ts +224 -0
- package/lib/Discord/types/gateway-raw.d.ts +585 -0
- package/lib/Discord/types/gateway.d.ts +401 -0
- package/lib/Discord/types/guild-template.d.ts +25 -0
- package/lib/Discord/types/guilds.d.ts +987 -0
- package/lib/Discord/types/index.d.ts +24 -0
- package/lib/Discord/types/interactions.d.ts +524 -0
- package/lib/Discord/types/invites.d.ts +117 -0
- package/lib/Discord/types/json.d.ts +833 -0
- package/lib/Discord/types/lobbies.d.ts +31 -0
- package/lib/Discord/types/misc.d.ts +25 -0
- package/lib/Discord/types/namespaced.d.ts +22 -0
- package/lib/Discord/types/oauth.d.ts +206 -0
- package/lib/Discord/types/request-handler.d.ts +54 -0
- package/lib/Discord/types/scheduled-events.d.ts +87 -0
- package/lib/Discord/types/shared.d.ts +24 -0
- package/lib/Discord/types/users.d.ts +104 -0
- package/lib/Discord/types/voice.d.ts +45 -0
- package/lib/Discord/types/webhooks.d.ts +75 -0
- package/lib/Discord/util/Collection.cjs +77 -0
- package/lib/Discord/util/Collection.d.ts +47 -0
- package/lib/Discord/util/Collection.js +77 -0
- package/lib/Discord/util/Errors.cjs +84 -0
- package/lib/Discord/util/Errors.d.ts +43 -0
- package/lib/Discord/util/Errors.js +84 -0
- package/lib/Discord/util/QueryBuilder.cjs +20 -0
- package/lib/Discord/util/QueryBuilder.d.ts +4 -0
- package/lib/Discord/util/QueryBuilder.js +20 -0
- package/lib/Discord/util/Routes.cjs +293 -0
- package/lib/Discord/util/Routes.d.ts +145 -0
- package/lib/Discord/util/Routes.js +293 -0
- package/lib/Discord/util/SimpleCollection.cjs +82 -0
- package/lib/Discord/util/SimpleCollection.d.ts +12 -0
- package/lib/Discord/util/SimpleCollection.js +82 -0
- package/lib/Discord/util/Time.cjs +93 -0
- package/lib/Discord/util/Time.d.ts +39 -0
- package/lib/Discord/util/Time.js +93 -0
- package/lib/Discord/util/TypedCollection.cjs +81 -0
- package/lib/Discord/util/TypedCollection.d.ts +24 -0
- package/lib/Discord/util/TypedCollection.js +81 -0
- package/lib/Discord/util/TypedEmitter.cjs +20 -0
- package/lib/Discord/util/TypedEmitter.d.ts +18 -0
- package/lib/Discord/util/TypedEmitter.js +20 -0
- package/lib/Discord/util/Util.cjs +906 -0
- package/lib/Discord/util/Util.d.ts +66 -0
- package/lib/Discord/util/Util.js +906 -0
- package/lib/Discord/util/interactions/InteractionOptionsWrapper.cjs +211 -0
- package/lib/Discord/util/interactions/InteractionOptionsWrapper.d.ts +170 -0
- package/lib/Discord/util/interactions/InteractionOptionsWrapper.js +211 -0
- package/lib/Discord/util/interactions/MessageInteractionResponse.cjs +29 -0
- package/lib/Discord/util/interactions/MessageInteractionResponse.d.ts +27 -0
- package/lib/Discord/util/interactions/MessageInteractionResponse.js +29 -0
- package/lib/Discord/util/interactions/ModalSubmitInteractionComponentsWrapper.cjs +101 -0
- package/lib/Discord/util/interactions/ModalSubmitInteractionComponentsWrapper.d.ts +157 -0
- package/lib/Discord/util/interactions/ModalSubmitInteractionComponentsWrapper.js +101 -0
- package/lib/Discord/util/interactions/SelectMenuValuesWrapper.cjs +81 -0
- package/lib/Discord/util/interactions/SelectMenuValuesWrapper.d.ts +59 -0
- package/lib/Discord/util/interactions/SelectMenuValuesWrapper.js +81 -0
- package/lib/Discord/util/interactions/shared.cjs +20 -0
- package/lib/Discord/util/interactions/shared.d.ts +7 -0
- package/lib/Discord/util/interactions/shared.js +20 -0
- package/lib/Discord/util/warning.cjs +34 -0
- package/lib/Discord/util/warning.d.ts +6 -0
- package/lib/Discord/util/warning.js +34 -0
- package/lib/Signal/Group/ciphertext-message.d.ts +10 -0
- package/lib/Signal/Group/ciphertext-message.d.ts.map +1 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/ciphertext-message.js.map +1 -0
- package/lib/Signal/Group/group-session-builder.d.ts +8 -0
- package/lib/Signal/Group/group-session-builder.d.ts.map +1 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group-session-builder.js.map +1 -0
- package/lib/Signal/Group/group_cipher.d.ts +11 -0
- package/lib/Signal/Group/group_cipher.d.ts.map +1 -0
- package/lib/Signal/Group/group_cipher.js +82 -0
- package/lib/Signal/Group/group_cipher.js.map +1 -0
- package/lib/Signal/Group/index.d.ts +12 -0
- package/lib/Signal/Group/index.d.ts.map +1 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/index.js.map +1 -0
- package/lib/Signal/Group/keyhelper.d.ts +7 -0
- package/lib/Signal/Group/keyhelper.d.ts.map +1 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/lib/Signal/Group/keyhelper.js.map +1 -0
- package/lib/Signal/Group/sender-chain-key.d.ts +14 -0
- package/lib/Signal/Group/sender-chain-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-chain-key.js +26 -0
- package/lib/Signal/Group/sender-chain-key.js.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts +17 -0
- package/lib/Signal/Group/sender-key-distribution-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-distribution-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-message.d.ts +19 -0
- package/lib/Signal/Group/sender-key-message.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-message.js +66 -0
- package/lib/Signal/Group/sender-key-message.js.map +1 -0
- package/lib/Signal/Group/sender-key-name.d.ts +12 -0
- package/lib/Signal/Group/sender-key-name.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-name.js.map +1 -0
- package/lib/Signal/Group/sender-key-record.d.ts +13 -0
- package/lib/Signal/Group/sender-key-record.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-record.js +41 -0
- package/lib/Signal/Group/sender-key-record.js.map +1 -0
- package/lib/Signal/Group/sender-key-state.d.ts +17 -0
- package/lib/Signal/Group/sender-key-state.d.ts.map +1 -0
- package/lib/Signal/Group/sender-key-state.js +84 -0
- package/lib/Signal/Group/sender-key-state.js.map +1 -0
- package/lib/Signal/Group/sender-message-key.d.ts +12 -0
- package/lib/Signal/Group/sender-message-key.d.ts.map +1 -0
- package/lib/Signal/Group/sender-message-key.js +26 -0
- package/lib/Signal/Group/sender-message-key.js.map +1 -0
- package/lib/Signal/libsignal.d.ts +55 -0
- package/lib/Signal/libsignal.d.ts.map +1 -0
- package/lib/Signal/libsignal.js +431 -0
- package/lib/Signal/libsignal.js.map +1 -0
- package/lib/Signal/lid-mapping.d.ts +21 -0
- package/lib/Signal/lid-mapping.d.ts.map +1 -0
- package/lib/Signal/lid-mapping.js +277 -0
- package/lib/Signal/lid-mapping.js.map +1 -0
- package/lib/Socket/Client/index.d.ts +3 -0
- package/lib/Socket/Client/index.d.ts.map +1 -0
- package/lib/Socket/Client/index.js +3 -0
- package/lib/Socket/Client/index.js.map +1 -0
- package/lib/Socket/Client/types.d.ts +6 -0
- package/lib/Socket/Client/types.d.ts.map +1 -0
- package/lib/Socket/Client/types.js +11 -0
- package/lib/Socket/Client/types.js.map +1 -0
- package/lib/Socket/Client/websocket.d.ts +13 -0
- package/lib/Socket/Client/websocket.d.ts.map +1 -0
- package/lib/Socket/Client/websocket.js +54 -0
- package/lib/Socket/Client/websocket.js.map +1 -0
- package/lib/Socket/business.d.ts +395 -0
- package/lib/Socket/business.d.ts.map +1 -0
- package/lib/Socket/business.js +380 -0
- package/lib/Socket/business.js.map +1 -0
- package/lib/Socket/chats.d.ts +137 -0
- package/lib/Socket/chats.d.ts.map +1 -0
- package/lib/Socket/chats.js +1214 -0
- package/lib/Socket/chats.js.map +1 -0
- package/lib/Socket/communities.d.ts +562 -0
- package/lib/Socket/communities.d.ts.map +1 -0
- package/lib/Socket/communities.js +432 -0
- package/lib/Socket/communities.js.map +1 -0
- package/lib/Socket/groups.d.ts +286 -0
- package/lib/Socket/groups.d.ts.map +1 -0
- package/lib/Socket/groups.js +348 -0
- package/lib/Socket/groups.js.map +1 -0
- package/lib/Socket/index.d.ts +530 -0
- package/lib/Socket/index.d.ts.map +1 -0
- package/lib/Socket/index.js +12 -0
- package/lib/Socket/index.js.map +1 -0
- package/lib/Socket/messages-recv.d.ts +334 -0
- package/lib/Socket/messages-recv.d.ts.map +1 -0
- package/lib/Socket/messages-recv.js +1765 -0
- package/lib/Socket/messages-recv.js.map +1 -0
- package/lib/Socket/messages-send.d.ts +330 -0
- package/lib/Socket/messages-send.d.ts.map +1 -0
- package/lib/Socket/messages-send.js +1368 -0
- package/lib/Socket/messages-send.js.map +1 -0
- package/lib/Socket/mex.d.ts +2 -0
- package/lib/Socket/mex.d.ts.map +1 -0
- package/lib/Socket/mex.js +42 -0
- package/lib/Socket/mex.js.map +1 -0
- package/lib/Socket/newsletter.d.ts +283 -0
- package/lib/Socket/newsletter.d.ts.map +1 -0
- package/lib/Socket/newsletter.js +226 -0
- package/lib/Socket/newsletter.js.map +1 -0
- package/lib/Socket/socket.d.ts +61 -0
- package/lib/Socket/socket.d.ts.map +1 -0
- package/lib/Socket/socket.js +972 -0
- package/lib/Socket/socket.js.map +1 -0
- package/lib/Store/index.d.ts +4 -0
- package/lib/Store/index.d.ts.map +1 -0
- package/lib/Store/index.js +4 -0
- package/lib/Store/index.js.map +1 -0
- package/lib/Store/make-in-memory-store.d.ts +63 -0
- package/lib/Store/make-in-memory-store.d.ts.map +1 -0
- package/lib/Store/make-in-memory-store.js +471 -0
- package/lib/Store/make-in-memory-store.js.map +1 -0
- package/lib/Store/make-ordered-dictionary.d.ts +13 -0
- package/lib/Store/make-ordered-dictionary.d.ts.map +1 -0
- package/lib/Store/make-ordered-dictionary.js +79 -0
- package/lib/Store/make-ordered-dictionary.js.map +1 -0
- package/lib/Store/object-repository.d.ts +11 -0
- package/lib/Store/object-repository.d.ts.map +1 -0
- package/lib/Store/object-repository.js +24 -0
- package/lib/Store/object-repository.js.map +1 -0
- package/lib/Telegram/button.js +147 -0
- package/lib/Telegram/cli.mjs +105 -0
- package/lib/Telegram/composer.js +582 -0
- package/lib/Telegram/context.js +855 -0
- package/lib/Telegram/core/helpers/args.js +57 -0
- package/lib/Telegram/core/helpers/check.js +55 -0
- package/lib/Telegram/core/helpers/compact.js +16 -0
- package/lib/Telegram/core/helpers/deunionize.js +12 -0
- package/lib/Telegram/core/helpers/formatting.js +91 -0
- package/lib/Telegram/core/helpers/util.js +50 -0
- package/lib/Telegram/core/network/client.js +330 -0
- package/lib/Telegram/core/network/error.js +21 -0
- package/lib/Telegram/core/network/multipart-stream.js +71 -0
- package/lib/Telegram/core/network/polling.js +87 -0
- package/lib/Telegram/core/network/webhook.js +54 -0
- package/lib/Telegram/core/types/typegram.js +27 -0
- package/lib/Telegram/elynn-telegraf.js +256 -0
- package/lib/Telegram/esm-bridge.mjs +21 -0
- package/lib/Telegram/filters.js +69 -0
- package/lib/Telegram/format.js +58 -0
- package/lib/Telegram/future.js +140 -0
- package/lib/Telegram/index.js +59 -0
- package/lib/Telegram/input.js +61 -0
- package/lib/Telegram/markup.js +121 -0
- package/lib/Telegram/middleware.js +2 -0
- package/lib/Telegram/package.json +3 -0
- package/lib/Telegram/reactions.js +84 -0
- package/lib/Telegram/router.js +46 -0
- package/lib/Telegram/scenes/base.js +39 -0
- package/lib/Telegram/scenes/context.js +104 -0
- package/lib/Telegram/scenes/index.js +21 -0
- package/lib/Telegram/scenes/stage.js +49 -0
- package/lib/Telegram/scenes/wizard/context.js +31 -0
- package/lib/Telegram/scenes/wizard/index.js +45 -0
- package/lib/Telegram/scenes.js +17 -0
- package/lib/Telegram/session.js +166 -0
- package/lib/Telegram/telegram-types.js +6 -0
- package/lib/Telegram/telegram.js +945 -0
- package/lib/Telegram/types.js +2 -0
- package/lib/Telegram/utils.js +5 -0
- package/lib/Types/Auth.d.ts +2 -0
- package/lib/Types/Auth.d.ts.map +1 -0
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Auth.js.map +1 -0
- package/lib/Types/Bussines.d.ts +2 -0
- package/lib/Types/Bussines.d.ts.map +1 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Bussines.js.map +1 -0
- package/lib/Types/Call.d.ts +2 -0
- package/lib/Types/Call.d.ts.map +1 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Call.js.map +1 -0
- package/lib/Types/Chat.d.ts +2 -0
- package/lib/Types/Chat.d.ts.map +1 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Chat.js.map +1 -0
- package/lib/Types/Contact.d.ts +2 -0
- package/lib/Types/Contact.d.ts.map +1 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Contact.js.map +1 -0
- package/lib/Types/Events.d.ts +2 -0
- package/lib/Types/Events.d.ts.map +1 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/Events.js.map +1 -0
- package/lib/Types/GroupMetadata.d.ts +2 -0
- package/lib/Types/GroupMetadata.d.ts.map +1 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/GroupMetadata.js.map +1 -0
- package/lib/Types/Label.d.ts +3 -0
- package/lib/Types/Label.d.ts.map +1 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/Label.js.map +1 -0
- package/lib/Types/LabelAssociation.d.ts +3 -0
- package/lib/Types/LabelAssociation.d.ts.map +1 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/LabelAssociation.js.map +1 -0
- package/lib/Types/Message.d.ts +12 -0
- package/lib/Types/Message.d.ts.map +1 -0
- package/lib/Types/Message.js +18 -0
- package/lib/Types/Message.js.map +1 -0
- package/lib/Types/Mex.d.ts +3 -0
- package/lib/Types/Mex.d.ts.map +1 -0
- package/lib/Types/Mex.js +39 -0
- package/lib/Types/Mex.js.map +1 -0
- package/lib/Types/Product.d.ts +2 -0
- package/lib/Types/Product.d.ts.map +1 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Product.js.map +1 -0
- package/lib/Types/RichType.d.ts +3 -0
- package/lib/Types/RichType.d.ts.map +1 -0
- package/lib/Types/RichType.js +23 -0
- package/lib/Types/RichType.js.map +1 -0
- package/lib/Types/Signal.d.ts +2 -0
- package/lib/Types/Signal.d.ts.map +1 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Signal.js.map +1 -0
- package/lib/Types/Socket.d.ts +2 -0
- package/lib/Types/Socket.d.ts.map +1 -0
- package/lib/Types/Socket.js +2 -0
- package/lib/Types/Socket.js.map +1 -0
- package/lib/Types/State.d.ts +6 -0
- package/lib/Types/State.d.ts.map +1 -0
- package/lib/Types/State.js +56 -0
- package/lib/Types/State.js.map +1 -0
- package/lib/Types/USync.d.ts +2 -0
- package/lib/Types/USync.d.ts.map +1 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/USync.js.map +1 -0
- package/lib/Types/index.d.ts +14 -0
- package/lib/Types/index.d.ts.map +1 -0
- package/lib/Types/index.js +26 -0
- package/lib/Types/index.js.map +1 -0
- package/lib/Utils/auth-utils.d.ts +58 -0
- package/lib/Utils/auth-utils.d.ts.map +1 -0
- package/lib/Utils/auth-utils.js +302 -0
- package/lib/Utils/auth-utils.js.map +1 -0
- package/lib/Utils/browser-utils.d.ts +9 -0
- package/lib/Utils/browser-utils.d.ts.map +1 -0
- package/lib/Utils/browser-utils.js +36 -0
- package/lib/Utils/browser-utils.js.map +1 -0
- package/lib/Utils/business.d.ts +50 -0
- package/lib/Utils/business.d.ts.map +1 -0
- package/lib/Utils/business.js +231 -0
- package/lib/Utils/business.js.map +1 -0
- package/lib/Utils/chat-utils.d.ts +409 -0
- package/lib/Utils/chat-utils.d.ts.map +1 -0
- package/lib/Utils/chat-utils.js +872 -0
- package/lib/Utils/chat-utils.js.map +1 -0
- package/lib/Utils/companion-reg-client-utils.d.ts +5 -0
- package/lib/Utils/companion-reg-client-utils.d.ts.map +1 -0
- package/lib/Utils/companion-reg-client-utils.js +46 -0
- package/lib/Utils/companion-reg-client-utils.js.map +1 -0
- package/lib/Utils/crypto.d.ts +40 -0
- package/lib/Utils/crypto.d.ts.map +1 -0
- package/lib/Utils/crypto.js +119 -0
- package/lib/Utils/crypto.js.map +1 -0
- package/lib/Utils/decode-wa-message.d.ts +84 -0
- package/lib/Utils/decode-wa-message.d.ts.map +1 -0
- package/lib/Utils/decode-wa-message.js +325 -0
- package/lib/Utils/decode-wa-message.js.map +1 -0
- package/lib/Utils/event-buffer.d.ts +13 -0
- package/lib/Utils/event-buffer.d.ts.map +1 -0
- package/lib/Utils/event-buffer.js +622 -0
- package/lib/Utils/event-buffer.js.map +1 -0
- package/lib/Utils/generics.d.ts +64 -0
- package/lib/Utils/generics.d.ts.map +1 -0
- package/lib/Utils/generics.js +395 -0
- package/lib/Utils/generics.js.map +1 -0
- package/lib/Utils/history.d.ts +76 -0
- package/lib/Utils/history.d.ts.map +1 -0
- package/lib/Utils/history.js +134 -0
- package/lib/Utils/history.js.map +1 -0
- package/lib/Utils/identity-change-handler.d.ts +14 -0
- package/lib/Utils/identity-change-handler.d.ts.map +1 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/identity-change-handler.js.map +1 -0
- package/lib/Utils/index.d.ts +25 -0
- package/lib/Utils/index.d.ts.map +1 -0
- package/lib/Utils/index.js +27 -0
- package/lib/Utils/index.js.map +1 -0
- package/lib/Utils/link-preview.d.ts +13 -0
- package/lib/Utils/link-preview.d.ts.map +1 -0
- package/lib/Utils/link-preview.js +85 -0
- package/lib/Utils/link-preview.js.map +1 -0
- package/lib/Utils/logger.d.ts +3 -0
- package/lib/Utils/logger.d.ts.map +1 -0
- package/lib/Utils/logger.js +3 -0
- package/lib/Utils/logger.js.map +1 -0
- package/lib/Utils/lt-hash.d.ts +7 -0
- package/lib/Utils/lt-hash.d.ts.map +1 -0
- package/lib/Utils/lt-hash.js +8 -0
- package/lib/Utils/lt-hash.js.map +1 -0
- package/lib/Utils/make-mutex.d.ts +7 -0
- package/lib/Utils/make-mutex.d.ts.map +1 -0
- package/lib/Utils/make-mutex.js +33 -0
- package/lib/Utils/make-mutex.js.map +1 -0
- package/lib/Utils/message-retry-manager.d.ts +80 -0
- package/lib/Utils/message-retry-manager.d.ts.map +1 -0
- package/lib/Utils/message-retry-manager.js +265 -0
- package/lib/Utils/message-retry-manager.js.map +1 -0
- package/lib/Utils/messages-media.d.ts +137 -0
- package/lib/Utils/messages-media.d.ts.map +1 -0
- package/lib/Utils/messages-media.js +843 -0
- package/lib/Utils/messages-media.js.map +1 -0
- package/lib/Utils/messages.d.ts +46 -0
- package/lib/Utils/messages.d.ts.map +1 -0
- package/lib/Utils/messages.js +1878 -0
- package/lib/Utils/messages.js.map +1 -0
- package/lib/Utils/noise-handler.d.ts +21 -0
- package/lib/Utils/noise-handler.d.ts.map +1 -0
- package/lib/Utils/noise-handler.js +201 -0
- package/lib/Utils/noise-handler.js.map +1 -0
- package/lib/Utils/offline-node-processor.d.ts +10 -0
- package/lib/Utils/offline-node-processor.d.ts.map +1 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/offline-node-processor.js.map +1 -0
- package/lib/Utils/pre-key-manager.d.ts +26 -0
- package/lib/Utils/pre-key-manager.d.ts.map +1 -0
- package/lib/Utils/pre-key-manager.js +106 -0
- package/lib/Utils/pre-key-manager.js.map +1 -0
- package/lib/Utils/process-message.d.ts +84 -0
- package/lib/Utils/process-message.d.ts.map +1 -0
- package/lib/Utils/process-message.js +745 -0
- package/lib/Utils/process-message.js.map +1 -0
- package/lib/Utils/reporting-utils.d.ts +13 -0
- package/lib/Utils/reporting-utils.d.ts.map +1 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/reporting-utils.js.map +1 -0
- package/lib/Utils/rich-message-utils.d.ts +49 -0
- package/lib/Utils/rich-message-utils.d.ts.map +1 -0
- package/lib/Utils/rich-message-utils.js +400 -0
- package/lib/Utils/rich-message-utils.js.map +1 -0
- package/lib/Utils/session-guard.js +148 -0
- package/lib/Utils/signal.d.ts +83 -0
- package/lib/Utils/signal.d.ts.map +1 -0
- package/lib/Utils/signal.js +201 -0
- package/lib/Utils/signal.js.map +1 -0
- package/lib/Utils/stanza-ack.d.ts +17 -0
- package/lib/Utils/stanza-ack.d.ts.map +1 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/stanza-ack.js.map +1 -0
- package/lib/Utils/sync-action-utils.d.ts +3 -0
- package/lib/Utils/sync-action-utils.d.ts.map +1 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/sync-action-utils.js.map +1 -0
- package/lib/Utils/tc-token-utils.d.ts +30 -0
- package/lib/Utils/tc-token-utils.d.ts.map +1 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/Utils/tc-token-utils.js.map +1 -0
- package/lib/Utils/text-sticker.js +149 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts +11 -0
- package/lib/Utils/use-multi-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-multi-file-auth-state.js +121 -0
- package/lib/Utils/use-multi-file-auth-state.js.map +1 -0
- package/lib/Utils/use-single-file-auth-state.d.ts +11 -0
- package/lib/Utils/use-single-file-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-single-file-auth-state.js +109 -0
- package/lib/Utils/use-single-file-auth-state.js.map +1 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts +11 -0
- package/lib/Utils/use-sqlite-auth-state.d.ts.map +1 -0
- package/lib/Utils/use-sqlite-auth-state.js +109 -0
- package/lib/Utils/use-sqlite-auth-state.js.map +1 -0
- package/lib/Utils/validate-connection.d.ts +44 -0
- package/lib/Utils/validate-connection.d.ts.map +1 -0
- package/lib/Utils/validate-connection.js +203 -0
- package/lib/Utils/validate-connection.js.map +1 -0
- package/lib/WABinary/constants.d.ts +62 -0
- package/lib/WABinary/constants.d.ts.map +1 -0
- package/lib/WABinary/constants.js +1467 -0
- package/lib/WABinary/constants.js.map +1 -0
- package/lib/WABinary/decode.d.ts +10 -0
- package/lib/WABinary/decode.d.ts.map +1 -0
- package/lib/WABinary/decode.js +262 -0
- package/lib/WABinary/decode.js.map +1 -0
- package/lib/WABinary/encode.d.ts +3 -0
- package/lib/WABinary/encode.d.ts.map +1 -0
- package/lib/WABinary/encode.js +220 -0
- package/lib/WABinary/encode.js.map +1 -0
- package/lib/WABinary/generic-utils.d.ts +77 -0
- package/lib/WABinary/generic-utils.d.ts.map +1 -0
- package/lib/WABinary/generic-utils.js +226 -0
- package/lib/WABinary/generic-utils.js.map +1 -0
- package/lib/WABinary/index.d.ts +6 -0
- package/lib/WABinary/index.d.ts.map +1 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/index.js.map +1 -0
- package/lib/WABinary/jid-utils.d.ts +29 -0
- package/lib/WABinary/jid-utils.d.ts.map +1 -0
- package/lib/WABinary/jid-utils.js +96 -0
- package/lib/WABinary/jid-utils.js.map +1 -0
- package/lib/WABinary/types.d.ts +2 -0
- package/lib/WABinary/types.d.ts.map +1 -0
- package/lib/WABinary/types.js +2 -0
- package/lib/WABinary/types.js.map +1 -0
- package/lib/WAM/BinaryInfo.d.ts +8 -0
- package/lib/WAM/BinaryInfo.d.ts.map +1 -0
- package/lib/WAM/BinaryInfo.js +10 -0
- package/lib/WAM/BinaryInfo.js.map +1 -0
- package/lib/WAM/constants.d.ts +34927 -0
- package/lib/WAM/constants.d.ts.map +1 -0
- package/lib/WAM/constants.js +22853 -0
- package/lib/WAM/constants.js.map +1 -0
- package/lib/WAM/encode.d.ts +2 -0
- package/lib/WAM/encode.d.ts.map +1 -0
- package/lib/WAM/encode.js +150 -0
- package/lib/WAM/encode.js.map +1 -0
- package/lib/WAM/index.d.ts +4 -0
- package/lib/WAM/index.d.ts.map +1 -0
- package/lib/WAM/index.js +4 -0
- package/lib/WAM/index.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts +37 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts +23 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +54 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts +13 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts +13 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts +10 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts +39 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts +15 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js.map +1 -0
- package/lib/WAUSync/Protocols/index.d.ts +6 -0
- package/lib/WAUSync/Protocols/index.d.ts.map +1 -0
- package/lib/WAUSync/Protocols/index.js +6 -0
- package/lib/WAUSync/Protocols/index.js.map +1 -0
- package/lib/WAUSync/USyncQuery.d.ts +21 -0
- package/lib/WAUSync/USyncQuery.d.ts.map +1 -0
- package/lib/WAUSync/USyncQuery.js +98 -0
- package/lib/WAUSync/USyncQuery.js.map +1 -0
- package/lib/WAUSync/USyncUser.d.ts +17 -0
- package/lib/WAUSync/USyncUser.d.ts.map +1 -0
- package/lib/WAUSync/USyncUser.js +31 -0
- package/lib/WAUSync/USyncUser.js.map +1 -0
- package/lib/WAUSync/index.d.ts +4 -0
- package/lib/WAUSync/index.d.ts.map +1 -0
- package/lib/WAUSync/index.js +4 -0
- package/lib/WAUSync/index.js.map +1 -0
- package/lib/index.d.ts +201 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +314 -0
- package/lib/index.js.map +1 -0
- package/lib/plugins/loader.cjs +26 -0
- package/lib/plugins/loader.js +94 -0
- package/package.json +148 -0
package/README.md
ADDED
|
@@ -0,0 +1,2372 @@
|
|
|
1
|
+
<img src="https://i.ibb.co/xq4NzXq0/elynn28760176.png" width="100%" style="border-radius:12px" />
|
|
2
|
+
# ๐ elynn-baileys
|
|
3
|
+
Elynn Baileys adalah sebuah library WhatsApp Web API yang sangat kuat, stabil, dan telah ditingkatkan fungsionalitasnya โ kini juga dilengkapi engine Telegram Bot (`ElynnTelegraf`) **dan** Discord Client (`ElynnDiscord`) terintegrasi penuh dalam satu package yang sama. Library ini merupakan versi *enhanced* yang mendukung penuh protokol WhatsApp 2026 (View-Once Text, View-Once Voice Note, Community Events, Group Message History, Channel Polling, dll), dilengkapi plugin Brat/Bratvid bawaan, serta fungsi eksklusif `testMessage` untuk pengujian semua jenis pesan langsung di chat atau grup manapun. Dibangun secara khusus untuk lingkungan Node.js dengan format ECMAScript Modules (ESM).
|
|
4
|
+
## ๐ Table of Contents
|
|
5
|
+
|
|
6
|
+
- [1. ๐ฆ Installation](#1--installation)
|
|
7
|
+
- [2. โก Quick Start](#2--quick-start)
|
|
8
|
+
- [3. ๐ Auth State](#3--auth-state)
|
|
9
|
+
- [3.1 Multi File Auth State](#31-multi-file-auth-state)
|
|
10
|
+
- [3.2 Single File Auth State](#32-single-file-auth-state)
|
|
11
|
+
- [3.3 SQLite Auth State](#33-sqlite-auth-state)
|
|
12
|
+
- [4. ๐พ makeInMemoryStore](#4--makeinmemorystore)
|
|
13
|
+
- [5. ๐ฌ Sending Messages](#5--sending-messages)
|
|
14
|
+
- [5.1 Text Biasa](#51-text-biasa)
|
|
15
|
+
- [5.2 Text dengan Mention User](#52-text-dengan-mention-user)
|
|
16
|
+
- [5.3 Mention All](#53-mention-all)
|
|
17
|
+
- [5.4 Reply / Quote Message](#54-reply--quote-message)
|
|
18
|
+
- [5.5 Reaction](#55-reaction)
|
|
19
|
+
- [5.6 Image](#56-image)
|
|
20
|
+
- [5.7 Video](#57-video)
|
|
21
|
+
- [5.8 Audio](#58-audio)
|
|
22
|
+
- [5.9 Document](#59-document)
|
|
23
|
+
- [5.10 Sticker](#510-sticker)
|
|
24
|
+
- [5.11 Sticker Pack](#511-sticker-pack)
|
|
25
|
+
- [5.12 Contact / vCard](#512-contact--vcard)
|
|
26
|
+
- [5.13 Location](#513-location)
|
|
27
|
+
- [5.14 Live Location](#514-live-location)
|
|
28
|
+
- [5.15 Poll](#515-poll)
|
|
29
|
+
- [5.16 Album](#516-album)
|
|
30
|
+
- [5.17 Interactive โ Buttons (Native Flow)](#517-interactive--buttons-native-flow)
|
|
31
|
+
- [5.18 Interactive โ List](#518-interactive--list)
|
|
32
|
+
- [5.19 Interactive โ Image Header](#519-interactive--image-header)
|
|
33
|
+
- [5.20 Interactive sebagai Template](#520-interactive-sebagai-template)
|
|
34
|
+
- [5.21 Hydrated Template Button](#521-hydrated-template-button)
|
|
35
|
+
- [5.22 View Once](#522-view-once)
|
|
36
|
+
- [5.23 Ephemeral](#523-ephemeral)
|
|
37
|
+
- [5.24 Spoiler](#524-spoiler)
|
|
38
|
+
- [5.25 Group Status](#525-group-status)
|
|
39
|
+
- [5.26 External Ad Reply](#526-external-ad-reply)
|
|
40
|
+
- [5.27 Forward Pesan](#527-forward-pesan)
|
|
41
|
+
- [5.28 Pin Pesan](#528-pin-pesan)
|
|
42
|
+
- [5.29 Raw Message](#529-raw-message)
|
|
43
|
+
- [5.30 Group Invite Link](#530-group-invite-link)
|
|
44
|
+
- [5.31 Event dengan Reminder (fitur WA Januari 2026)](#531-event-dengan-reminder-fitur-wa-januari-2026)
|
|
45
|
+
- [5.32 Text Sticker (fitur WA Januari 2026)](#532-text-sticker-fitur-wa-januari-2026)
|
|
46
|
+
- [5.33 View-Once Text โ Teks Sekali Lihat (WA 2026)](#533-view-once-text--teks-sekali-lihat-wa-2026)
|
|
47
|
+
- [5.34 View-Once Voice Note โ Audio Sekali Dengar (WA 2026)](#534-view-once-voice-note--audio-sekali-dengar-wa-2026)
|
|
48
|
+
- [5.35 Community Event โ RSVP & Virtual Meeting Call (WA 2026)](#535-community-event--rsvp--virtual-meeting-call-wa-2026)
|
|
49
|
+
- [5.36 Group Message History Share (WA 2026)](#536-group-message-history-share-wa-2026)
|
|
50
|
+
- [5.37 Channel Poll โ Polling di Saluran/Channel (WA 2026)](#537-channel-poll--polling-di-saluranchannel-wa-2026)
|
|
51
|
+
- [5.38 Channel Voice Note (WA 2026)](#538-channel-voice-note-wa-2026)
|
|
52
|
+
- [6. ๐ค Rich Response Messages](#6--rich-response-messages)
|
|
53
|
+
- [6.1 Text Rich](#61-text-rich)
|
|
54
|
+
- [6.2 Code Block](#62-code-block)
|
|
55
|
+
- [6.3 Table](#63-table)
|
|
56
|
+
- [6.4 Inline Image](#64-inline-image)
|
|
57
|
+
- [6.5 Inline Link / Citation](#65-inline-link--citation)
|
|
58
|
+
- [6.6 Rich Response Kombinasi](#66-rich-response-kombinasi)
|
|
59
|
+
- [7. ๐ฅ Group Management](#7--group-management)
|
|
60
|
+
- [8. ๐ข Newsletter / Channel](#8--newsletter--channel)
|
|
61
|
+
- [9. ๐ก๏ธ Privacy & Profile](#9--privacy--profile)
|
|
62
|
+
- [10. ๐ก Handling Events](#10--handling-events)
|
|
63
|
+
- [11. ๐งฉ Elynn Plugins โ Brat & Bratvid](#11--elynn-plugins--brat--bratvid)
|
|
64
|
+
- [12. ๐ Read Messages & Presence](#12--read-messages--presence)
|
|
65
|
+
- [13. ๐๏ธ Delete / Edit Pesan](#13--delete--edit-pesan)
|
|
66
|
+
- [14. โ๏ธ Message Options Tambahan](#14--message-options-tambahan)
|
|
67
|
+
- [15. ๐ Browser Fingerprint (Kiwi, UC Browser, dll)](#15--browser-fingerprint-kiwi-uc-browser-dll)
|
|
68
|
+
- [16. ๐ค Telegram Bot (ElynnTelegraf)](#16--telegram-bot-elynntelegraf)
|
|
69
|
+
- [16.1 Setup Dasar & Long Polling](#161-setup-dasar--long-polling)
|
|
70
|
+
- [16.2 Setup via Webhook](#162-setup-via-webhook)
|
|
71
|
+
- [16.3 Inline Keyboard & Reply Keyboard](#163-inline-keyboard--reply-keyboard)
|
|
72
|
+
- [16.4 Session, Scenes & Wizard](#164-session-scenes--wizard)
|
|
73
|
+
- [16.5 Memanggil Elynn Plugins (Brat/Bratvid) dari Bot Telegram](#165-memanggil-elynn-plugins-bratbratvid-dari-bot-telegram)
|
|
74
|
+
- [16.6 Cek Koneksi Bot dengan connectTelegram](#166-cek-koneksi-bot-dengan-connecttelegram)
|
|
75
|
+
- [16.7 Bot API 9.3โ9.4 โ sendMessageDraft, Profile Photo Bot, Button Style & Icon](#167-bot-api-9394--sendmessagedraft-profile-photo-bot-button-style--icon)
|
|
76
|
+
- [16.8 Bot API 9.5 โ Member Tags, Date-Time Entity](#168-bot-api-95--member-tags-date-time-entity)
|
|
77
|
+
- [16.9 Bot API 9.6 โ Managed Bots](#169-bot-api-96--managed-bots)
|
|
78
|
+
- [16.10 Bot API 10.0 โ Guest Mode](#1610-bot-api-100--guest-mode)
|
|
79
|
+
- [16.11 Bot API 10.0 โ Bot-to-Bot Communication](#1611-bot-api-100--bot-to-bot-communication)
|
|
80
|
+
- [16.12 Bot API 10.0 โ Delete Reactions](#1612-bot-api-100--delete-reactions)
|
|
81
|
+
- [16.13 Bot API 10.0 โ Live Photo](#1613-bot-api-100--live-photo)
|
|
82
|
+
- [16.14 Bot API 10.0 โ Managed Bot Access Settings](#1614-bot-api-100--managed-bot-access-settings)
|
|
83
|
+
- [16.15 Bot API 10.0 โ Get User Personal Chat Messages](#1615-bot-api-100--get-user-personal-chat-messages)
|
|
84
|
+
- [16.16 Bot API 10.1 โ Join Request Queries](#1616-bot-api-101--join-request-queries)
|
|
85
|
+
- [16.17 Bot API 10.1 โ Rich Messages](#1617-bot-api-101--rich-messages)
|
|
86
|
+
- [17. ๐ฌ Discord Bot (ElynnDiscord)](#17--discord-bot-elynndiscord)
|
|
87
|
+
- [17.1 Setup Dasar & Login Bot](#171-setup-dasar--login-bot)
|
|
88
|
+
- [17.2 Menangani Event & Pesan](#172-menangani-event--pesan)
|
|
89
|
+
- [17.3 Slash Commands (Application Commands)](#173-slash-commands-application-commands)
|
|
90
|
+
- [17.4 Embed & File Upload](#174-embed--file-upload)
|
|
91
|
+
- [17.5 Sharding dengan ShardManager](#175-sharding-dengan-shardmanager)
|
|
92
|
+
- [17.6 Cek Koneksi Bot dengan connectDiscord](#176-cek-koneksi-bot-dengan-connectdiscord)
|
|
93
|
+
- [17.7 [NEW 2026] Granular Access Control (Invite API)](#177-new-2026-granular-access-control-invite-api)
|
|
94
|
+
- [17.8 [NEW 2026] Modals UI Components (Select Menus, Label, TextDisplay)](#178-new-2026-modals-ui-components-select-menus-label-textdisplay)
|
|
95
|
+
- [17.9 [NEW 2026] Server-Specific Bot Profiles (Per-Guild Profiles)](#179-new-2026-server-specific-bot-profiles-per-guild-profiles)
|
|
96
|
+
- [17.10 [NEW 2026] Threshold Intents (10k Users) & Moderation Metadata](#1710-new-2026-threshold-intents-10k-users--moderation-metadata)
|
|
97
|
+
- [18. ๐งช testMessage โ Tes Semua Jenis Pesan](#18--testmessage--tes-semua-jenis-pesan)
|
|
98
|
+
- [Cara import & penggunaan](#cara-import--penggunaan)
|
|
99
|
+
- [Signature lengkap](#signature-lengkap)
|
|
100
|
+
- [Yang diuji (16 jenis pesan)](#yang-diuji-16-jenis-pesan)
|
|
101
|
+
- [19. ๐ sessionGuard โ Proteksi Session dari Pencurian](#19--sessionguard--proteksi-session-dari-pencurian)
|
|
102
|
+
- [Cara Import](#cara-import)
|
|
103
|
+
- [Penggunaan Dasar](#penggunaan-dasar)
|
|
104
|
+
- [Opsi Lengkap](#opsi-lengkap)
|
|
105
|
+
- [Cara Kerja](#cara-kerja)
|
|
106
|
+
- [Cek Status Guard](#cek-status-guard)
|
|
107
|
+
- [Reset Guard (Pindah Server)](#reset-guard-pindah-server)
|
|
108
|
+
- [Contoh Output Log](#contoh-output-log)
|
|
109
|
+
- [โฆ Credits & License](#-credits--license)
|
|
110
|
+
|
|
111
|
+
## 1. ๐ฆ Installation
|
|
112
|
+
Anda dapat menginstal package ini menggunakan manajer paket Node.js favorit Anda. Package ini membutuhkan Node.js versi 18 ke atas.
|
|
113
|
+
```bash
|
|
114
|
+
npm install elynn-baileys
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
```bash
|
|
118
|
+
yarn add elynn-baileys
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
```bash
|
|
122
|
+
pnpm add elynn-baileys
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
Untuk memaksimalkan semua fitur yang ada, terutama fitur manipulasi media, integrasi database, dan sistem preview, Anda disarankan untuk menginstal peer dependencies opsional berikut ini secara bersamaan.
|
|
126
|
+
```bash
|
|
127
|
+
npm install sharp jimp @napi-rs/image audio-decode better-sqlite3 link-preview-js
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
## 2. โก Quick Start
|
|
131
|
+
Berikut adalah contoh lengkap cara melakukan inisialisasi koneksi ke WhatsApp. Kode ini menangani pembuatan socket, integrasi kredensial login, dan logika rekoneksi otomatis. Terdapat dua metode login: menggunakan Pairing Code atau QR Code.
|
|
132
|
+
```js
|
|
133
|
+
import pino from 'pino'
|
|
134
|
+
import { makeWASocket, useMultiFileAuthState, DisconnectReason, fetchLatestBaileysVersion, Browsers } from 'elynn-baileys'
|
|
135
|
+
|
|
136
|
+
async function connectToWhatsApp() {
|
|
137
|
+
const logger = pino({ level: 'silent' })
|
|
138
|
+
|
|
139
|
+
const { state, saveCreds } = await useMultiFileAuthState('./session-auth')
|
|
140
|
+
const { version, isLatest } = await fetchLatestBaileysVersion()
|
|
141
|
+
|
|
142
|
+
const usePairingCode = true
|
|
143
|
+
const phoneNumber = '6281234567890'
|
|
144
|
+
|
|
145
|
+
const sock = makeWASocket({
|
|
146
|
+
version: version,
|
|
147
|
+
logger: logger,
|
|
148
|
+
printQRInTerminal: !usePairingCode,
|
|
149
|
+
auth: state,
|
|
150
|
+
browser: Browsers.ubuntu('Chrome'), // bisa juga Browsers.kiwi(), Browsers.ucBrowser(), dll โ lihat Bab 15
|
|
151
|
+
markOnlineOnConnect: true,
|
|
152
|
+
generateHighQualityLinkPreview: true,
|
|
153
|
+
syncFullHistory: false
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
if (usePairingCode && !sock.authState.creds.registered) {
|
|
157
|
+
const code = await sock.requestPairingCode(phoneNumber)
|
|
158
|
+
console.log(`Pairing Code Anda: ${code}`)
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
sock.ev.on('creds.update', saveCreds)
|
|
162
|
+
|
|
163
|
+
sock.ev.on('connection.update', (update) => {
|
|
164
|
+
const { connection, lastDisconnect } = update
|
|
165
|
+
|
|
166
|
+
if (connection === 'close') {
|
|
167
|
+
const shouldReconnect = lastDisconnect.error?.output?.statusCode !== DisconnectReason.loggedOut
|
|
168
|
+
|
|
169
|
+
if (shouldReconnect) {
|
|
170
|
+
connectToWhatsApp()
|
|
171
|
+
} else {
|
|
172
|
+
console.log('Koneksi terputus dan sesi telah dihapus.')
|
|
173
|
+
}
|
|
174
|
+
} else if (connection === 'open') {
|
|
175
|
+
console.log('Koneksi berhasil dibuka dan WhatsApp siap digunakan.')
|
|
176
|
+
}
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
return sock
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
connectToWhatsApp()
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
## 3. ๐ Auth State
|
|
186
|
+
elynn-baileys menyediakan tiga jenis mekanisme penyimpanan status autentikasi yang dapat Anda pilih sesuai dengan infrastruktur aplikasi Anda.
|
|
187
|
+
### 3.1 Multi File Auth State
|
|
188
|
+
Menyimpan data kredensial dan keys dalam sebuah direktori yang berisi banyak file JSON. Sangat stabil dan direkomendasikan untuk penggunaan standar.
|
|
189
|
+
```js
|
|
190
|
+
import { useMultiFileAuthState } from 'elynn-baileys'
|
|
191
|
+
|
|
192
|
+
async function setupAuth() {
|
|
193
|
+
const { state, saveCreds } = await useMultiFileAuthState('./auth_info_baileys')
|
|
194
|
+
return { state, saveCreds }
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
### 3.2 Single File Auth State
|
|
199
|
+
Menyimpan seluruh data kredensial ke dalam satu file JSON tunggal. Mudah dipindahkan namun bisa menjadi sangat besar seiring waktu.
|
|
200
|
+
```js
|
|
201
|
+
import { useSingleFileAuthState } from 'elynn-baileys'
|
|
202
|
+
|
|
203
|
+
async function setupAuth() {
|
|
204
|
+
const { state, saveCreds } = await useSingleFileAuthState('./creds.json')
|
|
205
|
+
return { state, saveCreds }
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
### 3.3 SQLite Auth State
|
|
210
|
+
Menyimpan data autentikasi ke dalam database SQLite. Sangat cepat, hemat memori, dan sangat disarankan untuk produksi berskala besar.
|
|
211
|
+
```js
|
|
212
|
+
import { useSqliteAuthState } from 'elynn-baileys'
|
|
213
|
+
|
|
214
|
+
async function setupAuth() {
|
|
215
|
+
// Membutuhkan peer dependency: npm install better-sqlite3
|
|
216
|
+
const { state, saveCreds } = await useSqliteAuthState({ dbPath: './auth_database.db' })
|
|
217
|
+
return { state, saveCreds }
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
## 4. ๐พ makeInMemoryStore
|
|
222
|
+
makeInMemoryStore adalah sistem penyimpanan data sesi dalam memori yang ditingkatkan. Menyediakan caching cerdas untuk pesan, kontak, dan metadata grup.
|
|
223
|
+
Konfigurasi dan implementasi lengkap:
|
|
224
|
+
```js
|
|
225
|
+
import { makeInMemoryStore } from 'elynn-baileys'
|
|
226
|
+
import pino from 'pino'
|
|
227
|
+
|
|
228
|
+
const logger = pino({ level: 'silent' })
|
|
229
|
+
|
|
230
|
+
const store = makeInMemoryStore({
|
|
231
|
+
logger: logger,
|
|
232
|
+
maxMessages: Infinity,
|
|
233
|
+
presenceTTL: 300000
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
function setupStore(sock) {
|
|
237
|
+
store.bind(sock.ev)
|
|
238
|
+
|
|
239
|
+
store.on('onMessage', (message) => {
|
|
240
|
+
console.log(message)
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
store.on('onPresence', (presence) => {
|
|
244
|
+
console.log(presence)
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
store.on('onChat', (chat) => {
|
|
248
|
+
console.log(chat)
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
setInterval(() => {
|
|
252
|
+
store.writeToFile('./store_backup.json')
|
|
253
|
+
}, 10000)
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
async function useStoreFeatures(sock, jid, messageId) {
|
|
257
|
+
const stats = store.getStats()
|
|
258
|
+
|
|
259
|
+
const searchResults = await store.searchMessages('halo dunia', jid)
|
|
260
|
+
|
|
261
|
+
const allMessages = await store.loadAllMessages(jid)
|
|
262
|
+
|
|
263
|
+
const lastMessages = await store.loadLastMessages(jid, 20)
|
|
264
|
+
|
|
265
|
+
const allGroupMetadata = await store.fetchAllGroupMetadata(sock)
|
|
266
|
+
|
|
267
|
+
const isRead = store.isMessageRead(jid, messageId)
|
|
268
|
+
|
|
269
|
+
store.readFromFile('./store_backup.json')
|
|
270
|
+
|
|
271
|
+
store.clear()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
## 5. ๐ฌ Sending Messages
|
|
276
|
+
Seksi ini memuat seluruh metode dan struktur pengiriman pesan menggunakan library ini.
|
|
277
|
+
### 5.1 Text Biasa
|
|
278
|
+
```js
|
|
279
|
+
async function sendText(sock, jid) {
|
|
280
|
+
await sock.sendMessage(jid, {
|
|
281
|
+
text: 'Halo, ini adalah pesan teks biasa.'
|
|
282
|
+
})
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
```
|
|
286
|
+
### 5.2 Text dengan Mention User
|
|
287
|
+
```js
|
|
288
|
+
async function sendMention(sock, jid) {
|
|
289
|
+
await sock.sendMessage(jid, {
|
|
290
|
+
text: 'Halo @6281234567890, selamat datang di grup!',
|
|
291
|
+
mentions: ['6281234567890@s.whatsapp.net']
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
```
|
|
296
|
+
### 5.3 Mention All
|
|
297
|
+
```js
|
|
298
|
+
async function sendMentionAll(sock, jid) {
|
|
299
|
+
const meta = await sock.groupMetadata(jid)
|
|
300
|
+
await sock.sendMessage(jid, {
|
|
301
|
+
text: 'Pengumuman untuk seluruh anggota grup!',
|
|
302
|
+
mentionAll: true,
|
|
303
|
+
groupMetadata: meta
|
|
304
|
+
})
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
### 5.4 Reply / Quote Message
|
|
309
|
+
```js
|
|
310
|
+
async function sendReply(sock, jid, quotedMessage) {
|
|
311
|
+
await sock.sendMessage(jid, {
|
|
312
|
+
text: 'Ini adalah balasan dari pesan sebelumnya.',
|
|
313
|
+
quote: quotedMessage
|
|
314
|
+
})
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
```
|
|
318
|
+
### 5.5 Reaction
|
|
319
|
+
```js
|
|
320
|
+
async function sendReaction(sock, jid, messageKey) {
|
|
321
|
+
await sock.sendMessage(jid, {
|
|
322
|
+
react: {
|
|
323
|
+
text: '๐ฅ',
|
|
324
|
+
key: messageKey
|
|
325
|
+
}
|
|
326
|
+
})
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
```
|
|
330
|
+
### 5.6 Image
|
|
331
|
+
```js
|
|
332
|
+
import fs from 'fs'
|
|
333
|
+
|
|
334
|
+
async function sendImages(sock, jid) {
|
|
335
|
+
await sock.sendMessage(jid, {
|
|
336
|
+
image: { url: 'https://domain.com/gambar-bagus.jpg' },
|
|
337
|
+
caption: 'Ini adalah gambar yang dikirim dari URL'
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
const bufferImage = fs.readFileSync('./lokal_foto.jpg')
|
|
341
|
+
await sock.sendMessage(jid, {
|
|
342
|
+
image: bufferImage,
|
|
343
|
+
caption: 'Ini adalah gambar yang dikirim dari buffer lokal'
|
|
344
|
+
})
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
```
|
|
348
|
+
### 5.7 Video
|
|
349
|
+
```js
|
|
350
|
+
async function sendVideo(sock, jid) {
|
|
351
|
+
await sock.sendMessage(jid, {
|
|
352
|
+
video: { url: 'https://domain.com/video-keren.mp4' },
|
|
353
|
+
caption: 'Deskripsi untuk video ini',
|
|
354
|
+
gifPlayback: false
|
|
355
|
+
})
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
```
|
|
359
|
+
### 5.8 Audio
|
|
360
|
+
```js
|
|
361
|
+
async function sendAudio(sock, jid) {
|
|
362
|
+
await sock.sendMessage(jid, {
|
|
363
|
+
audio: { url: 'https://domain.com/voice-note.ogg' },
|
|
364
|
+
mimetype: 'audio/ogg; codecs=opus',
|
|
365
|
+
ptt: true
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
await sock.sendMessage(jid, {
|
|
369
|
+
audio: { url: 'https://domain.com/musik.mp3' },
|
|
370
|
+
mimetype: 'audio/mp4'
|
|
371
|
+
})
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
### 5.9 Document
|
|
376
|
+
```js
|
|
377
|
+
async function sendDocument(sock, jid) {
|
|
378
|
+
await sock.sendMessage(jid, {
|
|
379
|
+
document: { url: 'https://domain.com/laporan-tahunan.pdf' },
|
|
380
|
+
mimetype: 'application/pdf',
|
|
381
|
+
fileName: 'laporan-tahunan-2026.pdf',
|
|
382
|
+
caption: 'Berikut adalah file dokumen yang diminta'
|
|
383
|
+
})
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
```
|
|
387
|
+
### 5.10 Sticker
|
|
388
|
+
```js
|
|
389
|
+
import fs from 'fs'
|
|
390
|
+
|
|
391
|
+
async function sendSticker(sock, jid) {
|
|
392
|
+
const stickerBuffer = fs.readFileSync('./animasi_sticker.webp')
|
|
393
|
+
await sock.sendMessage(jid, {
|
|
394
|
+
sticker: stickerBuffer
|
|
395
|
+
})
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
```
|
|
399
|
+
### 5.11 Sticker Pack
|
|
400
|
+
```js
|
|
401
|
+
import fs from 'fs'
|
|
402
|
+
|
|
403
|
+
async function sendStickerPack(sock, jid) {
|
|
404
|
+
const localSticker = fs.readFileSync('./sticker_dua.webp')
|
|
405
|
+
await sock.sendMessage(jid, {
|
|
406
|
+
stickerPack: {
|
|
407
|
+
name: 'Koleksi Sticker Eksklusif',
|
|
408
|
+
publisher: 'Elynn',
|
|
409
|
+
cover: { url: 'https://domain.com/cover-pack.png' },
|
|
410
|
+
stickers: [
|
|
411
|
+
{ data: { url: 'https://domain.com/sticker_satu.webp' }, emojis: ['๐', '๐คฃ'] },
|
|
412
|
+
{ data: localSticker, emojis: ['๐ฅ', 'โจ'] }
|
|
413
|
+
]
|
|
414
|
+
}
|
|
415
|
+
})
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
### 5.12 Contact / vCard
|
|
420
|
+
```js
|
|
421
|
+
async function sendContact(sock, jid) {
|
|
422
|
+
const vcardString = 'BEGIN:VCARD\nVERSION:3.0\nFN:Elynn\nTEL;type=CELL;waid=6281234567890:+62 812 3456 7890\nEND:VCARD'
|
|
423
|
+
|
|
424
|
+
await sock.sendMessage(jid, {
|
|
425
|
+
contacts: {
|
|
426
|
+
displayName: 'Elynn Contact',
|
|
427
|
+
contacts: [{
|
|
428
|
+
vcard: vcardString
|
|
429
|
+
}]
|
|
430
|
+
}
|
|
431
|
+
})
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
### 5.13 Location
|
|
436
|
+
```js
|
|
437
|
+
async function sendLocation(sock, jid) {
|
|
438
|
+
await sock.sendMessage(jid, {
|
|
439
|
+
location: {
|
|
440
|
+
degreesLatitude: -6.2087634,
|
|
441
|
+
degreesLongitude: 106.845599,
|
|
442
|
+
name: 'Monumen Nasional',
|
|
443
|
+
address: 'Gambir, Jakarta Pusat, DKI Jakarta, Indonesia'
|
|
444
|
+
}
|
|
445
|
+
})
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
```
|
|
449
|
+
### 5.14 Live Location
|
|
450
|
+
```js
|
|
451
|
+
async function sendLiveLocation(sock, jid) {
|
|
452
|
+
await sock.sendMessage(jid, {
|
|
453
|
+
liveLocation: {
|
|
454
|
+
degreesLatitude: -6.2087634,
|
|
455
|
+
degreesLongitude: 106.845599,
|
|
456
|
+
accuracyInMeters: 10,
|
|
457
|
+
speedInMps: 0,
|
|
458
|
+
degreesClockwiseFromMagneticNorth: 0,
|
|
459
|
+
caption: 'Saya sedang membagikan lokasi langsung',
|
|
460
|
+
sequenceNumber: 1
|
|
461
|
+
}
|
|
462
|
+
})
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
```
|
|
466
|
+
### 5.15 Poll
|
|
467
|
+
```js
|
|
468
|
+
async function sendPoll(sock, jid) {
|
|
469
|
+
await sock.sendMessage(jid, {
|
|
470
|
+
poll: {
|
|
471
|
+
name: 'Apa bahasa pemrograman favorit Anda untuk backend?',
|
|
472
|
+
values: ['Node.js', 'Python', 'Go', 'Rust'],
|
|
473
|
+
selectableCount: 1
|
|
474
|
+
}
|
|
475
|
+
})
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
```
|
|
479
|
+
### 5.16 Album
|
|
480
|
+
```js
|
|
481
|
+
import fs from 'fs'
|
|
482
|
+
|
|
483
|
+
async function sendAlbum(sock, jid) {
|
|
484
|
+
const localImage = fs.readFileSync('./foto_galeri.jpg')
|
|
485
|
+
|
|
486
|
+
await sock.sendMessage(jid, {
|
|
487
|
+
album: [
|
|
488
|
+
{ image: { url: 'https://domain.com/foto_satu.jpg' }, caption: 'Dokumentasi Bagian 1' },
|
|
489
|
+
{ image: localImage, caption: 'Dokumentasi Bagian 2' },
|
|
490
|
+
{ video: { url: 'https://domain.com/video_dokumentasi.mp4' }, caption: 'Video Rekaman' }
|
|
491
|
+
]
|
|
492
|
+
})
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
```
|
|
496
|
+
### 5.17 Interactive โ Buttons (Native Flow)
|
|
497
|
+
```js
|
|
498
|
+
async function sendInteractiveButtons(sock, jid) {
|
|
499
|
+
await sock.sendMessage(jid, {
|
|
500
|
+
interactive: {
|
|
501
|
+
type: 'native_flow',
|
|
502
|
+
header: { hasMediaAttachment: false },
|
|
503
|
+
body: { text: 'Silakan pilih salah satu opsi di bawah ini untuk melanjutkan:' },
|
|
504
|
+
footer: { text: 'elynn-baileys' },
|
|
505
|
+
nativeFlowMessage: {
|
|
506
|
+
buttons: [
|
|
507
|
+
{
|
|
508
|
+
name: 'quick_reply',
|
|
509
|
+
buttonParamsJson: JSON.stringify({
|
|
510
|
+
display_text: 'โ
Konfirmasi Pesanan',
|
|
511
|
+
id: 'btn_confirm_order'
|
|
512
|
+
})
|
|
513
|
+
},
|
|
514
|
+
{
|
|
515
|
+
name: 'cta_url',
|
|
516
|
+
buttonParamsJson: JSON.stringify({
|
|
517
|
+
display_text: '๐ Kunjungi Website Resmi',
|
|
518
|
+
url: 'https://example.com',
|
|
519
|
+
merchant_url: 'https://example.com'
|
|
520
|
+
})
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
name: 'cta_copy',
|
|
524
|
+
buttonParamsJson: JSON.stringify({
|
|
525
|
+
display_text: '๐ Salin Kode Promo',
|
|
526
|
+
copy_code: 'ELYNN2026PROMO'
|
|
527
|
+
})
|
|
528
|
+
},
|
|
529
|
+
{
|
|
530
|
+
name: 'cta_call',
|
|
531
|
+
buttonParamsJson: JSON.stringify({
|
|
532
|
+
display_text: '๐ Hubungi Customer Service',
|
|
533
|
+
phone_number: '+6281234567890'
|
|
534
|
+
})
|
|
535
|
+
}
|
|
536
|
+
]
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
})
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
```
|
|
543
|
+
### 5.18 Interactive โ List
|
|
544
|
+
```js
|
|
545
|
+
async function sendInteractiveList(sock, jid) {
|
|
546
|
+
await sock.sendMessage(jid, {
|
|
547
|
+
interactive: {
|
|
548
|
+
type: 'native_flow',
|
|
549
|
+
body: { text: 'Berikut adalah katalog produk kami. Silakan pilih kategori yang Anda inginkan:' },
|
|
550
|
+
footer: { text: 'elynn-baileys' },
|
|
551
|
+
nativeFlowMessage: {
|
|
552
|
+
buttons: [{
|
|
553
|
+
name: 'single_select',
|
|
554
|
+
buttonParamsJson: JSON.stringify({
|
|
555
|
+
title: '๐ Buka Katalog Menu',
|
|
556
|
+
sections: [
|
|
557
|
+
{
|
|
558
|
+
title: '๐ Makanan Utama',
|
|
559
|
+
rows: [
|
|
560
|
+
{ id: 'menu_nasi_goreng', title: 'Nasi Goreng Spesial', description: 'Rp 25.000 - Ekstra Telur' },
|
|
561
|
+
{ id: 'menu_mie_goreng', title: 'Mie Goreng Seafood', description: 'Rp 30.000 - Udang & Cumi' }
|
|
562
|
+
]
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
title: '๐ฅค Minuman Segar',
|
|
566
|
+
rows: [
|
|
567
|
+
{ id: 'menu_es_teh', title: 'Es Teh Manis', description: 'Rp 5.000 - Gula Asli' },
|
|
568
|
+
{ id: 'menu_jus_jeruk', title: 'Jus Jeruk Peras', description: 'Rp 12.000 - Jeruk Murni' }
|
|
569
|
+
]
|
|
570
|
+
}
|
|
571
|
+
]
|
|
572
|
+
})
|
|
573
|
+
}]
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
})
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
### 5.19 Interactive โ Image Header
|
|
581
|
+
```js
|
|
582
|
+
async function sendInteractiveImageHeader(sock, jid) {
|
|
583
|
+
const imagePreparation = await sock.prepareMessage(jid, {
|
|
584
|
+
image: { url: 'https://domain.com/banner-promo.jpg' }
|
|
585
|
+
})
|
|
586
|
+
|
|
587
|
+
await sock.sendMessage(jid, {
|
|
588
|
+
interactive: {
|
|
589
|
+
type: 'native_flow',
|
|
590
|
+
header: {
|
|
591
|
+
hasMediaAttachment: true,
|
|
592
|
+
imageMessage: imagePreparation.message.imageMessage
|
|
593
|
+
},
|
|
594
|
+
body: { text: 'Dapatkan diskon 50% untuk pembelian pertama Anda hari ini!' },
|
|
595
|
+
footer: { text: 'elynn-baileys' },
|
|
596
|
+
nativeFlowMessage: {
|
|
597
|
+
buttons: [
|
|
598
|
+
{
|
|
599
|
+
name: 'quick_reply',
|
|
600
|
+
buttonParamsJson: JSON.stringify({
|
|
601
|
+
display_text: '๐ Klaim Diskon & Beli Sekarang',
|
|
602
|
+
id: 'claim_discount_buy'
|
|
603
|
+
})
|
|
604
|
+
}
|
|
605
|
+
]
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
})
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
```
|
|
612
|
+
### 5.20 Interactive sebagai Template
|
|
613
|
+
|
|
614
|
+
> โ ๏ธ Opsi `interactiveAsTemplate` membungkus pesan jadi `templateMessage`, format legacy yang **tidak tampil di akun WhatsApp personal** (lihat catatan di 5.21). Hanya gunakan ini jika tujuan target adalah WhatsApp Business Cloud API resmi dengan template approved. Untuk bot/personal account biasa, kirim langsung tanpa flag `interactiveAsTemplate` (lihat 5.17).
|
|
615
|
+
|
|
616
|
+
```js
|
|
617
|
+
async function sendInteractiveAsTemplate(sock, jid) {
|
|
618
|
+
await sock.sendMessage(jid, {
|
|
619
|
+
interactive: {
|
|
620
|
+
type: 'native_flow',
|
|
621
|
+
body: { text: 'Pesan interaktif ini dikirim menggunakan format bungkus template.' },
|
|
622
|
+
footer: { text: 'elynn-baileys' },
|
|
623
|
+
nativeFlowMessage: {
|
|
624
|
+
buttons: [
|
|
625
|
+
{
|
|
626
|
+
name: 'quick_reply',
|
|
627
|
+
buttonParamsJson: JSON.stringify({
|
|
628
|
+
display_text: 'Tampilkan Detail',
|
|
629
|
+
id: 'show_details'
|
|
630
|
+
})
|
|
631
|
+
}
|
|
632
|
+
]
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
interactiveAsTemplate: true
|
|
636
|
+
})
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
```
|
|
640
|
+
### 5.21 Hydrated Template Button
|
|
641
|
+
|
|
642
|
+
> โ ๏ธ **PENTING โ `templateMessage`/`buttonsMessage` (legacy) SUDAH TIDAK WORK di akun WhatsApp personal.** Berdasarkan dokumentasi resmi WhatsApp (developers.facebook.com), button & template format lama ini hanya didukung lewat **WhatsApp Business Cloud API** dengan template yang sudah di-approve Meta โ bukan lewat koneksi personal/MD seperti Baileys. Mengirim `templateMessage` mentah dari akun biasa akan terkirim tapi **buttonnya tidak muncul / pesan tidak tampil** di sisi penerima (silent fail). Gunakan **5.17 Native Flow** sebagai gantinya โ itu yang dipakai WA app resmi sekarang untuk personal account.
|
|
643
|
+
|
|
644
|
+
Helper `templateButtons` di bawah ini tetap disediakan untuk kompatibilitas kode lama, tapi secara internal **otomatis di-convert** memakai struktur yang sama dengan native flow agar tetap bisa tampil:
|
|
645
|
+
|
|
646
|
+
```js
|
|
647
|
+
import { generateWAMessageFromContent, proto } from 'elynn-baileys'
|
|
648
|
+
|
|
649
|
+
// โ
CARA YANG BENAR-BENAR WORK โ pakai nativeFlow (lihat juga 5.17)
|
|
650
|
+
async function sendWorkingButtons(sock, jid) {
|
|
651
|
+
await sock.sendMessage(jid, {
|
|
652
|
+
text: 'Pilih salah satu opsi di bawah ini:',
|
|
653
|
+
footer: 'elynn-baileys',
|
|
654
|
+
nativeFlow: {
|
|
655
|
+
buttons: [
|
|
656
|
+
{ url: 'https://example.com', text: '๐ Buka Situs Web' },
|
|
657
|
+
{ call: '+6281234567890', text: '๐ Hubungi Kami' },
|
|
658
|
+
{ id: 'btn_agree_terms', text: 'โ
Setuju' }
|
|
659
|
+
]
|
|
660
|
+
}
|
|
661
|
+
})
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
// โ ๏ธ Legacy hydratedTemplate โ disediakan untuk backward-compat, TIDAK direkomendasikan untuk fitur baru
|
|
665
|
+
async function sendHydratedTemplate(sock, jid) {
|
|
666
|
+
await sock.sendMessage(jid, {
|
|
667
|
+
templateButtons: [
|
|
668
|
+
{ url: 'https://example.com', text: '๐ Buka Situs Web' },
|
|
669
|
+
{ call: '+6281234567890', text: '๐ Hubungi Kami' },
|
|
670
|
+
{ id: 'btn_agree_terms', text: 'โ
Setuju' }
|
|
671
|
+
],
|
|
672
|
+
text: 'Ini adalah teks konten utama untuk pesan jenis hydrated template.',
|
|
673
|
+
footer: 'Informasi Footer Tambahan'
|
|
674
|
+
})
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
```
|
|
678
|
+
### 5.22 View Once
|
|
679
|
+
```js
|
|
680
|
+
async function sendViewOnce(sock, jid) {
|
|
681
|
+
await sock.sendMessage(jid, {
|
|
682
|
+
image: { url: 'https://domain.com/rahasia.jpg' },
|
|
683
|
+
caption: 'Dokumen ini hanya dapat dilihat satu kali.',
|
|
684
|
+
viewOnce: true
|
|
685
|
+
})
|
|
686
|
+
|
|
687
|
+
await sock.sendMessage(jid, {
|
|
688
|
+
video: { url: 'https://domain.com/video-rahasia.mp4' },
|
|
689
|
+
viewOnceV2: true
|
|
690
|
+
})
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
```
|
|
694
|
+
### 5.23 Ephemeral
|
|
695
|
+
```js
|
|
696
|
+
async function sendEphemeral(sock, jid) {
|
|
697
|
+
await sock.sendMessage(jid, {
|
|
698
|
+
text: 'Pesan ini bersifat rahasia dan akan terhapus otomatis secara permanen dalam waktu 24 jam.',
|
|
699
|
+
ephemeral: true
|
|
700
|
+
}, {
|
|
701
|
+
ephemeralExpiration: 86400
|
|
702
|
+
})
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
```
|
|
706
|
+
### 5.24 Spoiler
|
|
707
|
+
```js
|
|
708
|
+
async function sendSpoiler(sock, jid) {
|
|
709
|
+
await sock.sendMessage(jid, {
|
|
710
|
+
image: { url: 'https://domain.com/kejutan.jpg' },
|
|
711
|
+
caption: 'Ini adalah gambar kejutan yang disembunyikan di balik spoiler!',
|
|
712
|
+
spoiler: true
|
|
713
|
+
})
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
```
|
|
717
|
+
### 5.25 Group Status
|
|
718
|
+
```js
|
|
719
|
+
async function sendGroupStatus(sock, jid) {
|
|
720
|
+
await sock.sendMessage(jid, {
|
|
721
|
+
text: 'Pengumuman penting telah ditambahkan ke status grup.',
|
|
722
|
+
groupStatus: true
|
|
723
|
+
})
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
```
|
|
727
|
+
### 5.26 External Ad Reply
|
|
728
|
+
|
|
729
|
+
> โ ๏ธ **Catatan penting:** `externalAdReply` di shorthand `sock.sendMessage()` butuh field `url` (string, dipakai untuk `mediaUrl`/`sourceUrl`/`thumbnailUrl` sekaligus) dan `thumbnail` (Buffer JPEG, bukan `thumbnailUrl` string) โ bukan `thumbnailUrl`/`sourceUrl` terpisah. Tanpa `thumbnail` (Buffer), preview card sering tidak muncul karena WA app butuh gambar sudah ter-embed, tidak bisa fetch dari URL eksternal saat render. Sertakan juga `forwardingScore` + `isForwarded: true` โ pola ini paling konsisten membuat card-nya muncul.
|
|
730
|
+
>
|
|
731
|
+
> โ ๏ธ **Limitasi yang tidak bisa diperbaiki dari sisi kode:** `externalAdReply` murni metadata dekorasi di `contextInfo`, bukan tipe pesan sendiri โ apakah card-nya dirender atau tidak itu **keputusan WhatsApp app di sisi penerima**, tergantung platform (Android/iOS) dan versi app. Ini dikonfirmasi sebagai known issue di banyak fork Baileys (lihat issue [#51](https://github.com/WhiskeySockets/Baileys/issues/51) dan [#75](https://github.com/WhiskeySockets/Baileys/issues/75) di repo WhiskeySockets/Baileys). Gejala umum: pengirim/linked-device sendiri melihat card lengkap (karena disinkron via WA Web/Desktop yang versinya lebih baru), tapi penerima dengan WA app versi/platform berbeda **hanya melihat teks biasa tanpa card**. Tidak ada konfigurasi proto yang menjamin tampil 100% di semua device โ anggap fitur ini sebagai *progressive enhancement*, bukan sesuatu yang reliable untuk dipakai sebagai fitur utama bot.
|
|
732
|
+
|
|
733
|
+
```js
|
|
734
|
+
import fs from 'fs'
|
|
735
|
+
|
|
736
|
+
async function sendExternalAdReply(sock, jid) {
|
|
737
|
+
await sock.sendMessage(jid, {
|
|
738
|
+
text: 'Silakan periksa tautan referensi berikut ini untuk informasi lebih lanjut!',
|
|
739
|
+
contextInfo: {
|
|
740
|
+
forwardingScore: 100,
|
|
741
|
+
isForwarded: true
|
|
742
|
+
},
|
|
743
|
+
externalAdReply: {
|
|
744
|
+
title: 'Artikel Referensi Lengkap',
|
|
745
|
+
body: 'Membahas teknologi terbaru dan perkembangannya di masa depan',
|
|
746
|
+
thumbnail: fs.readFileSync('./thumbnail-artikel.jpg'), // wajib Buffer, bukan URL
|
|
747
|
+
url: 'https://example.com/artikel-lengkap', // dipakai untuk mediaUrl & sourceUrl
|
|
748
|
+
mediaType: 1, // 1 = tanpa media spesifik, 2 = image, 3 = video
|
|
749
|
+
renderLargerThumbnail: true,
|
|
750
|
+
showAdAttribution: true // default sudah true di lib, eksplisit di sini untuk kejelasan
|
|
751
|
+
}
|
|
752
|
+
})
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// Alternatif: raw style sesuai proto asli, kalau butuh kontrol penuh tanpa shorthand
|
|
756
|
+
async function sendExternalAdReplyRaw(sock, jid) {
|
|
757
|
+
await sock.sendMessage(jid, {
|
|
758
|
+
text: 'Versi raw, langsung isi contextInfo.externalAdReply.',
|
|
759
|
+
contextInfo: {
|
|
760
|
+
forwardingScore: 100,
|
|
761
|
+
isForwarded: true,
|
|
762
|
+
externalAdReply: {
|
|
763
|
+
title: 'Artikel Referensi Lengkap',
|
|
764
|
+
body: 'Membahas teknologi terbaru',
|
|
765
|
+
thumbnail: fs.readFileSync('./thumbnail-artikel.jpg'),
|
|
766
|
+
thumbnailUrl: 'https://example.com/thumbnail-artikel.jpg',
|
|
767
|
+
sourceUrl: 'https://example.com/artikel-lengkap',
|
|
768
|
+
mediaType: 1,
|
|
769
|
+
showAdAttribution: true
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
})
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
```
|
|
776
|
+
### 5.27 Forward Pesan
|
|
777
|
+
```js
|
|
778
|
+
async function sendForwardMessage(sock, jid, messageToForward) {
|
|
779
|
+
await sock.sendMessage(jid, {
|
|
780
|
+
forward: messageToForward
|
|
781
|
+
})
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
```
|
|
785
|
+
### 5.28 Pin Pesan
|
|
786
|
+
```js
|
|
787
|
+
async function pinMessageInChat(sock, jid, messageKey) {
|
|
788
|
+
await sock.sendMessage(jid, {
|
|
789
|
+
pin: {
|
|
790
|
+
messageKey: messageKey,
|
|
791
|
+
type: 1
|
|
792
|
+
}
|
|
793
|
+
})
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
```
|
|
797
|
+
### 5.29 Raw Message
|
|
798
|
+
```js
|
|
799
|
+
async function sendRawProtoMessage(sock, jid) {
|
|
800
|
+
await sock.sendMessage(jid, {
|
|
801
|
+
text: 'Pengujian pengiriman struktur raw protocol buffer langsung.',
|
|
802
|
+
raw: true
|
|
803
|
+
})
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
```
|
|
807
|
+
### 5.30 Group Invite Link
|
|
808
|
+
```js
|
|
809
|
+
async function sendGroupInvite(sock, jid) {
|
|
810
|
+
const currentTime = Math.round(new Date().getTime() / 1000)
|
|
811
|
+
const expirationTime = currentTime + 86400
|
|
812
|
+
|
|
813
|
+
await sock.sendMessage(jid, {
|
|
814
|
+
groupInviteMessage: {
|
|
815
|
+
inviteCode: 'AbCdEfGhIjKlMnOp',
|
|
816
|
+
inviteExpiration: expirationTime,
|
|
817
|
+
groupJid: '1234567890-0987654321@g.us',
|
|
818
|
+
groupName: 'Komunitas Pengembang Nusantara',
|
|
819
|
+
caption: 'Mari bergabung dengan grup diskusi kami untuk bertukar wawasan dan pengalaman!'
|
|
820
|
+
}
|
|
821
|
+
})
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
```
|
|
825
|
+
### 5.31 Event dengan Reminder (fitur WA Januari 2026)
|
|
826
|
+
WhatsApp resmi menambahkan "Event Reminders" pada update grup chat 7 Januari 2026 โ pembuat event kini bisa menyetel pengingat otomatis untuk semua undangan sebelum acara dimulai. Cukup tambahkan `reminderOffsetSec` (dalam detik) ke object `event` yang sudah ada di elynn-baileys.
|
|
827
|
+
```js
|
|
828
|
+
async function sendEventWithReminder(sock, jid) {
|
|
829
|
+
await sock.sendMessage(jid, {
|
|
830
|
+
event: {
|
|
831
|
+
name: 'Nonton Bareng Final Liga',
|
|
832
|
+
description: 'Kumpul bareng nonton final di basecamp ya, jangan telat!',
|
|
833
|
+
startDate: new Date('2026-08-01T20:00:00+07:00'),
|
|
834
|
+
endDate: new Date('2026-08-01T23:00:00+07:00'),
|
|
835
|
+
location: 'Basecamp Komunitas, Jl. Mawar No. 5',
|
|
836
|
+
extraGuestsAllowed: true,
|
|
837
|
+
reminderOffsetSec: 3600 // ingatkan semua undangan 1 jam sebelum acara dimulai
|
|
838
|
+
}
|
|
839
|
+
})
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
```
|
|
843
|
+
> Catatan: jika `reminderOffsetSec` diisi, elynn-baileys otomatis menyetel `hasReminder: true` pada `eventMessage`. Tanpa parameter ini, event tetap terkirim normal tanpa pengingat โ perilaku ini sepenuhnya backward-compatible dengan kode event lama Anda.
|
|
844
|
+
### 5.32 Text Sticker (fitur WA Januari 2026)
|
|
845
|
+
WhatsApp juga merilis "Text Stickers" pada update yang sama โ mengubah kata apa pun menjadi stiker hanya dengan mengetik di Sticker Search. Karena fitur aslinya murni rendering sisi klien (tanpa endpoint protokol khusus), elynn-baileys menyediakan generator `renderTextSticker()` bawaan yang merender teks menjadi stiker WebP secara lokal (memakai `canvas` + `sharp`/`@napi-rs/image`, tanpa API pihak ketiga) lalu langsung bisa dikirim seperti stiker biasa.
|
|
846
|
+
```js
|
|
847
|
+
import { renderTextSticker } from 'elynn-baileys'
|
|
848
|
+
|
|
849
|
+
async function sendTextSticker(sock, jid) {
|
|
850
|
+
const stickerBuffer = await renderTextSticker('MANTAP', {
|
|
851
|
+
backgroundColor: '#FFD60A',
|
|
852
|
+
textColor: '#1A1A1A',
|
|
853
|
+
fontWeight: 'bold'
|
|
854
|
+
})
|
|
855
|
+
|
|
856
|
+
await sock.sendMessage(jid, {
|
|
857
|
+
sticker: stickerBuffer
|
|
858
|
+
})
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
```
|
|
862
|
+
> Beda dengan plugin `attp`/`ttp` (Bab 11) yang memanggil API eksternal untuk efek teks bergerak/glow, `renderTextSticker` murni lokal โ tidak butuh koneksi internet maupun API key, cocok untuk stiker teks polos yang cepat dan privat.
|
|
863
|
+
|
|
864
|
+
---
|
|
865
|
+
|
|
866
|
+
### 5.33 View-Once Text โ Teks Sekali Lihat (WA 2026)
|
|
867
|
+
|
|
868
|
+
Pertengahan 2026, WhatsApp merilis kemampuan mengirim **teks murni** sebagai view-once: pesan hanya bisa dibaca satu kali, setelah itu otomatis dihapus. Penerima tidak bisa menyalin, meneruskan, atau merekam layarnya. Di Baileys, ini bekerja dengan membungkus `extendedTextMessage` ke dalam `viewOnceMessageV2` via `generateWAMessageFromContent`.
|
|
869
|
+
|
|
870
|
+
```js
|
|
871
|
+
import { generateWAMessageFromContent, proto } from 'elynn-baileys'
|
|
872
|
+
|
|
873
|
+
async function sendViewOnceText(sock, jid) {
|
|
874
|
+
// Cara 1 โ shorthand flag (dicoba dulu, support tergantung versi WA penerima)
|
|
875
|
+
await sock.sendMessage(jid, {
|
|
876
|
+
text: 'Pesan rahasia ini hanya bisa dibaca satu kali. ๐',
|
|
877
|
+
viewOnce: true,
|
|
878
|
+
})
|
|
879
|
+
|
|
880
|
+
// Cara 2 โ raw proto wrap (lebih kompatibel dengan WA build terbaru)
|
|
881
|
+
const innerMsg = generateWAMessageFromContent(jid, {
|
|
882
|
+
extendedTextMessage: {
|
|
883
|
+
text: 'Isi pesan rahasia yang hanya bisa dilihat sekali.',
|
|
884
|
+
},
|
|
885
|
+
}, {})
|
|
886
|
+
|
|
887
|
+
const viewOnceMsg = generateWAMessageFromContent(jid, {
|
|
888
|
+
viewOnceMessageV2: {
|
|
889
|
+
message: innerMsg.message,
|
|
890
|
+
},
|
|
891
|
+
}, { userJid: sock.user.id })
|
|
892
|
+
|
|
893
|
+
await sock.relayMessage(jid, viewOnceMsg.message, { messageId: viewOnceMsg.key.id })
|
|
894
|
+
}
|
|
895
|
+
```
|
|
896
|
+
|
|
897
|
+
> **Catatan:** Pastikan WA penerima sudah versi yang mendukung view-once teks (2025.8+). Pada versi lebih lama pesan akan tampil sebagai teks biasa.
|
|
898
|
+
|
|
899
|
+
---
|
|
900
|
+
|
|
901
|
+
### 5.34 View-Once Voice Note โ Audio Sekali Dengar (WA 2026)
|
|
902
|
+
|
|
903
|
+
Voice note (PTT) kini resmi bisa dikirim sebagai view-once: audio hanya bisa diputar satu kali lalu hilang. Cocok untuk kirim kode OTP audio atau pesan suara rahasia.
|
|
904
|
+
|
|
905
|
+
```js
|
|
906
|
+
async function sendViewOnceVoice(sock, jid) {
|
|
907
|
+
// View-Once Voice Note (PTT sekali dengar)
|
|
908
|
+
await sock.sendMessage(jid, {
|
|
909
|
+
audio: { url: './voice-rahasia.ogg' },
|
|
910
|
+
mimetype: 'audio/ogg; codecs=opus',
|
|
911
|
+
ptt: true, // wajib true agar muncul sebagai voice note
|
|
912
|
+
viewOnce: true, // sekali dengar, lalu terhapus otomatis
|
|
913
|
+
})
|
|
914
|
+
|
|
915
|
+
// Dengan waveform custom (opsional, memperindah tampilan)
|
|
916
|
+
await sock.sendMessage(jid, {
|
|
917
|
+
audio: { url: './voice-rahasia.ogg' },
|
|
918
|
+
mimetype: 'audio/ogg; codecs=opus',
|
|
919
|
+
ptt: true,
|
|
920
|
+
viewOnce: true,
|
|
921
|
+
waveform: [0, 15, 42, 80, 110, 95, 70, 50, 30, 10], // array amplitudo 0-100
|
|
922
|
+
})
|
|
923
|
+
}
|
|
924
|
+
```
|
|
925
|
+
|
|
926
|
+
> **Catatan:** `ptt: true` wajib ada โ tanpa itu audio dikirim sebagai musik biasa dan flag `viewOnce` tidak akan aktif dengan benar.
|
|
927
|
+
|
|
928
|
+
---
|
|
929
|
+
|
|
930
|
+
### 5.35 Community Event โ RSVP & Virtual Meeting Call (WA 2026)
|
|
931
|
+
|
|
932
|
+
WhatsApp 2026 memperluas fitur event di **Community** dengan dukungan RSVP tracking dan link virtual meeting langsung di dalam pesan event. Berbeda dari 5.31 (event grup biasa dengan reminder), fitur ini spesifik untuk:
|
|
933
|
+
- **Virtual call** (audio/video link tertanam)
|
|
934
|
+
- **RSVP**: bot bisa mendeteksi siapa yang menerima/menolak lewat `messages.upsert` event bertipe `eventResponseMessage`
|
|
935
|
+
- **extraGuestsAllowed**: anggota bisa mengajak tamu di luar grup
|
|
936
|
+
|
|
937
|
+
```js
|
|
938
|
+
// Kirim event virtual meeting di community/grup
|
|
939
|
+
async function sendVirtualMeetingEvent(sock, groupJid) {
|
|
940
|
+
await sock.sendMessage(groupJid, {
|
|
941
|
+
event: {
|
|
942
|
+
isCancelled: false,
|
|
943
|
+
name: 'Elynn Dev โ Sprint Review Q4',
|
|
944
|
+
description: 'Review sprint bulanan + demo fitur baru. Join via WA Call.',
|
|
945
|
+
location: {
|
|
946
|
+
// Untuk virtual meeting: isi name dengan link meeting, lat/long bisa 0
|
|
947
|
+
degreesLatitude: 0,
|
|
948
|
+
degreesLongitude: 0,
|
|
949
|
+
name: 'Google Meet โ meet.google.com/abc-defg-hij',
|
|
950
|
+
},
|
|
951
|
+
call: 'video', // 'audio' = voice call, 'video' = video call -- butuh options.getCallLink saat dipanggil dari generateWAMessageFromContent agar joinLink terisi
|
|
952
|
+
startDate: new Date('2026-10-10T15:00:00+07:00'), // wajib objek Date, bukan unix timestamp
|
|
953
|
+
endDate: new Date('2026-10-10T16:30:00+07:00'),
|
|
954
|
+
extraGuestsAllowed: false, // false = hanya member grup yang bisa join
|
|
955
|
+
},
|
|
956
|
+
})
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
// Handle respons RSVP dari peserta
|
|
960
|
+
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
961
|
+
for (const msg of messages) {
|
|
962
|
+
const rsvp = msg.message?.eventResponseMessage
|
|
963
|
+
if (!rsvp) continue
|
|
964
|
+
|
|
965
|
+
// rsvp.response: 1 = GOING, 2 = NOT GOING
|
|
966
|
+
const status = rsvp.response === 1 ? 'HADIR โ
' : 'TIDAK HADIR โ'
|
|
967
|
+
const eventId = rsvp.eventCreationMessageKey?.id
|
|
968
|
+
const voter = msg.key.participant || msg.key.remoteJid
|
|
969
|
+
|
|
970
|
+
console.log(`RSVP dari ${voter}: ${status} (event ID: ${eventId})`)
|
|
971
|
+
}
|
|
972
|
+
})
|
|
973
|
+
```
|
|
974
|
+
|
|
975
|
+
> **Perbedaan dari 5.31:** Section 5.31 fokus pada event grup biasa dengan `reminderOffsetSec` (pengingat waktu). Section ini fokus pada **virtual meeting** + **RSVP response handling** โ dua kemampuan berbeda yang hadir bersamaan di WA 2026.
|
|
976
|
+
|
|
977
|
+
---
|
|
978
|
+
|
|
979
|
+
### 5.36 Group Message History Share (WA 2026)
|
|
980
|
+
|
|
981
|
+
WhatsApp merilis fitur ini Februari 2026: saat member baru ditambahkan, admin/member bisa membagikan 25โ100 pesan terakhir ke member tersebut lewat prompt di UI client resmi. Fitur ini murni **client-side** (ditangani oleh aplikasi WA, bukan dikirim sebagai pesan protokol terpisah) dan field internalnya (`GroupHistoryBundleInfo`) ditandai `deprecated` di proto WA sendiri โ sehingga **belum ada endpoint resmi** untuk men-trigger ini lewat Baileys/elynn-baileys.
|
|
982
|
+
|
|
983
|
+
Yang **sudah bisa** dilakukan lewat lib ini sekarang:
|
|
984
|
+
```js
|
|
985
|
+
// Cek setting grup yang berkaitan (member add mode, announce, dst)
|
|
986
|
+
async function checkGroupSettings(sock, groupJid) {
|
|
987
|
+
const meta = await sock.groupMetadata(groupJid)
|
|
988
|
+
console.log('Group metadata:', {
|
|
989
|
+
name: meta.subject,
|
|
990
|
+
memberAddMode: meta.memberAddMode, // 'all_member_add' | 'admin_add'
|
|
991
|
+
announce: meta.announce, // true = hanya admin bisa kirim pesan
|
|
992
|
+
participants: meta.participants.length,
|
|
993
|
+
})
|
|
994
|
+
return meta
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// Alternatif manual: forward N pesan terakhir ke member baru via DM/bot logic sendiri
|
|
998
|
+
async function shareRecentMessagesManually(sock, groupJid, newMemberJid, messages) {
|
|
999
|
+
for (const msg of messages.slice(-25)) { // ambil 25 pesan terakhir
|
|
1000
|
+
await sock.relayMessage(newMemberJid, msg.message, { messageId: msg.key.id })
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
```
|
|
1004
|
+
|
|
1005
|
+
> **Catatan:** Belum ada method native (`groupToggleMessageHistory` dkk **tidak exist**) karena WA belum membuka protokol publik untuk fitur ini. Jangan gunakan nama method yang belum ada di lib โ cek dulu dengan `console.log(Object.keys(sock))` untuk daftar method yang benar-benar tersedia.
|
|
1006
|
+
|
|
1007
|
+
---
|
|
1008
|
+
|
|
1009
|
+
### 5.37 Channel Poll โ Polling di Saluran/Channel (WA 2026)
|
|
1010
|
+
|
|
1011
|
+
WhatsApp Channels kini mendukung pembuatan polling โ fitur interaksi satu arah berskala besar langsung di saluran. Gunakan `toAnnouncementGroup: true` agar poll terkirim ke channel/saluran (newsletter JID).
|
|
1012
|
+
|
|
1013
|
+
```js
|
|
1014
|
+
async function sendChannelPoll(sock, channelJid) {
|
|
1015
|
+
// Kirim poll ke Channel / Saluran WhatsApp
|
|
1016
|
+
// channelJid format: 'xxxxxxxxxxxxxxxxxx@newsletter'
|
|
1017
|
+
await sock.sendMessage(channelJid, {
|
|
1018
|
+
poll: {
|
|
1019
|
+
name: 'Bahasa pemrograman favorit kamu?',
|
|
1020
|
+
values: ['JavaScript', 'Python', 'Go', 'Rust', 'TypeScript'],
|
|
1021
|
+
selectableCount: 1, // 1 = single choice, >1 = multi choice
|
|
1022
|
+
toAnnouncementGroup: true, // WAJIB true untuk Channel/saluran
|
|
1023
|
+
},
|
|
1024
|
+
})
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
// Poll biasa di grup (bukan channel)
|
|
1028
|
+
async function sendGroupPoll(sock, groupJid) {
|
|
1029
|
+
await sock.sendMessage(groupJid, {
|
|
1030
|
+
poll: {
|
|
1031
|
+
name: 'Kapan kita meet offline?',
|
|
1032
|
+
values: ['Minggu ini', 'Minggu depan', 'Bulan depan', 'Belum bisa'],
|
|
1033
|
+
selectableCount: 1,
|
|
1034
|
+
toAnnouncementGroup: false,
|
|
1035
|
+
},
|
|
1036
|
+
})
|
|
1037
|
+
}
|
|
1038
|
+
|
|
1039
|
+
// Handling respons poll di event handler
|
|
1040
|
+
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
1041
|
+
for (const msg of messages) {
|
|
1042
|
+
if (msg.message?.pollUpdateMessage) {
|
|
1043
|
+
const update = msg.message.pollUpdateMessage
|
|
1044
|
+
console.log('Vote masuk:', {
|
|
1045
|
+
voter: msg.key.participant,
|
|
1046
|
+
pollMsgId: update.pollCreationMessageKey?.id,
|
|
1047
|
+
selectedOpt: update.vote?.selectedOptions,
|
|
1048
|
+
})
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
})
|
|
1052
|
+
```
|
|
1053
|
+
|
|
1054
|
+
---
|
|
1055
|
+
|
|
1056
|
+
### 5.38 Channel Voice Note (WA 2026)
|
|
1057
|
+
|
|
1058
|
+
WhatsApp Channels kini mendukung pengiriman voice note โ memungkinkan kreator saluran berinteraksi lebih personal dengan subscriber via audio langsung di channel.
|
|
1059
|
+
|
|
1060
|
+
```js
|
|
1061
|
+
async function sendChannelVoiceNote(sock, channelJid) {
|
|
1062
|
+
// channelJid format: 'xxxxxxxxxxxxxxxxxx@newsletter'
|
|
1063
|
+
await sock.sendMessage(channelJid, {
|
|
1064
|
+
audio: { url: './pengumuman.ogg' },
|
|
1065
|
+
mimetype: 'audio/ogg; codecs=opus',
|
|
1066
|
+
ptt: true, // wajib true agar tampil sebagai voice note di channel
|
|
1067
|
+
})
|
|
1068
|
+
|
|
1069
|
+
// Dengan caption/deskripsi (support tergantung WA build)
|
|
1070
|
+
await sock.sendMessage(channelJid, {
|
|
1071
|
+
audio: { url: './rekaman-siaran.mp3' },
|
|
1072
|
+
mimetype: 'audio/mp4',
|
|
1073
|
+
ptt: false, // false = audio biasa (musik/rekaman), bukan PTT
|
|
1074
|
+
caption: 'Rekaman siaran terbaru โ dengarkan sekarang! ๐๏ธ',
|
|
1075
|
+
})
|
|
1076
|
+
}
|
|
1077
|
+
```
|
|
1078
|
+
|
|
1079
|
+
> **Catatan:** Newsletter JID bisa didapat dari `sock.newsletterSubscribers(channelJid)`, `sock.newsletterFetchMessages(...)`, atau dari metadata channel yang sudah kamu follow saat event `messaging-history.set`.
|
|
1080
|
+
|
|
1081
|
+
---
|
|
1082
|
+
|
|
1083
|
+
## 6. ๐ค Rich Response Messages
|
|
1084
|
+
Fitur ini secara eksklusif memungkinkan Anda mengirim struktur data yang lebih kompleks menyerupai antarmuka dari bot AI resmi WhatsApp.
|
|
1085
|
+
### 6.1 Text Rich
|
|
1086
|
+
```js
|
|
1087
|
+
import { prepareRichResponseMessage } from 'elynn-baileys'
|
|
1088
|
+
|
|
1089
|
+
async function sendRichText(sock, jid) {
|
|
1090
|
+
const messageData = prepareRichResponseMessage({
|
|
1091
|
+
contentText: 'Ini adalah paragraf teks biasa yang dirender dalam kontainer rich response yang memiliki margin dan padding khusus.'
|
|
1092
|
+
})
|
|
1093
|
+
|
|
1094
|
+
await sock.sendMessage(jid, messageData)
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
```
|
|
1098
|
+
### 6.2 Code Block
|
|
1099
|
+
```js
|
|
1100
|
+
import { prepareRichResponseMessage } from 'elynn-baileys'
|
|
1101
|
+
|
|
1102
|
+
async function sendRichCode(sock, jid) {
|
|
1103
|
+
const kodeProgram = 'const status = "success";\nconsole.log(`Operasi selesai dengan status: ${status}`);'
|
|
1104
|
+
|
|
1105
|
+
const messageData = prepareRichResponseMessage({
|
|
1106
|
+
headerText: 'Berikut adalah implementasi kode dalam JavaScript:',
|
|
1107
|
+
code: kodeProgram,
|
|
1108
|
+
language: 'javascript'
|
|
1109
|
+
})
|
|
1110
|
+
|
|
1111
|
+
await sock.sendMessage(jid, messageData)
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
```
|
|
1115
|
+
### 6.3 Table
|
|
1116
|
+
```js
|
|
1117
|
+
import { prepareRichResponseMessage } from 'elynn-baileys'
|
|
1118
|
+
|
|
1119
|
+
async function sendRichTable(sock, jid) {
|
|
1120
|
+
const tabelData = [
|
|
1121
|
+
['Nama Menu', 'Harga', 'Ketersediaan'],
|
|
1122
|
+
['Nasi Goreng Spesial', 'Rp 25.000', 'โ
Tersedia'],
|
|
1123
|
+
['Mie Goreng Seafood', 'Rp 30.000', 'โ
Tersedia'],
|
|
1124
|
+
['Es Teh Manis', 'Rp 5.000', 'โ
Tersedia'],
|
|
1125
|
+
['Ayam Bakar Madu', 'Rp 35.000', 'โ Habis']
|
|
1126
|
+
]
|
|
1127
|
+
|
|
1128
|
+
const messageData = prepareRichResponseMessage({
|
|
1129
|
+
headerText: 'Daftar Harga Lengkap:',
|
|
1130
|
+
title: 'Katalog Menu Restoran',
|
|
1131
|
+
table: tabelData,
|
|
1132
|
+
noHeading: false
|
|
1133
|
+
})
|
|
1134
|
+
|
|
1135
|
+
await sock.sendMessage(jid, messageData)
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
```
|
|
1139
|
+
### 6.4 Inline Image
|
|
1140
|
+
```js
|
|
1141
|
+
import { prepareRichResponseMessage } from 'elynn-baileys'
|
|
1142
|
+
|
|
1143
|
+
async function sendRichInlineImage(sock, jid) {
|
|
1144
|
+
const messageData = prepareRichResponseMessage({
|
|
1145
|
+
contentText: 'Gambar di bawah ini disisipkan langsung di dalam kotak pesan:',
|
|
1146
|
+
inlineImage: 'https://domain.com/gambar-inline.jpg',
|
|
1147
|
+
imageText: 'Ilustrasi pemandangan alam',
|
|
1148
|
+
tapLinkUrl: 'https://example.com/galeri'
|
|
1149
|
+
})
|
|
1150
|
+
|
|
1151
|
+
await sock.sendMessage(jid, messageData)
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
```
|
|
1155
|
+
### 6.5 Inline Link / Citation
|
|
1156
|
+
```js
|
|
1157
|
+
import { prepareRichResponseMessage } from 'elynn-baileys'
|
|
1158
|
+
|
|
1159
|
+
async function sendRichCitation(sock, jid) {
|
|
1160
|
+
const messageData = prepareRichResponseMessage({
|
|
1161
|
+
links: [{
|
|
1162
|
+
text: 'Silakan merujuk ke dokumentasi resmi untuk rincian lebih lanjut',
|
|
1163
|
+
title: 'Dokumentasi API',
|
|
1164
|
+
url: 'https://example.com/docs',
|
|
1165
|
+
displayName: 'Portal Edukasi',
|
|
1166
|
+
sources: [{
|
|
1167
|
+
displayName: 'Portal Edukasi',
|
|
1168
|
+
subtitle: 'Situs Referensi',
|
|
1169
|
+
url: 'https://example.com/docs'
|
|
1170
|
+
}]
|
|
1171
|
+
}]
|
|
1172
|
+
})
|
|
1173
|
+
|
|
1174
|
+
await sock.sendMessage(jid, messageData)
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
```
|
|
1178
|
+
### 6.6 Rich Response Kombinasi
|
|
1179
|
+
```js
|
|
1180
|
+
import { prepareRichResponseMessage } from 'elynn-baileys'
|
|
1181
|
+
|
|
1182
|
+
async function sendComplexRichResponse(sock, jid) {
|
|
1183
|
+
const tabelKombinasi = [
|
|
1184
|
+
{ isHeading: true, items: ['Kolom Identitas', 'Kolom Status'] },
|
|
1185
|
+
{ isHeading: false, items: ['Server Utama', 'Online'] },
|
|
1186
|
+
{ isHeading: false, items: ['Server Cadangan', 'Maintenance'] }
|
|
1187
|
+
]
|
|
1188
|
+
|
|
1189
|
+
const messageData = prepareRichResponseMessage({
|
|
1190
|
+
richResponse: [
|
|
1191
|
+
{ text: 'Sistem telah menyelesaikan analisis keseluruhan. Berikut adalah laporan terperinci:' },
|
|
1192
|
+
{ code: [{ codeContent: 'function checkStatus() { return true; }', highlightType: 0 }], language: 'javascript' },
|
|
1193
|
+
{ text: 'Kode di atas memvalidasi integritas data. Status server saat ini adalah:' },
|
|
1194
|
+
{ table: tabelKombinasi, title: 'Status Infrastruktur Jaringan' },
|
|
1195
|
+
{ inlineImage: 'https://domain.com/grafik-server.png', imageText: 'Grafik Beban Server' }
|
|
1196
|
+
]
|
|
1197
|
+
})
|
|
1198
|
+
|
|
1199
|
+
await sock.sendMessage(jid, messageData)
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
```
|
|
1203
|
+
## 7. ๐ฅ Group Management
|
|
1204
|
+
API yang ekstensif untuk memanipulasi dan mengelola data serta operasional grup secara menyeluruh.
|
|
1205
|
+
```js
|
|
1206
|
+
async function manageGroup(sock, jid) {
|
|
1207
|
+
const daftarAnggotaAwal = ['6281234567890@s.whatsapp.net', '6289876543210@s.whatsapp.net']
|
|
1208
|
+
const grupBaru = await sock.groupCreate('Grup Diskusi Internal', daftarAnggotaAwal)
|
|
1209
|
+
const idGrup = grupBaru.id
|
|
1210
|
+
|
|
1211
|
+
const metadataGrup = await sock.groupMetadata(idGrup)
|
|
1212
|
+
|
|
1213
|
+
const targetUser = ['628111222333@s.whatsapp.net']
|
|
1214
|
+
await sock.groupParticipantsUpdate(idGrup, targetUser, 'add')
|
|
1215
|
+
await sock.groupParticipantsUpdate(idGrup, targetUser, 'promote')
|
|
1216
|
+
await sock.groupParticipantsUpdate(idGrup, targetUser, 'demote')
|
|
1217
|
+
await sock.groupParticipantsUpdate(idGrup, targetUser, 'remove')
|
|
1218
|
+
|
|
1219
|
+
await sock.groupUpdateSubject(idGrup, 'Grup Diskusi Internal v2')
|
|
1220
|
+
await sock.groupUpdateDescription(idGrup, 'Ini adalah deskripsi grup yang baru saja diperbarui melalui sistem bot otomatis.')
|
|
1221
|
+
await sock.updateProfilePicture(idGrup, { url: 'https://domain.com/ikon-grup.png' })
|
|
1222
|
+
|
|
1223
|
+
const kodeUndangan = await sock.groupInviteCode(idGrup)
|
|
1224
|
+
await sock.groupRevokeInvite(idGrup)
|
|
1225
|
+
const infoUndangan = await sock.groupGetInviteInfo(kodeUndangan)
|
|
1226
|
+
await sock.groupAcceptInvite(kodeUndangan)
|
|
1227
|
+
|
|
1228
|
+
await sock.groupSettingUpdate(idGrup, 'announcement')
|
|
1229
|
+
await sock.groupSettingUpdate(idGrup, 'not_announcement')
|
|
1230
|
+
await sock.groupSettingUpdate(idGrup, 'locked')
|
|
1231
|
+
await sock.groupSettingUpdate(idGrup, 'unlocked')
|
|
1232
|
+
|
|
1233
|
+
await sock.groupToggleEphemeral(idGrup, 86400)
|
|
1234
|
+
await sock.groupJoinApprovalMode(idGrup, 'on')
|
|
1235
|
+
await sock.groupMemberAddMode(idGrup, 'admin_add')
|
|
1236
|
+
|
|
1237
|
+
await sock.groupLeave(idGrup)
|
|
1238
|
+
|
|
1239
|
+
const daftarGrupAktif = await sock.groupFetchAllParticipating()
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
```
|
|
1243
|
+
## 8. ๐ข Newsletter / Channel
|
|
1244
|
+
Fungsionalitas penuh untuk memoderasi saluran informasi siaran satu arah (Channel WhatsApp).
|
|
1245
|
+
```js
|
|
1246
|
+
async function manageNewsletter(sock) {
|
|
1247
|
+
const metadataChannelBaru = await sock.newsletterCreate('Saluran Berita Utama', 'Pusat informasi dan pembaruan sistem secara langsung dan cepat.')
|
|
1248
|
+
const idChannel = metadataChannelBaru.id
|
|
1249
|
+
|
|
1250
|
+
await sock.newsletterFollow(idChannel)
|
|
1251
|
+
await sock.newsletterUnfollow(idChannel)
|
|
1252
|
+
|
|
1253
|
+
await sock.newsletterMute(idChannel)
|
|
1254
|
+
await sock.newsletterUnmute(idChannel)
|
|
1255
|
+
|
|
1256
|
+
await sock.newsletterUpdateName(idChannel, 'Berita Utama Revisi')
|
|
1257
|
+
await sock.newsletterUpdateDescription(idChannel, 'Pembaruan deskripsi untuk memperjelas tujuan dari saluran komunikasi ini.')
|
|
1258
|
+
await sock.newsletterUpdatePicture(idChannel, { url: 'https://domain.com/logo-channel.jpg' })
|
|
1259
|
+
await sock.newsletterRemovePicture(idChannel)
|
|
1260
|
+
|
|
1261
|
+
const kodeInviteChannel = 'KODE_INVITE_YANG_VALID'
|
|
1262
|
+
const detailMetadataChannel = await sock.newsletterMetadata('invite', kodeInviteChannel)
|
|
1263
|
+
|
|
1264
|
+
const idPesanServer = '1234567890'
|
|
1265
|
+
await sock.newsletterReactMessage(idChannel, idPesanServer, '๐ฅ')
|
|
1266
|
+
|
|
1267
|
+
const daftarSaluranDiikuti = await sock.newsletterSubscribed()
|
|
1268
|
+
|
|
1269
|
+
const batasPesan = 10
|
|
1270
|
+
const daftarPesanChannel = await sock.newsletterFetchMessages('invite', kodeInviteChannel, batasPesan, null, null)
|
|
1271
|
+
|
|
1272
|
+
await sock.newsletterDelete(idChannel)
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
```
|
|
1276
|
+
## 9. ๐ก๏ธ Privacy & Profile
|
|
1277
|
+
Pengaturan terkait profil pribadi pengguna dan konfigurasi privasi keamanan akun.
|
|
1278
|
+
```js
|
|
1279
|
+
async function updateProfileAndPrivacy(sock) {
|
|
1280
|
+
const targetJid = '6281234567890@s.whatsapp.net'
|
|
1281
|
+
|
|
1282
|
+
await sock.updateProfileName('Elynn Bot System')
|
|
1283
|
+
await sock.updateProfileStatus('Sistem berjalan dengan optimal dan sedang memonitor antrean tugas.')
|
|
1284
|
+
await sock.updateProfilePicture(targetJid, { url: 'https://domain.com/foto-profil-baru.jpg' })
|
|
1285
|
+
await sock.removeProfilePicture(targetJid)
|
|
1286
|
+
|
|
1287
|
+
const tautanFotoProfil = await sock.profilePictureUrl(targetJid, 'image')
|
|
1288
|
+
const informasiBio = await sock.fetchStatus(targetJid)
|
|
1289
|
+
|
|
1290
|
+
await sock.updateLastSeenPrivacy('all')
|
|
1291
|
+
await sock.updateOnlinePrivacy('all')
|
|
1292
|
+
await sock.updateProfilePicturePrivacy('all')
|
|
1293
|
+
await sock.updateStatusPrivacy('all')
|
|
1294
|
+
await sock.updateReadReceiptsPrivacy('all')
|
|
1295
|
+
await sock.updateGroupsAddPrivacy('all')
|
|
1296
|
+
await sock.updateCallPrivacy('all')
|
|
1297
|
+
await sock.updateMessagesPrivacy('all')
|
|
1298
|
+
await sock.updateDefaultDisappearingMode(86400)
|
|
1299
|
+
|
|
1300
|
+
await sock.updateBlockStatus(targetJid, 'block')
|
|
1301
|
+
await sock.updateBlockStatus(targetJid, 'unblock')
|
|
1302
|
+
const daftarBlokir = await sock.fetchBlocklist()
|
|
1303
|
+
|
|
1304
|
+
const nomorTelepon = '6281234567890'
|
|
1305
|
+
const hasilPengecekanWA = await sock.onWhatsApp(nomorTelepon)
|
|
1306
|
+
|
|
1307
|
+
await sock.sendPresenceUpdate('composing', targetJid)
|
|
1308
|
+
await sock.sendPresenceUpdate('recording', targetJid)
|
|
1309
|
+
await sock.sendPresenceUpdate('paused', targetJid)
|
|
1310
|
+
await sock.presenceSubscribe(targetJid)
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
```
|
|
1314
|
+
## 10. ๐ก Handling Events
|
|
1315
|
+
Cara komprehensif untuk mendaftarkan pendengar acara ke seluruh aktivitas yang terjadi di jaringan.
|
|
1316
|
+
```js
|
|
1317
|
+
function setupEventHandlers(sock, saveCreds) {
|
|
1318
|
+
sock.ev.on('connection.update', (updatePayload) => {
|
|
1319
|
+
const koneksi = updatePayload.connection
|
|
1320
|
+
const pemutusanTerakhir = updatePayload.lastDisconnect
|
|
1321
|
+
const kodeQr = updatePayload.qr
|
|
1322
|
+
const loginBaru = updatePayload.isNewLogin
|
|
1323
|
+
})
|
|
1324
|
+
|
|
1325
|
+
sock.ev.on('messages.upsert', (dataUpsert) => {
|
|
1326
|
+
const daftarPesan = dataUpsert.messages
|
|
1327
|
+
const tipeData = dataUpsert.type
|
|
1328
|
+
|
|
1329
|
+
for (const dataPesan of daftarPesan) {
|
|
1330
|
+
const pengirimJid = dataPesan.key.remoteJid
|
|
1331
|
+
const dikirimOlehSaya = dataPesan.key.fromMe
|
|
1332
|
+
const apakahGrup = pengirimJid.endsWith('@g.us')
|
|
1333
|
+
|
|
1334
|
+
const teksPesan = dataPesan.message?.conversation
|
|
1335
|
+
|| dataPesan.message?.extendedTextMessage?.text
|
|
1336
|
+
|| dataPesan.message?.imageMessage?.caption
|
|
1337
|
+
|| ''
|
|
1338
|
+
|
|
1339
|
+
console.log({ pengirimJid, dikirimOlehSaya, apakahGrup, teksPesan })
|
|
1340
|
+
}
|
|
1341
|
+
})
|
|
1342
|
+
|
|
1343
|
+
sock.ev.on('messages.update', (dataPembaruanPesan) => {
|
|
1344
|
+
})
|
|
1345
|
+
|
|
1346
|
+
sock.ev.on('messages.reaction', (dataReaksi) => {
|
|
1347
|
+
})
|
|
1348
|
+
|
|
1349
|
+
sock.ev.on('message-receipt.update', (dataTandaTerima) => {
|
|
1350
|
+
})
|
|
1351
|
+
|
|
1352
|
+
sock.ev.on('presence.update', (dataKehadiran) => {
|
|
1353
|
+
const identitasUser = dataKehadiran.id
|
|
1354
|
+
const statusKehadiran = dataKehadiran.presences
|
|
1355
|
+
})
|
|
1356
|
+
|
|
1357
|
+
sock.ev.on('chats.update', (dataPembaruanChat) => {
|
|
1358
|
+
})
|
|
1359
|
+
|
|
1360
|
+
sock.ev.on('chats.upsert', (dataChatBaru) => {
|
|
1361
|
+
})
|
|
1362
|
+
|
|
1363
|
+
sock.ev.on('chats.delete', (dataPenghapusanChat) => {
|
|
1364
|
+
})
|
|
1365
|
+
|
|
1366
|
+
sock.ev.on('contacts.upsert', (dataKontakBaru) => {
|
|
1367
|
+
})
|
|
1368
|
+
|
|
1369
|
+
sock.ev.on('contacts.update', (dataPembaruanKontak) => {
|
|
1370
|
+
})
|
|
1371
|
+
|
|
1372
|
+
sock.ev.on('groups.update', (dataPembaruanGrup) => {
|
|
1373
|
+
})
|
|
1374
|
+
|
|
1375
|
+
sock.ev.on('group-participants.update', (dataAksiPesertaGrup) => {
|
|
1376
|
+
const idGrup = dataAksiPesertaGrup.id
|
|
1377
|
+
const daftarPeserta = dataAksiPesertaGrup.participants
|
|
1378
|
+
const jenisTindakan = dataAksiPesertaGrup.action
|
|
1379
|
+
})
|
|
1380
|
+
|
|
1381
|
+
sock.ev.on('call', (dataPanggilanMasuk) => {
|
|
1382
|
+
for (const panggilan of dataPanggilanMasuk) {
|
|
1383
|
+
const idPanggilan = panggilan.id
|
|
1384
|
+
const pemanggil = panggilan.from
|
|
1385
|
+
|
|
1386
|
+
sock.rejectCall(idPanggilan, pemanggil)
|
|
1387
|
+
}
|
|
1388
|
+
})
|
|
1389
|
+
|
|
1390
|
+
sock.ev.on('labels.edit', (dataLabelDiedit) => {
|
|
1391
|
+
})
|
|
1392
|
+
|
|
1393
|
+
sock.ev.on('labels.association', (dataAsosiasiLabel) => {
|
|
1394
|
+
const tipeAsosiasi = dataAsosiasiLabel.type
|
|
1395
|
+
const detailAsosiasi = dataAsosiasiLabel.association
|
|
1396
|
+
})
|
|
1397
|
+
|
|
1398
|
+
sock.ev.on('creds.update', saveCreds)
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
```
|
|
1402
|
+
## 11. ๐งฉ Elynn Plugins โ Brat & Bratvid
|
|
1403
|
+
|
|
1404
|
+
elynn-baileys menyertakan **30+ plugin bawaan** siap pakai mencakup AI, berita, downloader, search, stalk, info, dan maker. Plugin dapat diimport langsung atau diakses via objek `plugins`. Output tiap plugin mengikuti format `{ ok, type, result }` โ langsung bisa dipakai di `sendMessage`.
|
|
1405
|
+
|
|
1406
|
+
| Key | Method | Endpoint | Output | Parameter |
|
|
1407
|
+
|-----------|--------|--------------------------|----------------|-----------------|
|
|
1408
|
+
| `brat` | GET | `/api/maker/brat` | Sticker (img) | `text` (string) |
|
|
1409
|
+
| `bratvid` | GET | `/api/maker/bratvid` | Sticker (vid) | `text` (string) |
|
|
1410
|
+
|
|
1411
|
+
```js
|
|
1412
|
+
import { plugins, listPlugins } from 'elynn-baileys'
|
|
1413
|
+
|
|
1414
|
+
// Cek plugin yang tersedia
|
|
1415
|
+
console.log(listPlugins()) // ['ai', 'deepseek', 'qwq', 'glm', 'gpt', 'gita', 'cnbc', 'cnn', ..., 'brat', 'bratvid'] (30+ plugins)
|
|
1416
|
+
|
|
1417
|
+
// Kirim Brat image sebagai stiker
|
|
1418
|
+
async function kirimBrat(sock, jid) {
|
|
1419
|
+
const hasil = await plugins.brat({ text: 'gabut nih' })
|
|
1420
|
+
if (!hasil.ok) return console.error(hasil.message)
|
|
1421
|
+
|
|
1422
|
+
// hasil.type === 'sticker' โ kirim langsung sebagai stiker
|
|
1423
|
+
await sock.sendMessage(jid, {
|
|
1424
|
+
sticker: { url: hasil.result },
|
|
1425
|
+
})
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
// Kirim Bratvid (video) sebagai stiker animasi
|
|
1429
|
+
async function kirimBratvid(sock, jid) {
|
|
1430
|
+
const hasil = await plugins.bratvid({ text: 'literally me every monday' })
|
|
1431
|
+
if (!hasil.ok) return console.error(hasil.message)
|
|
1432
|
+
|
|
1433
|
+
await sock.sendMessage(jid, {
|
|
1434
|
+
sticker: { url: hasil.result },
|
|
1435
|
+
isAnimated: true, // opsional โ indikator untuk stiker bergerak
|
|
1436
|
+
})
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
// Contoh di dalam handler pesan bot
|
|
1440
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
1441
|
+
for (const msg of messages) {
|
|
1442
|
+
const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text || ''
|
|
1443
|
+
const jid = msg.key.remoteJid
|
|
1444
|
+
const isBot = msg.key.fromMe
|
|
1445
|
+
|
|
1446
|
+
if (isBot || !text) continue
|
|
1447
|
+
|
|
1448
|
+
if (text.startsWith('.brat ')) {
|
|
1449
|
+
const input = text.slice(6).trim()
|
|
1450
|
+
const res = await plugins.brat({ text: input })
|
|
1451
|
+
if (res.ok) {
|
|
1452
|
+
await sock.sendMessage(jid, { sticker: { url: res.result } }, { quoted: msg })
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
if (text.startsWith('.bratvid ')) {
|
|
1457
|
+
const input = text.slice(9).trim()
|
|
1458
|
+
const res = await plugins.bratvid({ text: input })
|
|
1459
|
+
if (res.ok) {
|
|
1460
|
+
await sock.sendMessage(jid, { sticker: { url: res.result } }, { quoted: msg })
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
})
|
|
1465
|
+
```
|
|
1466
|
+
|
|
1467
|
+
> Plugin Brat & Bratvid selalu mengembalikan `{ ok: boolean, type: 'sticker', result: string }` di mana `result` adalah URL gambar/video yang bisa langsung dipakai di `sendMessage`. Tidak ada API key tambahan yang diperlukan โ sudah ter-bundle di dalam library.
|
|
1468
|
+
|
|
1469
|
+
## 12. ๐ Read Messages & Presence
|
|
1470
|
+
Kendali mutlak atas indikator pesan dibaca dan pelaporan presensi sesi secara waktu nyata.
|
|
1471
|
+
```js
|
|
1472
|
+
async function markMessagesAsRead(sock, kunciPesanTunggal, arrayKunciPesan) {
|
|
1473
|
+
await sock.readMessages([kunciPesanTunggal])
|
|
1474
|
+
|
|
1475
|
+
const kunciPesanSatu = arrayKunciPesan[0]
|
|
1476
|
+
const kunciPesanDua = arrayKunciPesan[1]
|
|
1477
|
+
const kunciPesanTiga = arrayKunciPesan[2]
|
|
1478
|
+
|
|
1479
|
+
await sock.readMessages([kunciPesanSatu, kunciPesanDua, kunciPesanTiga])
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
```
|
|
1483
|
+
## 13. ๐๏ธ Delete / Edit Pesan
|
|
1484
|
+
Mekanisme pasca-pengiriman yang memungkinkan Anda menarik kembali atau merevisi pesan yang telah telanjur terkirim ke server tujuan.
|
|
1485
|
+
```js
|
|
1486
|
+
async function modifySentMessages(sock, jid, kunciPesanTerkirim) {
|
|
1487
|
+
await sock.sendMessage(jid, {
|
|
1488
|
+
delete: kunciPesanTerkirim
|
|
1489
|
+
})
|
|
1490
|
+
|
|
1491
|
+
await sock.sendMessage(jid, {
|
|
1492
|
+
edit: kunciPesanTerkirim,
|
|
1493
|
+
text: 'Ini adalah teks yang telah direvisi dan menggantikan konten pesan sebelumnya yang salah.'
|
|
1494
|
+
})
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
```
|
|
1498
|
+
## 14. โ๏ธ Message Options Tambahan
|
|
1499
|
+
Modifikasi perilaku tambahan untuk pesan agar sesuai dengan spesifikasi kasus penggunaan tingkat lanjut.
|
|
1500
|
+
```js
|
|
1501
|
+
import { prepareDisappearingMessageSettingContent } from 'elynn-baileys'
|
|
1502
|
+
|
|
1503
|
+
async function applyAdvancedMessageOptions(sock, jid, dataPesanKutipan) {
|
|
1504
|
+
const durasiMenghilangDariPenyimpanan = sock.store?.chats.get(jid)?.ephemeralExpiration
|
|
1505
|
+
|
|
1506
|
+
await sock.sendMessage(jid, {
|
|
1507
|
+
text: 'Pesan ini dikirim dengan konfigurasi menghilang mengikuti pengaturan chat lokal.'
|
|
1508
|
+
}, {
|
|
1509
|
+
ephemeralExpiration: durasiMenghilangDariPenyimpanan
|
|
1510
|
+
})
|
|
1511
|
+
|
|
1512
|
+
const pengaturanWaktuSatuHari = 86400
|
|
1513
|
+
const konfigurasiTimerBawaan = prepareDisappearingMessageSettingContent(pengaturanWaktuSatuHari)
|
|
1514
|
+
await sock.sendMessage(jid, konfigurasiTimerBawaan)
|
|
1515
|
+
|
|
1516
|
+
await sock.sendMessage(jid, {
|
|
1517
|
+
text: 'Balasan ini mencakup elemen antarmuka tombol interaktif yang diikatkan ke pesan historis.',
|
|
1518
|
+
interactive: {
|
|
1519
|
+
type: 'native_flow',
|
|
1520
|
+
body: { text: 'Klik tombol di bawah ini' },
|
|
1521
|
+
nativeFlowMessage: {
|
|
1522
|
+
buttons: [
|
|
1523
|
+
{ name: 'quick_reply', buttonParamsJson: JSON.stringify({ display_text: 'Tombol Aksi', id: 'aksi' }) }
|
|
1524
|
+
]
|
|
1525
|
+
}
|
|
1526
|
+
},
|
|
1527
|
+
quote: dataPesanKutipan
|
|
1528
|
+
})
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
```
|
|
1532
|
+
## 15. ๐ Browser Fingerprint (Kiwi, UC Browser, dll)
|
|
1533
|
+
Saat membuka koneksi dengan `makeWASocket`, properti `browser` menentukan perangkat & browser apa yang "terlihat" oleh WhatsApp sebagai linked device Anda. elynn-baileys menyediakan helper `Browsers` berisi preset fingerprint siap pakai โ termasuk Kiwi Browser dan UC Browser โ supaya Anda tidak perlu menulis array `[OS, Browser, Version]` secara manual.
|
|
1534
|
+
```js
|
|
1535
|
+
import { Browsers } from 'elynn-baileys'
|
|
1536
|
+
|
|
1537
|
+
Browsers.ubuntu('Chrome') // ['Ubuntu', 'Chrome', '22.04.4']
|
|
1538
|
+
Browsers.macOS('Safari') // ['Mac OS', 'Safari', '14.4.1']
|
|
1539
|
+
Browsers.windows('Edge') // ['Windows', 'Edge', '10.0.22631']
|
|
1540
|
+
Browsers.android('Chrome') // ['Android', 'Chrome', '14.0']
|
|
1541
|
+
Browsers.baileys('Custom') // ['Baileys', 'Custom', '6.5.0']
|
|
1542
|
+
Browsers.kiwi() // ['Android', 'Chrome', '130.0.6723.58'] โ fingerprint Kiwi Browser
|
|
1543
|
+
Browsers.ucBrowser() // ['Android', 'Chrome', '16.4.0.1'] โ fingerprint UC Browser
|
|
1544
|
+
Browsers.brave() // ['Windows', 'Chrome', '130.0.0.0']
|
|
1545
|
+
Browsers.vivaldi() // ['Windows', 'Chrome', '6.9.3447.48']
|
|
1546
|
+
Browsers.arc() // ['Mac OS', 'Chrome', '1.60.0']
|
|
1547
|
+
Browsers.appropriate('Chrome') // otomatis menyesuaikan OS tempat proses Node.js Anda berjalan
|
|
1548
|
+
|
|
1549
|
+
```
|
|
1550
|
+
Gunakan langsung di opsi koneksi:
|
|
1551
|
+
```js
|
|
1552
|
+
import { makeWASocket, Browsers } from 'elynn-baileys'
|
|
1553
|
+
|
|
1554
|
+
const sock = makeWASocket({
|
|
1555
|
+
auth: state,
|
|
1556
|
+
browser: Browsers.kiwi(), // linked device akan tampil sebagai "Kiwi Browser" di WhatsApp
|
|
1557
|
+
})
|
|
1558
|
+
|
|
1559
|
+
```
|
|
1560
|
+
> Catatan: fingerprint browser ini hanya memengaruhi bagaimana sesi tampil di daftar "Linked Devices" pada WhatsApp pengguna, dan tidak mengubah perilaku jaringan atau protokol koneksi itu sendiri.
|
|
1561
|
+
## 16. ๐ค Telegram Bot (ElynnTelegraf)
|
|
1562
|
+
Selain WhatsApp, elynn-baileys juga membungkus engine Telegraf secara penuh dengan nama `ElynnTelegraf`. Artinya Anda bisa membangun bot Telegram lengkap โ command, inline keyboard, scenes/wizard, session, hingga webhook โ tanpa perlu menginstal package `telegraf` terpisah.
|
|
1563
|
+
### 16.1 Setup Dasar & Long Polling
|
|
1564
|
+
```js
|
|
1565
|
+
import { ElynnTelegraf } from 'elynn-baileys'
|
|
1566
|
+
|
|
1567
|
+
const bot = new ElynnTelegraf(process.env.TELEGRAM_BOT_TOKEN)
|
|
1568
|
+
|
|
1569
|
+
bot.start((ctx) => ctx.reply('Halo! Bot Elynn siap digunakan ๐'))
|
|
1570
|
+
bot.help((ctx) => ctx.reply('Kirim /menu untuk melihat daftar fitur.'))
|
|
1571
|
+
|
|
1572
|
+
bot.command('ping', (ctx) => ctx.reply('Pong!'))
|
|
1573
|
+
|
|
1574
|
+
bot.on('text', (ctx) => {
|
|
1575
|
+
ctx.reply(`Kamu mengirim: ${ctx.message.text}`)
|
|
1576
|
+
})
|
|
1577
|
+
|
|
1578
|
+
bot.catch((err, ctx) => {
|
|
1579
|
+
console.error(`Error untuk ${ctx.updateType}`, err)
|
|
1580
|
+
})
|
|
1581
|
+
|
|
1582
|
+
bot.launch()
|
|
1583
|
+
console.log('Bot Telegram berjalan dengan mode long polling...')
|
|
1584
|
+
|
|
1585
|
+
process.once('SIGINT', () => bot.stop('SIGINT'))
|
|
1586
|
+
process.once('SIGTERM', () => bot.stop('SIGTERM'))
|
|
1587
|
+
|
|
1588
|
+
```
|
|
1589
|
+
### 16.2 Setup via Webhook
|
|
1590
|
+
Cocok untuk deployment di platform serverless seperti Vercel atau VPS dengan domain HTTPS aktif.
|
|
1591
|
+
```js
|
|
1592
|
+
import { ElynnTelegraf } from 'elynn-baileys'
|
|
1593
|
+
|
|
1594
|
+
const bot = new ElynnTelegraf(process.env.TELEGRAM_BOT_TOKEN)
|
|
1595
|
+
|
|
1596
|
+
bot.command('start', (ctx) => ctx.reply('Bot aktif via webhook!'))
|
|
1597
|
+
|
|
1598
|
+
await bot.launch({
|
|
1599
|
+
webhook: {
|
|
1600
|
+
domain: 'https://domain-anda.com',
|
|
1601
|
+
port: process.env.PORT || 3000,
|
|
1602
|
+
path: '/telegram-webhook'
|
|
1603
|
+
}
|
|
1604
|
+
})
|
|
1605
|
+
|
|
1606
|
+
```
|
|
1607
|
+
### 16.3 Inline Keyboard & Reply Keyboard
|
|
1608
|
+
```js
|
|
1609
|
+
import { ElynnTelegraf, TelegramMarkup as Markup } from 'elynn-baileys'
|
|
1610
|
+
|
|
1611
|
+
const bot = new ElynnTelegraf(process.env.TELEGRAM_BOT_TOKEN)
|
|
1612
|
+
|
|
1613
|
+
bot.command('menu', (ctx) => {
|
|
1614
|
+
ctx.reply('Pilih salah satu fitur:', Markup.inlineKeyboard([
|
|
1615
|
+
[Markup.button.callback('๐ค AI Chat', 'menu_ai'), Markup.button.callback('โฌ๏ธ Downloader', 'menu_dl')],
|
|
1616
|
+
[Markup.button.url('๐ GitHub', 'https://github.com/elynncntip/elynn-baileys')]
|
|
1617
|
+
]))
|
|
1618
|
+
})
|
|
1619
|
+
|
|
1620
|
+
bot.action('menu_ai', (ctx) => {
|
|
1621
|
+
ctx.answerCbQuery()
|
|
1622
|
+
ctx.editMessageText('Silakan ketik pertanyaan untuk AI.')
|
|
1623
|
+
})
|
|
1624
|
+
|
|
1625
|
+
bot.action('menu_dl', (ctx) => {
|
|
1626
|
+
ctx.answerCbQuery()
|
|
1627
|
+
ctx.editMessageText('Kirim link TikTok/Instagram/YouTube yang ingin diunduh.')
|
|
1628
|
+
})
|
|
1629
|
+
|
|
1630
|
+
```
|
|
1631
|
+
### 16.4 Session, Scenes & Wizard
|
|
1632
|
+
Untuk membangun percakapan bertahap (misalnya alur registrasi atau form multi-langkah), gunakan `telegramSession` bersama `TelegramScenes`.
|
|
1633
|
+
```js
|
|
1634
|
+
import { ElynnTelegraf, telegramSession, TelegramScenes } from 'elynn-baileys'
|
|
1635
|
+
|
|
1636
|
+
const registerScene = new TelegramScenes.WizardScene(
|
|
1637
|
+
'register-wizard',
|
|
1638
|
+
(ctx) => {
|
|
1639
|
+
ctx.reply('Siapa nama Anda?')
|
|
1640
|
+
return ctx.wizard.next()
|
|
1641
|
+
},
|
|
1642
|
+
(ctx) => {
|
|
1643
|
+
ctx.wizard.state.nama = ctx.message.text
|
|
1644
|
+
ctx.reply('Berapa umur Anda?')
|
|
1645
|
+
return ctx.wizard.next()
|
|
1646
|
+
},
|
|
1647
|
+
(ctx) => {
|
|
1648
|
+
ctx.reply(`Terdaftar sebagai ${ctx.wizard.state.nama}, umur ${ctx.message.text} tahun.`)
|
|
1649
|
+
return ctx.scene.leave()
|
|
1650
|
+
}
|
|
1651
|
+
)
|
|
1652
|
+
|
|
1653
|
+
const stage = new TelegramScenes.Stage([registerScene])
|
|
1654
|
+
const bot = new ElynnTelegraf(process.env.TELEGRAM_BOT_TOKEN)
|
|
1655
|
+
|
|
1656
|
+
bot.use(telegramSession())
|
|
1657
|
+
bot.use(stage.middleware())
|
|
1658
|
+
|
|
1659
|
+
bot.command('daftar', (ctx) => ctx.scene.enter('register-wizard'))
|
|
1660
|
+
|
|
1661
|
+
bot.launch()
|
|
1662
|
+
|
|
1663
|
+
```
|
|
1664
|
+
### 16.5 Memanggil Elynn Plugins (Brat/Bratvid) dari Bot Telegram
|
|
1665
|
+
Karena `plugins` adalah objek universal yang sama dipakai di sisi WhatsApp, Anda bisa memanggil fungsi AI/downloader/tools yang identik di dalam bot Telegram.
|
|
1666
|
+
```js
|
|
1667
|
+
import { ElynnTelegraf, plugins } from 'elynn-baileys'
|
|
1668
|
+
|
|
1669
|
+
const bot = new ElynnTelegraf(process.env.TELEGRAM_BOT_TOKEN)
|
|
1670
|
+
|
|
1671
|
+
bot.command('ai', async (ctx) => {
|
|
1672
|
+
const pertanyaan = ctx.message.text.split(' ').slice(1).join(' ')
|
|
1673
|
+
if (!pertanyaan) return ctx.reply('Gunakan format: /ai <pertanyaan>')
|
|
1674
|
+
|
|
1675
|
+
const respon = await plugins.gpt({ q: pertanyaan })
|
|
1676
|
+
ctx.reply(respon?.result?.message || respon?.message || 'Gagal mendapatkan respon AI.')
|
|
1677
|
+
})
|
|
1678
|
+
|
|
1679
|
+
bot.command('tiktok', async (ctx) => {
|
|
1680
|
+
const url = ctx.message.text.split(' ')[1]
|
|
1681
|
+
if (!url) return ctx.reply('Gunakan format: /tiktok <url>')
|
|
1682
|
+
|
|
1683
|
+
const hasil = await plugins.tiktok({ url })
|
|
1684
|
+
if (hasil?.ok === false) return ctx.reply(hasil.message)
|
|
1685
|
+
ctx.reply('Video berhasil diproses.')
|
|
1686
|
+
})
|
|
1687
|
+
|
|
1688
|
+
bot.launch()
|
|
1689
|
+
|
|
1690
|
+
```
|
|
1691
|
+
### 16.6 Cek Koneksi Bot dengan `connectTelegram`
|
|
1692
|
+
Helper bawaan untuk memvalidasi token bot secara cepat tanpa harus memulai polling/webhook penuh โ cocok dipakai saat startup aplikasi untuk logging status.
|
|
1693
|
+
```js
|
|
1694
|
+
import { connectTelegram } from 'elynn-baileys'
|
|
1695
|
+
|
|
1696
|
+
const botInfo = await connectTelegram(process.env.TELEGRAM_BOT_TOKEN)
|
|
1697
|
+
if (botInfo) {
|
|
1698
|
+
console.log(`Terhubung sebagai @${botInfo.username}`)
|
|
1699
|
+
}
|
|
1700
|
+
|
|
1701
|
+
```
|
|
1702
|
+
|
|
1703
|
+
### 16.7 Bot API 9.3โ9.4 โ sendMessageDraft, Profile Photo Bot, Button Style & Icon
|
|
1704
|
+
|
|
1705
|
+
**sendMessageDraft** โ Pre-isi input box user dengan draft pesan. User bisa edit dan kirim sendiri.
|
|
1706
|
+
|
|
1707
|
+
```js
|
|
1708
|
+
bot.on('message', async (ctx) => {
|
|
1709
|
+
await ctx.sendMessageDraft('Halo, nama saya adalah...')
|
|
1710
|
+
})
|
|
1711
|
+
|
|
1712
|
+
// Atau via telegram instance
|
|
1713
|
+
await bot.telegram.sendMessageDraft(chatId, 'Draft pesan ini')
|
|
1714
|
+
```
|
|
1715
|
+
|
|
1716
|
+
**setMyProfilePhoto / removeMyProfilePhoto** โ Bot bisa ganti/hapus foto profilnya sendiri.
|
|
1717
|
+
|
|
1718
|
+
```js
|
|
1719
|
+
await bot.telegram.setMyProfilePhoto({ source: './avatar.jpg' })
|
|
1720
|
+
await bot.telegram.removeMyProfilePhoto()
|
|
1721
|
+
```
|
|
1722
|
+
|
|
1723
|
+
**Button Style & Custom Emoji Icon (Bot API 9.4)** โ Tombol inline/reply keyboard bisa punya warna (`primary`=biru, `success`=hijau, `danger`=merah) dan emoji icon custom.
|
|
1724
|
+
|
|
1725
|
+
```js
|
|
1726
|
+
import { ElynnTelegraf, TelegramMarkup as Markup } from 'elynn-baileys'
|
|
1727
|
+
|
|
1728
|
+
// Helper Button dari Markup
|
|
1729
|
+
const Button = Markup.button
|
|
1730
|
+
|
|
1731
|
+
bot.on('message', async (ctx) => {
|
|
1732
|
+
await ctx.reply('Pilih aksi:', Markup.inlineKeyboard([
|
|
1733
|
+
// Tombol biasa dengan style warna
|
|
1734
|
+
[Button.styledCallback('โ
Setuju', 'approve', 'success')],
|
|
1735
|
+
[Button.styledCallback('โ Tolak', 'reject', 'danger')],
|
|
1736
|
+
[Button.styledCallback('โน๏ธ Info', 'info', 'primary')],
|
|
1737
|
+
|
|
1738
|
+
// Tombol dengan custom emoji icon (butuh Telegram Premium owner)
|
|
1739
|
+
[Button.iconCallback('Lihat Detail', 'detail', '5373141891321699086')],
|
|
1740
|
+
|
|
1741
|
+
// Tombol style + icon sekaligus
|
|
1742
|
+
[Button.styledIconCallback('Konfirmasi', 'confirm', 'success', '5368324170671202286')],
|
|
1743
|
+
]))
|
|
1744
|
+
})
|
|
1745
|
+
```
|
|
1746
|
+
|
|
1747
|
+
### 16.8 Bot API 9.5 โ Member Tags, Date-Time Entity
|
|
1748
|
+
|
|
1749
|
+
**setChatMemberTag** โ Set tag custom untuk member grup (butuh hak `can_manage_tags`).
|
|
1750
|
+
|
|
1751
|
+
```js
|
|
1752
|
+
// Beri tag ke member
|
|
1753
|
+
bot.command('tag', async (ctx) => {
|
|
1754
|
+
const userId = ctx.message.reply_to_message?.from?.id
|
|
1755
|
+
if (!userId) return ctx.reply('Reply ke pesan seseorang dulu')
|
|
1756
|
+
await ctx.setChatMemberTag(userId, 'VIP')
|
|
1757
|
+
await ctx.reply('Tag VIP berhasil dipasang!')
|
|
1758
|
+
})
|
|
1759
|
+
|
|
1760
|
+
// Hapus tag (kirim string kosong)
|
|
1761
|
+
await ctx.telegram.setChatMemberTag(chatId, userId, '')
|
|
1762
|
+
```
|
|
1763
|
+
|
|
1764
|
+
**getUserProfileAudios** โ Ambil daftar audio profil user.
|
|
1765
|
+
|
|
1766
|
+
```js
|
|
1767
|
+
const audios = await bot.telegram.getUserProfileAudios(userId, { limit: 5 })
|
|
1768
|
+
```
|
|
1769
|
+
|
|
1770
|
+
### 16.9 Bot API 9.6 โ Managed Bots
|
|
1771
|
+
Bot kini bisa membuat, mengonfigurasi, dan mengelola bot lain secara programatik tanpa perlu ke @BotFather.
|
|
1772
|
+
|
|
1773
|
+
```js
|
|
1774
|
+
// Dapatkan token bot yang dikelola
|
|
1775
|
+
const result = await bot.telegram.getManagedBotToken(botUserId)
|
|
1776
|
+
|
|
1777
|
+
// Ganti token bot yang dikelola
|
|
1778
|
+
await bot.telegram.replaceManagedBotToken(botUserId)
|
|
1779
|
+
|
|
1780
|
+
// Simpan prepared keyboard button untuk dipakai di Mini Apps
|
|
1781
|
+
await bot.telegram.savePreparedKeyboardButton(button, userId)
|
|
1782
|
+
```
|
|
1783
|
+
|
|
1784
|
+
### 16.10 Bot API 10.0 โ Guest Mode
|
|
1785
|
+
Bot bisa menerima pesan dan membalas di chat yang **bukan** anggotanya โ tanpa perlu join grup.
|
|
1786
|
+
|
|
1787
|
+
```js
|
|
1788
|
+
// Tangkap guest message
|
|
1789
|
+
bot.on('guest_message', async (ctx) => {
|
|
1790
|
+
// ctx.guestMessage โ update berisi pesan tamu
|
|
1791
|
+
await ctx.answerGuestQuery(
|
|
1792
|
+
{ type: 'text', text: 'Halo dari bot! ๐' }
|
|
1793
|
+
)
|
|
1794
|
+
})
|
|
1795
|
+
```
|
|
1796
|
+
|
|
1797
|
+
### 16.11 Bot API 10.0 โ Bot-to-Bot Communication
|
|
1798
|
+
Bot bisa kirim pesan ke bot lain via @username (keduanya harus opt-in via @BotFather).
|
|
1799
|
+
|
|
1800
|
+
```js
|
|
1801
|
+
// Aktifkan dulu di @BotFather: Bot-to-Bot Communication Mode
|
|
1802
|
+
await bot.telegram.sendMessage('@other_bot_username', 'Halo bot lain!')
|
|
1803
|
+
```
|
|
1804
|
+
|
|
1805
|
+
### 16.12 Bot API 10.0 โ Delete Reactions
|
|
1806
|
+
```js
|
|
1807
|
+
// Hapus satu reaction spesifik pada pesan
|
|
1808
|
+
bot.on('message', async (ctx) => {
|
|
1809
|
+
await ctx.deleteMessageReaction({ type: 'emoji', emoji: '๐' })
|
|
1810
|
+
})
|
|
1811
|
+
|
|
1812
|
+
// Hapus semua reaction sekaligus
|
|
1813
|
+
bot.on('message', async (ctx) => {
|
|
1814
|
+
await ctx.deleteAllMessageReactions()
|
|
1815
|
+
})
|
|
1816
|
+
|
|
1817
|
+
// Atau langsung via telegram instance
|
|
1818
|
+
await bot.telegram.deleteMessageReaction(chatId, messageId, { type: 'emoji', emoji: '๐ฅ' })
|
|
1819
|
+
await bot.telegram.deleteAllMessageReactions(chatId, messageId)
|
|
1820
|
+
```
|
|
1821
|
+
|
|
1822
|
+
### 16.13 Bot API 10.0 โ Live Photo
|
|
1823
|
+
Bot bisa mengirim foto dengan video pendek (seperti iPhone Live Photos).
|
|
1824
|
+
|
|
1825
|
+
```js
|
|
1826
|
+
// Kirim live photo
|
|
1827
|
+
bot.on('message', async (ctx) => {
|
|
1828
|
+
await ctx.sendLivePhoto({ source: './photo.heic' }, { caption: 'Live photo!' })
|
|
1829
|
+
})
|
|
1830
|
+
|
|
1831
|
+
// Atau via telegram instance
|
|
1832
|
+
await bot.telegram.sendLivePhoto(chatId, { source: './photo.heic' }, { caption: 'Keren!' })
|
|
1833
|
+
```
|
|
1834
|
+
|
|
1835
|
+
### 16.14 Bot API 10.0 โ Managed Bot Access Settings
|
|
1836
|
+
```js
|
|
1837
|
+
// Cek siapa yang bisa kirim pesan ke managed bot
|
|
1838
|
+
const settings = await bot.telegram.getManagedBotAccessSettings(botUserId)
|
|
1839
|
+
console.log(settings)
|
|
1840
|
+
|
|
1841
|
+
// Set whitelist akses
|
|
1842
|
+
await bot.telegram.setManagedBotAccessSettings(botUserId, {
|
|
1843
|
+
is_public: false,
|
|
1844
|
+
allowed_user_ids: [123456, 789012],
|
|
1845
|
+
})
|
|
1846
|
+
```
|
|
1847
|
+
|
|
1848
|
+
### 16.15 Bot API 10.0 โ Get User Personal Chat Messages
|
|
1849
|
+
```js
|
|
1850
|
+
// Ambil pesan dari personal chat user (yang di-pin di profil mereka)
|
|
1851
|
+
const messages = await bot.telegram.getUserPersonalChatMessages(userId, {
|
|
1852
|
+
offset: 0,
|
|
1853
|
+
limit: 10,
|
|
1854
|
+
})
|
|
1855
|
+
```
|
|
1856
|
+
|
|
1857
|
+
### 16.16 Bot API 10.1 โ Join Request Queries
|
|
1858
|
+
Bot bisa merespons join request secara interaktif, termasuk membuka Mini App.
|
|
1859
|
+
|
|
1860
|
+
```js
|
|
1861
|
+
// Jawab join request query langsung
|
|
1862
|
+
bot.on('chat_join_request', async (ctx) => {
|
|
1863
|
+
await ctx.answerChatJoinRequestQuery({ action: 'approve' })
|
|
1864
|
+
})
|
|
1865
|
+
|
|
1866
|
+
// Buka Web App saat user minta join
|
|
1867
|
+
bot.on('chat_join_request', async (ctx) => {
|
|
1868
|
+
await ctx.sendChatJoinRequestWebApp('https://myapp.example.com/verify')
|
|
1869
|
+
})
|
|
1870
|
+
```
|
|
1871
|
+
|
|
1872
|
+
### 16.17 Bot API 10.1 โ Rich Messages
|
|
1873
|
+
Fitur paling besar: bot bisa mengirim pesan super terstruktur โ heading, tabel, list, blockquote, slideshow, math, dan lain-lain. Cocok untuk bot AI yang perlu format output kaya.
|
|
1874
|
+
|
|
1875
|
+
```js
|
|
1876
|
+
// Kirim rich message lengkap
|
|
1877
|
+
bot.on('message', async (ctx) => {
|
|
1878
|
+
await ctx.sendRichMessage({
|
|
1879
|
+
blocks: [
|
|
1880
|
+
{ type: 'section_heading', text: { type: 'plain', plain_text: '๐ Laporan Harian' } },
|
|
1881
|
+
{ type: 'divider' },
|
|
1882
|
+
{ type: 'paragraph', text: { type: 'rich_text', elements: [
|
|
1883
|
+
{ type: 'bold', elements: [{ type: 'text', text: 'Status: ' }] },
|
|
1884
|
+
{ type: 'text', text: 'Semua sistem berjalan normal.' }
|
|
1885
|
+
]}},
|
|
1886
|
+
{ type: 'list', style: 'bullet', items: [
|
|
1887
|
+
{ label: { type: 'plain', plain_text: 'Server UP' } },
|
|
1888
|
+
{ label: { type: 'plain', plain_text: 'DB OK' } },
|
|
1889
|
+
{ label: { type: 'plain', plain_text: 'Cache OK' } },
|
|
1890
|
+
]}
|
|
1891
|
+
]
|
|
1892
|
+
})
|
|
1893
|
+
})
|
|
1894
|
+
|
|
1895
|
+
// Streaming AI reply secara real-time (sendRichMessageDraft)
|
|
1896
|
+
bot.on('message', async (ctx) => {
|
|
1897
|
+
let draft = await ctx.sendRichMessageDraft({
|
|
1898
|
+
blocks: [{ type: 'paragraph', text: { type: 'plain', plain_text: 'Memproses...' } }]
|
|
1899
|
+
})
|
|
1900
|
+
|
|
1901
|
+
// Update bertahap saat AI menghasilkan teks
|
|
1902
|
+
for (const chunk of aiStream) {
|
|
1903
|
+
await bot.telegram.sendRichMessageDraft(ctx.chat.id, {
|
|
1904
|
+
message_id: draft.message_id,
|
|
1905
|
+
blocks: [{ type: 'paragraph', text: { type: 'plain', plain_text: chunk } }]
|
|
1906
|
+
})
|
|
1907
|
+
}
|
|
1908
|
+
})
|
|
1909
|
+
```
|
|
1910
|
+
|
|
1911
|
+
---
|
|
1912
|
+
|
|
1913
|
+
## 17. ๐ฌ Discord Bot (ElynnDiscord)
|
|
1914
|
+
Selain WhatsApp dan Telegram, elynn-baileys kini juga membungkus **Oceanic.js** secara penuh dengan nama `ElynnDiscord`. Artinya Anda bisa membangun bot Discord lengkap โ menangani pesan, slash commands, embeds, file upload, hingga sharding โ tanpa perlu menginstal package `oceanic.js` terpisah.
|
|
1915
|
+
|
|
1916
|
+
### 17.1 Setup Dasar & Login Bot
|
|
1917
|
+
```js
|
|
1918
|
+
import { ElynnDiscord } from 'elynn-baileys'
|
|
1919
|
+
|
|
1920
|
+
const client = new ElynnDiscord({
|
|
1921
|
+
auth: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
|
|
1922
|
+
gateway: {
|
|
1923
|
+
intents: ['GUILDS', 'GUILD_MESSAGES', 'MESSAGE_CONTENT']
|
|
1924
|
+
}
|
|
1925
|
+
})
|
|
1926
|
+
|
|
1927
|
+
client.on('ready', () => {
|
|
1928
|
+
console.log(`Bot Discord siap sebagai ${client.user.tag}`)
|
|
1929
|
+
})
|
|
1930
|
+
|
|
1931
|
+
client.connect()
|
|
1932
|
+
```
|
|
1933
|
+
|
|
1934
|
+
> **Catatan:** `MESSAGE_CONTENT` adalah *privileged intent*. Aktifkan di [Discord Developer Portal](https://discord.com/developers/applications) โ Bot โ Privileged Gateway Intents.
|
|
1935
|
+
|
|
1936
|
+
### 17.2 Menangani Event & Pesan
|
|
1937
|
+
```js
|
|
1938
|
+
import { ElynnDiscord } from 'elynn-baileys'
|
|
1939
|
+
|
|
1940
|
+
const client = new ElynnDiscord({
|
|
1941
|
+
auth: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
|
|
1942
|
+
gateway: {
|
|
1943
|
+
intents: ['GUILDS', 'GUILD_MESSAGES', 'MESSAGE_CONTENT']
|
|
1944
|
+
}
|
|
1945
|
+
})
|
|
1946
|
+
|
|
1947
|
+
client.on('ready', () => {
|
|
1948
|
+
console.log(`Online sebagai ${client.user.tag} (ID: ${client.user.id})`)
|
|
1949
|
+
})
|
|
1950
|
+
|
|
1951
|
+
client.on('messageCreate', async (msg) => {
|
|
1952
|
+
// Abaikan pesan dari bot lain
|
|
1953
|
+
if (msg.author.bot) return
|
|
1954
|
+
|
|
1955
|
+
const text = msg.content.trim()
|
|
1956
|
+
|
|
1957
|
+
if (text === '!ping') {
|
|
1958
|
+
await msg.channel.createMessage({ content: 'Pong! ๐' })
|
|
1959
|
+
}
|
|
1960
|
+
|
|
1961
|
+
if (text === '!info') {
|
|
1962
|
+
await msg.channel.createMessage({
|
|
1963
|
+
content: `Kamu ada di guild: **${msg.channel.guild.name}**`
|
|
1964
|
+
})
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
if (text.startsWith('!echo ')) {
|
|
1968
|
+
const kata = text.slice(6)
|
|
1969
|
+
await msg.channel.createMessage({ content: kata })
|
|
1970
|
+
}
|
|
1971
|
+
})
|
|
1972
|
+
|
|
1973
|
+
client.on('error', (err) => {
|
|
1974
|
+
console.error('Discord error:', err)
|
|
1975
|
+
})
|
|
1976
|
+
|
|
1977
|
+
client.connect()
|
|
1978
|
+
```
|
|
1979
|
+
|
|
1980
|
+
### 17.3 Slash Commands (Application Commands)
|
|
1981
|
+
Oceanic mendukung pendaftaran dan penanganan Application Commands (Slash Commands) secara native.
|
|
1982
|
+
```js
|
|
1983
|
+
import { ElynnDiscord } from 'elynn-baileys'
|
|
1984
|
+
|
|
1985
|
+
const client = new ElynnDiscord({
|
|
1986
|
+
auth: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
|
|
1987
|
+
gateway: { intents: ['GUILDS'] }
|
|
1988
|
+
})
|
|
1989
|
+
|
|
1990
|
+
client.on('ready', async () => {
|
|
1991
|
+
console.log(`Online sebagai ${client.user.tag}`)
|
|
1992
|
+
|
|
1993
|
+
// Daftarkan slash command secara global
|
|
1994
|
+
await client.application.bulkEditGlobalCommands([
|
|
1995
|
+
{ name: 'ping', description: 'Cek latensi bot' },
|
|
1996
|
+
{ name: 'info', description: 'Tampilkan info server' },
|
|
1997
|
+
{
|
|
1998
|
+
name: 'say',
|
|
1999
|
+
description: 'Bot mengulang pesan Anda',
|
|
2000
|
+
options: [{
|
|
2001
|
+
type: 3, // STRING
|
|
2002
|
+
name: 'pesan',
|
|
2003
|
+
description: 'Pesan yang akan diulang',
|
|
2004
|
+
required: true
|
|
2005
|
+
}]
|
|
2006
|
+
}
|
|
2007
|
+
])
|
|
2008
|
+
|
|
2009
|
+
console.log('Slash commands berhasil didaftarkan!')
|
|
2010
|
+
})
|
|
2011
|
+
|
|
2012
|
+
client.on('interactionCreate', async (interaction) => {
|
|
2013
|
+
if (!interaction.isCommandInteraction()) return
|
|
2014
|
+
|
|
2015
|
+
if (interaction.data.name === 'ping') {
|
|
2016
|
+
await interaction.createMessage({
|
|
2017
|
+
content: `๐ Pong! Latensi: **${client.shards.get(0)?.latency ?? '?'}ms**`
|
|
2018
|
+
})
|
|
2019
|
+
}
|
|
2020
|
+
|
|
2021
|
+
if (interaction.data.name === 'info') {
|
|
2022
|
+
const guild = interaction.guild
|
|
2023
|
+
await interaction.createMessage({
|
|
2024
|
+
content: `๐ Guild: **${guild?.name}** | Member: **${guild?.memberCount}**`
|
|
2025
|
+
})
|
|
2026
|
+
}
|
|
2027
|
+
|
|
2028
|
+
if (interaction.data.name === 'say') {
|
|
2029
|
+
const pesan = interaction.data.options.getString('pesan', true)
|
|
2030
|
+
await interaction.createMessage({ content: pesan })
|
|
2031
|
+
}
|
|
2032
|
+
})
|
|
2033
|
+
|
|
2034
|
+
client.connect()
|
|
2035
|
+
```
|
|
2036
|
+
|
|
2037
|
+
### 17.4 Embed & File Upload
|
|
2038
|
+
```js
|
|
2039
|
+
import { ElynnDiscord } from 'elynn-baileys'
|
|
2040
|
+
import { readFileSync } from 'fs'
|
|
2041
|
+
|
|
2042
|
+
const client = new ElynnDiscord({
|
|
2043
|
+
auth: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
|
|
2044
|
+
gateway: { intents: ['GUILDS', 'GUILD_MESSAGES', 'MESSAGE_CONTENT'] }
|
|
2045
|
+
})
|
|
2046
|
+
|
|
2047
|
+
client.on('messageCreate', async (msg) => {
|
|
2048
|
+
if (msg.author.bot) return
|
|
2049
|
+
|
|
2050
|
+
// Kirim Embed
|
|
2051
|
+
if (msg.content === '!embed') {
|
|
2052
|
+
await msg.channel.createMessage({
|
|
2053
|
+
embeds: [{
|
|
2054
|
+
title: '๐ Elynn Discord Bot',
|
|
2055
|
+
description: 'Bot Discord bertenaga **elynn-baileys** + Oceanic.js',
|
|
2056
|
+
color: 0x5865F2,
|
|
2057
|
+
fields: [
|
|
2058
|
+
{ name: '๐ฆ Library', value: 'elynn-baileys', inline: true },
|
|
2059
|
+
{ name: 'โก Engine', value: 'Oceanic.js', inline: true },
|
|
2060
|
+
{ name: '๐ Node', value: 'v20+', inline: true }
|
|
2061
|
+
],
|
|
2062
|
+
footer: { text: 'Made with โก by Elynn' },
|
|
2063
|
+
timestamp: new Date().toISOString()
|
|
2064
|
+
}]
|
|
2065
|
+
})
|
|
2066
|
+
}
|
|
2067
|
+
|
|
2068
|
+
// Upload file/gambar
|
|
2069
|
+
if (msg.content === '!upload') {
|
|
2070
|
+
const fileBuffer = readFileSync('./gambar.png')
|
|
2071
|
+
await msg.channel.createMessage({
|
|
2072
|
+
content: 'Ini file dari bot:',
|
|
2073
|
+
files: [{ name: 'gambar.png', contents: fileBuffer }]
|
|
2074
|
+
})
|
|
2075
|
+
}
|
|
2076
|
+
|
|
2077
|
+
// Embed + file sekaligus
|
|
2078
|
+
if (msg.content === '!report') {
|
|
2079
|
+
const reportBuffer = readFileSync('./report.pdf')
|
|
2080
|
+
await msg.channel.createMessage({
|
|
2081
|
+
embeds: [{
|
|
2082
|
+
title: '๐ Laporan Bulanan',
|
|
2083
|
+
description: 'File PDF terlampir di bawah.',
|
|
2084
|
+
color: 0x57F287
|
|
2085
|
+
}],
|
|
2086
|
+
files: [{ name: 'laporan-juni-2026.pdf', contents: reportBuffer }]
|
|
2087
|
+
})
|
|
2088
|
+
}
|
|
2089
|
+
})
|
|
2090
|
+
|
|
2091
|
+
client.connect()
|
|
2092
|
+
```
|
|
2093
|
+
|
|
2094
|
+
### 17.5 Sharding dengan ShardManager
|
|
2095
|
+
Untuk bot berskala besar (1000+ guild), gunakan `ShardManager` bawaan Oceanic untuk mendistribusikan koneksi gateway.
|
|
2096
|
+
```js
|
|
2097
|
+
import { ElynnDiscord } from 'elynn-baileys'
|
|
2098
|
+
|
|
2099
|
+
const client = new ElynnDiscord({
|
|
2100
|
+
auth: `Bot ${process.env.DISCORD_BOT_TOKEN}`,
|
|
2101
|
+
gateway: {
|
|
2102
|
+
intents: ['GUILDS', 'GUILD_MESSAGES', 'MESSAGE_CONTENT'],
|
|
2103
|
+
maxShards: 'auto' // Oceanic auto-hitung jumlah shard optimal
|
|
2104
|
+
}
|
|
2105
|
+
})
|
|
2106
|
+
|
|
2107
|
+
client.on('ready', () => {
|
|
2108
|
+
console.log(`${client.user.tag} online dengan ${client.shards.size} shard`)
|
|
2109
|
+
})
|
|
2110
|
+
|
|
2111
|
+
client.on('shardReady', (shardID) => {
|
|
2112
|
+
console.log(`Shard #${shardID} siap`)
|
|
2113
|
+
})
|
|
2114
|
+
|
|
2115
|
+
client.on('shardDisconnect', (err, shardID) => {
|
|
2116
|
+
console.warn(`Shard #${shardID} disconnect:`, err?.message)
|
|
2117
|
+
})
|
|
2118
|
+
|
|
2119
|
+
client.on('messageCreate', async (msg) => {
|
|
2120
|
+
if (msg.author.bot) return
|
|
2121
|
+
if (msg.content === '!shards') {
|
|
2122
|
+
const info = [...client.shards.values()]
|
|
2123
|
+
.map(s => `Shard #${s.id}: ${s.status} (${s.latency}ms)`)
|
|
2124
|
+
.join('\n')
|
|
2125
|
+
await msg.channel.createMessage({ content: `\`\`\`\n${info}\n\`\`\`` })
|
|
2126
|
+
}
|
|
2127
|
+
})
|
|
2128
|
+
|
|
2129
|
+
client.connect()
|
|
2130
|
+
```
|
|
2131
|
+
|
|
2132
|
+
### 17.6 Cek Koneksi Bot dengan `connectDiscord`
|
|
2133
|
+
Helper bawaan untuk memvalidasi token bot Discord secara cepat tanpa harus memulai koneksi gateway penuh โ cocok dipakai saat startup aplikasi untuk logging status atau health-check deployment.
|
|
2134
|
+
```js
|
|
2135
|
+
import { connectDiscord } from 'elynn-baileys'
|
|
2136
|
+
|
|
2137
|
+
const botInfo = await connectDiscord(process.env.DISCORD_BOT_TOKEN)
|
|
2138
|
+
if (botInfo) {
|
|
2139
|
+
console.log(`โ Discord terhubung sebagai ${botInfo.tag} (ID: ${botInfo.id})`)
|
|
2140
|
+
} else {
|
|
2141
|
+
console.log('โ Token Discord tidak valid atau koneksi gagal.')
|
|
2142
|
+
}
|
|
2143
|
+
```
|
|
2144
|
+
|
|
2145
|
+
Anda juga bisa mengecek ketersediaan token di environment sebelum mencoba konek:
|
|
2146
|
+
```js
|
|
2147
|
+
import { isDiscordAvailable, connectDiscord } from 'elynn-baileys'
|
|
2148
|
+
|
|
2149
|
+
if (isDiscordAvailable()) {
|
|
2150
|
+
const info = await connectDiscord(process.env.DISCORD_BOT_TOKEN)
|
|
2151
|
+
if (info) console.log(`[ โฆ ] DC: ${info.tag} (${info.id})`)
|
|
2152
|
+
} else {
|
|
2153
|
+
console.log('[ โฆ ] DC: DISCORD_BOT_TOKEN belum di-set, skip.')
|
|
2154
|
+
}
|
|
2155
|
+
```
|
|
2156
|
+
|
|
2157
|
+
```markdown
|
|
2158
|
+
### 17.7 [NEW 2026] Granular Access Control (Invite API)
|
|
2159
|
+
Discord API (`POST /channels/{channel.id}/invites`) telah diperluas untuk mendukung *Granular Access Control* level arsitektur. Hal ini menihilkan kebutuhan terhadap event listener `guildMemberAdd` yang memiliki tendensi *delay* latensi saat bot membaca rotasi pengguna yang masuk.
|
|
2160
|
+
|
|
2161
|
+
* **`target_users_file`**: Parameter *array* untuk membatasi eksekusi *link* undangan secara spesifik. *Link* undangan otomatis tertolak apabila *request* masuk berasal dari entitas pengguna yang tidak terdaftar di dalam parameter ini.
|
|
2162
|
+
* **`role_ids`**: Parameter *array* (contoh: `"role_ids": ["ROLE_ID_1"]`) yang memerintahkan *backend* server Discord untuk menyematkan *role* kepada pengguna secara instan tepat pada hitungan milidetik setelah *request* bergabung melalui *link* tersebut divalidasi.
|
|
2163
|
+
|
|
2164
|
+
### 17.8 [NEW 2026] Modals UI Components (Select Menus, Label, TextDisplay)
|
|
2165
|
+
Interaction Response dengan tipe `9` (Modal Submit) menerima pembaruan form sehingga tidak lagi membatasi *developer* hanya pada input tipe teks (Text Input).
|
|
2166
|
+
|
|
2167
|
+
* **Penerapan Komponen**: Di dalam objek *Action Rows*, kamu dapat merender langsung tipe `3` (*String Select*, *User Select*, *Role Select*, atau *Channel Select*).
|
|
2168
|
+
* **Penerapan Statis**: Untuk teks dengan panduan panjang tanpa harus menggunakan *readonly text field*, komponen `Label` dan `TextDisplay` dapat disematkan di parameter `components` tepat di atas struktur form. Pengumpulan *value* tetap berjalan seperti biasa dan ditangkap melalui *Interaction Create* event.
|
|
2169
|
+
|
|
2170
|
+
### 17.9 [NEW 2026] Server-Specific Bot Profiles (Per-Guild Profiles)
|
|
2171
|
+
Infrastruktur *Per-Guild Profiles* memungkinkan klien Elynn Discord untuk merender aset visual secara dinamis bergantung pada spesifikasi server tempat *request* dilontarkan. Ini memisahkan identitas bot global dengan identitas lokal.
|
|
2172
|
+
|
|
2173
|
+
* **Integrasi Endpoint**: Melalui *request* ke `PATCH /guilds/{guild.id}/members/@me`.
|
|
2174
|
+
* **Format *Payload***: Konstruksi JSON mengizinkan penyuntikan string *base64 encoded* di atribut `"avatar"`, modifikasi `"nick"` untuk menimpa panggilan lokal, serta metadata bio spesifik untuk profil server lokal. Skema ini mengizinkan token aplikasi bot tunggal mereplikasi ribuan konfigurasi visual independen.
|
|
2175
|
+
|
|
2176
|
+
### 17.10 [NEW 2026] Threshold Intents (10k Users) & Moderation Metadata
|
|
2177
|
+
Infrastruktur *Privileged Gateway Intents* diatur ulang untuk sinkronisasi metadata secara lintas *platform* (terutama melalui Social SDK 1.8+).
|
|
2178
|
+
|
|
2179
|
+
* **Moderation Metadata**: Elynn Discord kini dapat mengatur transfer struktur *key-value* khusus kepada *server backend* eksternal. Informasi hukuman, limitasi akses, dan metadata pembatasan akun disinkronkan secara *real-time* menghindari latensi eskalasi konflik di Discord.
|
|
2180
|
+
* **Peninjauan Ambang Batas Pengguna**: Kalkulasi kepemilikan *Privileged Intents* (`MESSAGE_CONTENT`, `GUILD_MEMBERS`, dll) tidak lagi dihitung berdasarkan agregasi server. Discord mengunci ambang batas pada jangkauan kumulatif 10.000 pengguna individu. Seluruh *platform* aplikasi diwajibkan untuk memvalidasi alur izin *intent* tersebut secara manual per putaran verifikasi tahunan di dalam dasbor Developer Portal.
|
|
2181
|
+
---
|
|
2182
|
+
|
|
2183
|
+
## 18. ๐งช testMessage โ Tes Semua Jenis Pesan
|
|
2184
|
+
|
|
2185
|
+
`testMessage` adalah fungsi utilitas eksklusif elynn-baileys untuk **menguji pengiriman semua jenis pesan Baileys** secara cepat โ bisa dipakai di grup maupun private chat, tanpa perlu set target/total kirim. Cukup reply atau panggil di handler bot mana pun.
|
|
2186
|
+
|
|
2187
|
+
### Cara import & penggunaan
|
|
2188
|
+
|
|
2189
|
+
```js
|
|
2190
|
+
import { testMessage } from 'elynn-baileys'
|
|
2191
|
+
|
|
2192
|
+
// Di handler pesan:
|
|
2193
|
+
sock.ev.on('messages.upsert', async ({ messages }) => {
|
|
2194
|
+
for (const msg of messages) {
|
|
2195
|
+
const text = msg.message?.conversation || msg.message?.extendedTextMessage?.text || ''
|
|
2196
|
+
const jid = msg.key.remoteJid
|
|
2197
|
+
|
|
2198
|
+
if (text === '.testmsg' || text === '.test') {
|
|
2199
|
+
// Jalankan test โ akan kirim 16 jenis pesan secara berurutan
|
|
2200
|
+
await testMessage(sock, jid)
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
// Dengan quoted (reply ke pesan tertentu, termasuk tes reaction + edit)
|
|
2204
|
+
if (text === '.testquoted') {
|
|
2205
|
+
await testMessage(sock, jid, { quoted: msg })
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
})
|
|
2209
|
+
```
|
|
2210
|
+
|
|
2211
|
+
### Signature lengkap
|
|
2212
|
+
|
|
2213
|
+
```js
|
|
2214
|
+
/**
|
|
2215
|
+
* @param {WASocket} sock - instance dari makeWASocket()
|
|
2216
|
+
* @param {string} jid - target JID: grup (@g.us) atau private (@s.whatsapp.net)
|
|
2217
|
+
* @param {object} [opts]
|
|
2218
|
+
* @param {object} [opts.quoted] - pesan yang di-quote (untuk tes reaction, edit, dll)
|
|
2219
|
+
* @param {number} [opts.delay] - jeda antar pesan dalam ms (default: 500)
|
|
2220
|
+
*/
|
|
2221
|
+
await testMessage(sock, jid, { quoted: msg, delay: 700 })
|
|
2222
|
+
```
|
|
2223
|
+
|
|
2224
|
+
### Yang diuji (16 jenis pesan)
|
|
2225
|
+
|
|
2226
|
+
| # | Jenis Pesan | Keterangan |
|
|
2227
|
+
|---|-----------------------|---------------------------------------------------|
|
|
2228
|
+
| 1 | Text biasa | Plain text message |
|
|
2229
|
+
| 2 | Text + Mention | Mention member (group: semua, private: self) |
|
|
2230
|
+
| 3 | Image | Gambar dari URL + caption |
|
|
2231
|
+
| 4 | Video | Video dari URL + caption |
|
|
2232
|
+
| 5 | Audio | Audio musik (bukan PTT) |
|
|
2233
|
+
| 6 | PTT Voice Note | Voice note dengan codec opus |
|
|
2234
|
+
| 7 | Document | File PDF dengan filename |
|
|
2235
|
+
| 8 | Sticker | Stiker dari URL gambar |
|
|
2236
|
+
| 9 | Location | Koordinat lokasi |
|
|
2237
|
+
|10 | Contact / vCard | Kartu kontak WA |
|
|
2238
|
+
|11 | Reaction | Emoji reaction (jika `quoted` disediakan) |
|
|
2239
|
+
|12 | Edit Message | Kirim pesan โ tunggu โ edit isinya |
|
|
2240
|
+
|13 | Delete Message | Kirim pesan โ tunggu โ hapus |
|
|
2241
|
+
|14 | Forward Simulation | Simulasi forward (tanpa pesan asli) |
|
|
2242
|
+
|15 | Buttons (Legacy) | Tombol interaktif legacy |
|
|
2243
|
+
|16 | List Message | Pesan daftar pilihan (list) |
|
|
2244
|
+
|
|
2245
|
+
> Semua tes berjalan **async berurutan** dengan jeda antar pesan. Bekerja di grup maupun private chat tanpa konfigurasi tambahan.
|
|
2246
|
+
|
|
2247
|
+
---
|
|
2248
|
+
|
|
2249
|
+
## 19. ๐ sessionGuard โ Proteksi Session dari Pencurian
|
|
2250
|
+
|
|
2251
|
+
`sessionGuard` adalah fitur keamanan opsional yang **mengunci session WhatsApp ke IP server pertama kali bot dijalankan**. Jika session dicuri dan dicoba dijalankan di server lain, bot akan otomatis diblokir dan dihentikan paksa.
|
|
2252
|
+
|
|
2253
|
+
> **Tidak dipanggil = tidak ada proteksi** (default behaviour tetap normal)
|
|
2254
|
+
|
|
2255
|
+
### Cara Import
|
|
2256
|
+
|
|
2257
|
+
```js
|
|
2258
|
+
import { sessionGuard, isGuardActive, resetGuard } from 'elynn-baileys'
|
|
2259
|
+
```
|
|
2260
|
+
|
|
2261
|
+
### Penggunaan Dasar
|
|
2262
|
+
|
|
2263
|
+
Panggil `sessionGuard()` **sebelum** `makeWASocket`:
|
|
2264
|
+
|
|
2265
|
+
```js
|
|
2266
|
+
import { makeWASocket, useMultiFileAuthState } from 'elynn-baileys'
|
|
2267
|
+
import { sessionGuard } from 'elynn-baileys'
|
|
2268
|
+
|
|
2269
|
+
const { state, saveCreds } = await useMultiFileAuthState('./auth_state')
|
|
2270
|
+
|
|
2271
|
+
// Aktifkan guard โ wajib dipanggil sebelum makeWASocket
|
|
2272
|
+
await sessionGuard()
|
|
2273
|
+
|
|
2274
|
+
const sock = makeWASocket({ auth: state })
|
|
2275
|
+
sock.ev.on('creds.update', saveCreds)
|
|
2276
|
+
```
|
|
2277
|
+
|
|
2278
|
+
### Opsi Lengkap
|
|
2279
|
+
|
|
2280
|
+
```js
|
|
2281
|
+
await sessionGuard({
|
|
2282
|
+
sessionFile: './auth_state/creds.json', // path ke file session (default: './auth_state.json')
|
|
2283
|
+
silent: false, // true = sembunyikan log guard (default: false)
|
|
2284
|
+
onBlock: async ({ currentIP, guardPath }) => {
|
|
2285
|
+
// Callback dipanggil saat session diblokir karena IP beda
|
|
2286
|
+
console.log('Session diblokir! IP saat ini:', currentIP)
|
|
2287
|
+
// Bisa kirim notif ke owner di sini
|
|
2288
|
+
}
|
|
2289
|
+
})
|
|
2290
|
+
```
|
|
2291
|
+
|
|
2292
|
+
| Opsi | Type | Default | Keterangan |
|
|
2293
|
+
|------|------|---------|------------|
|
|
2294
|
+
| `sessionFile` | `string` | `'./auth_state.json'` | Path ke file session WA |
|
|
2295
|
+
| `silent` | `boolean` | `false` | Sembunyikan log info guard |
|
|
2296
|
+
| `onBlock` | `function` | `null` | Callback dipanggil sebelum `process.exit(1)` saat IP mismatch |
|
|
2297
|
+
|
|
2298
|
+
### Cara Kerja
|
|
2299
|
+
|
|
2300
|
+
1. **Pertama kali dijalankan** โ Guard ambil IP publik server, hash dengan SHA-256, simpan ke file `.elynn_guard` di folder yang sama dengan session.
|
|
2301
|
+
2. **Jalankan berikutnya** โ Guard bandingkan IP server sekarang dengan hash yang tersimpan.
|
|
2302
|
+
3. **IP cocok** โ Bot lanjut normal โ
|
|
2303
|
+
4. **IP beda** โ Bot cetak pesan error dan `process.exit(1)` โ
|
|
2304
|
+
|
|
2305
|
+
> IP disimpan dalam bentuk **hash SHA-256**, bukan plaintext โ aman meski file `.elynn_guard` bocor.
|
|
2306
|
+
|
|
2307
|
+
### Cek Status Guard
|
|
2308
|
+
|
|
2309
|
+
```js
|
|
2310
|
+
import { isGuardActive } from 'elynn-baileys'
|
|
2311
|
+
|
|
2312
|
+
if (isGuardActive()) {
|
|
2313
|
+
console.log('Session guard aktif')
|
|
2314
|
+
}
|
|
2315
|
+
```
|
|
2316
|
+
|
|
2317
|
+
### Reset Guard (Pindah Server)
|
|
2318
|
+
|
|
2319
|
+
Jika lo pindah server secara sah, hapus guard lama dulu sebelum jalankan bot:
|
|
2320
|
+
|
|
2321
|
+
```js
|
|
2322
|
+
import { resetGuard } from 'elynn-baileys'
|
|
2323
|
+
|
|
2324
|
+
await resetGuard('./auth_state/creds.json')
|
|
2325
|
+
// Output: [ โฆ ] ELYNN GUARD: Guard direset, silakan jalankan ulang bot.
|
|
2326
|
+
```
|
|
2327
|
+
|
|
2328
|
+
Atau hapus manual file `.elynn_guard` dari folder session lo, lalu jalankan bot kembali.
|
|
2329
|
+
|
|
2330
|
+
### Contoh Output Log
|
|
2331
|
+
|
|
2332
|
+
**Pertama kali (registrasi):**
|
|
2333
|
+
```
|
|
2334
|
+
[ โฆ ] ELYNN GUARD: Mengaktifkan proteksi session...
|
|
2335
|
+
[ โฆ ] ELYNN GUARD: IP Server: 103.xx.xx.xx
|
|
2336
|
+
[ โฆ ] ELYNN GUARD: Session terdaftar di server ini โ
|
|
2337
|
+
```
|
|
2338
|
+
|
|
2339
|
+
**Jalankan normal (IP cocok):**
|
|
2340
|
+
```
|
|
2341
|
+
[ โฆ ] ELYNN GUARD: Mengaktifkan proteksi session...
|
|
2342
|
+
[ โฆ ] ELYNN GUARD: IP Server: 103.xx.xx.xx
|
|
2343
|
+
[ โฆ ] ELYNN GUARD: IP cocok, session aman โ
|
|
2344
|
+
```
|
|
2345
|
+
|
|
2346
|
+
**Session dicuri (IP beda):**
|
|
2347
|
+
```
|
|
2348
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2349
|
+
โ โ ๏ธ ELYNN GUARD โ SESSION BLOCK
|
|
2350
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2351
|
+
Session ini tidak bisa digunakan
|
|
2352
|
+
di server ini karena IP berbeda.
|
|
2353
|
+
|
|
2354
|
+
Session hanya bisa berjalan di
|
|
2355
|
+
server tempat session dibuat.
|
|
2356
|
+
|
|
2357
|
+
Jika ini server kamu sendiri,
|
|
2358
|
+
hapus file: .elynn_guard
|
|
2359
|
+
lalu jalankan ulang bot.
|
|
2360
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
2361
|
+
```
|
|
2362
|
+
|
|
2363
|
+
> **Catatan:** Fitur ini tidak 100% foolproof jika server menggunakan IP dinamis (berubah setiap restart). Untuk VPS dengan IP statis, perlindungan ini sangat efektif.
|
|
2364
|
+
|
|
2365
|
+
---
|
|
2366
|
+
## โฆ Credits & License
|
|
2367
|
+
Elynn Baileys dibangun di atas pondasi [Baileys](https://github.com/WhiskeySockets/Baileys) oleh Rajeh Taher/WhiskeySockets, dan diperluas oleh **Elynn** dengan integrasi Telegram Bot, plugin Brat/Bratvid bawaan, dukungan protokol WhatsApp 2026, serta berbagai peningkatan stabilitas.
|
|
2368
|
+
|
|
2369
|
+
Dirilis di bawah lisensi **MIT**.
|
|
2370
|
+
Copyright ยฉ 2025 Rajeh Taher/WhiskeySockets ยท Copyright ยฉ 2026 **Elynn**
|
|
2371
|
+
|
|
2372
|
+
*Made with โก by Elynn*
|