Skip to content

Commit

Permalink
Merge pull request #559 from Kraigie/jb3/cheat-sheets
Browse files Browse the repository at this point in the history
Add cheat sheets
  • Loading branch information
jb3 authored May 4, 2024
2 parents 4ca164c + fd9bf42 commit 52a4316
Show file tree
Hide file tree
Showing 3 changed files with 221 additions and 2 deletions.
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

0 comments on commit 52a4316

Please sign in to comment.