Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add cheat sheets #559

Merged
merged 6 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 139 additions & 0 deletions guides/cheat-sheets/api.cheatmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# API Usage

This cheat sheet covers basic use of the Discord API through the `Nostrum.Api` module.

## Messages
{: .col-2}

### Sending a message

```elixir
utc_now = DateTime.utc_now
atom_count = :erlang.system_info(:atom_count)

content = """
UTC time is: #{DateTime.to_iso8601(utc_now)}
Atom table size is: #{atom_count}
"""

Nostrum.Api.create_message(msg.channel_id, content)
```

### Sending a message with an embed

```elixir
import Nostrum.Struct.Embed

embed =
%Nostrum.Struct.Embed{}
|> put_title("Craig's Cats")
|> put_description("nostrum")
|> put_url("https://google.com/")
|> put_timestamp("2016-05-05T21:04:13.203Z")
|> put_color(431_948)
|> put_field("Field 1", "Test")
# set inline attribute to true
|> put_field("Field 2", "More test", true)

Nostrum.Api.create_message(msg.channel_id, embeds: [embed])
```

You can look at the documentation in `m:Nostrum.Struct.Embed#module-using-structs` for more advanced usage.

### Upload an attachment

```elixir
Nostrum.Api.create_message(
msg.channel_id,
files: [
# file from filesystem
"/path/to/file.txt",
# file from memory
%{body: "test file", name: "example.txt"}
]
)
```

### Reply to a message

With a mention:

```elixir
Nostrum.Api.create_message(
msg.channel_id,
content: "Hello!",
message_reference: %{message_id: msg.id}
)
```

Without a mention:

```elixir
Nostrum.Api.create_message(
msg.channel_id,
content: "Hello!",
message_reference: %{message_id: msg.id},
allowed_mentions: :none
)
```

### Send a poll

```elixir
poll = Poll.create_poll(
"Do you enjoy pineapple on pizza?",
duration: 2,
allow_multiselect: false
)
|> Poll.put_answer("Yes!", default_emoji: "\u2705")
|> Poll.put_answer("No!", default_emoji: "\u274C")

Api.create_message(channel_id, poll: poll)
```

### React to a message

Using a default emoji (unicode representation):
```elixir
Nostrum.Api.create_reaction(
msg.channel_id,
msg.id,
"👾"
)
```

Using a custom Discord emoji:
```elixir
emoji = %Nostrum.Struct.Emoji{
name: "emojiname",
id: 1228698654022434866
}

Nostrum.Api.create_reaction(msg.channel_id, msg.id, emoji)
```

## Miscellaneous
{: .col-2}

### Update the bot status

```elixir
Nostrum.Api.update_status(
:dnd,
"craigs cats",
3 # Watching status
)
```
You can also update a single shard with `Nostrum.Api.update_shard_status/5`.

### Create a guild emoji

```elixir
image = "data:image/png;base64,..."

Nostrum.Api.create_guild_emoji(
msg.guild_id,
name: "nostrum",
image: image
)
```
77 changes: 77 additions & 0 deletions guides/cheat-sheets/qlc.cheatmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# QLC Usage

This cheat sheet covers some example queries using Query-List Comprehensions in Erlang, as well as some debugging tips.

QLC modules must include this library include as part of their prelude:

```erl
-include_lib("stdlib/include/qlc.hrl").
```

As per the Erlang docs for QLC:

> This causes a parse transform to substitute a fun for the QLC. The (compiled) fun is called when the query handle is evaluated.

## Examples

### Fetch role members

```erl
find_role_users(RequestedGuildId, RoleId, MemberCache) ->
qlc:q([{User, Member} || {{GuildId, MemberId}, Member} <- MemberCache:query_handle(),
% Filter to member objects of the selected guild
GuildId =:= RequestedGuildId,
% Filter to members of the provided role
lists:member(RoleId, map_get(roles, Member))]).
```

### Fetch guilds over a certain size

```erl
find_large_communities(Threshold, GuildCache) ->
qlc:q([Guild || {_, Guild} <- GuildCache:query_handle(),
% Filter for guilds that are over the provided size
map_get(member_count, Guild) > Threshold]).
```

### Find all online users in a guild

```erl
find_online_users(RequestedGuildId, PresenceCache, UserCache) ->
qlc:q([User || {{GuildId, PresenceUserId}, Presence} <- PresenceCache:query_handle(),
% Filter to members in the requested guild ID
GuildId =:= RequestedGuildId,
% Fetch any members where the status is not offline
map_get(status, Presence) /= offline,
% Join the found users on the UserCache
{UserId, User} <- UserCache:query_handle(),
% Return the users that match the found presences
UserId =:= PresenceUserId]).
```

This depends on the guild presences intent being enabled and the bot storing received presences in the presence cache.

## Debugging QLC

{: .col-2 }

### View query info

You can use `:qlc.info/1` to evaluate how Erlang will parse a query. You can read the Erlang docs for an explanation of the value returned by this call

```elixir
:qlc.info(
:my_queries.find_users(..., Nostrum.Cache.UserCache)
)
```

### Sampling a query

You can return only X records that match a query using `:qlc.next_answers/2`, passing in the query as the first argument and the number of answers to return as the second argument.

```elixir
:qlc.next_answers(
:my_queries.find_users(..., Nostrum.Cache.UserCache),
5
)
```
7 changes: 5 additions & 2 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ defmodule Nostrum.Mixfile do
Introduction: ~r"/introduction/",
Functionality: ~r"/functionality/",
Configuration: ~r"/configuration/",
Advanced: ~r"/advanced/"
Advanced: ~r"/advanced/",
"Cheat Sheets": ~r"/cheat-sheets/"
],
source_ref: "master",
assets: "guides/assets",
Expand Down Expand Up @@ -79,7 +80,9 @@ defmodule Nostrum.Mixfile do
"guides/functionality/voice.md",
"guides/advanced/pluggable_caching.md",
"guides/advanced/multi_node.md",
"guides/advanced/hot_code_upgrade.md"
"guides/advanced/hot_code_upgrade.md",
"guides/cheat-sheets/api.cheatmd",
"guides/cheat-sheets/qlc.cheatmd"
]
end

Expand Down