slackdb v0.1.1 SlackDB View Source

GenServer that is responsible for all interactions with SlackDB.

On startup, the server will load into memory the current state of the server (as described in the supervisor channel). All changes to state (channel additions and archivals) made through this API will be updated and persisted in the supervisor channel

Link to this section Summary

Types

Types of SlackDB keys represented as atoms

More key metadata options represented as atoms

Represents the types of values that keys can hold. Since all values are stored in Slack, they are all returned as strings (or a list of strings in the case of key_type :multiple)

Functions

Appends values to the current thread of the key (maintaining history)

Archives a channel and removes it from the state of the database

Returns a specification to start this module under a supervisor.

Create a key/value pair in the specified server and channel of the given type

Deletes a key and it's associated thread

Returns a map representing the current state of the database

Includes an existing channel and updates the state of the database

Invites a user_id or a list of user_ids to the supervisor channel of a specified server

Invites a user_id or a list of user_ids to a specified channel

Creates a new channel and updates the current state of the database

Reads a key in the given server and channel

Reads a key in the given server and channel, raising an error if anything went wrong

Start genserver, pull server config from application environment and pass to init/1

Overwrites the current value of the key by deleting the current thread and posting new values (sacrificing rollback)

Link to this section Types

Link to this type

key_type() View Source
key_type() :: :voting | :multiple | :single_front | :single_back

Types of SlackDB keys represented as atoms

Types

  • :voting - replies to keys are treated as a ballot where reactions represent support for that particular value. winner takes all.
  • :multiple - the reply thread represents an array that is returned in full and in chronological order
  • :single_front - the first reply to the key is the value
  • :single_back - the most recent reply to the key is the value
Link to this type

more_metadata() View Source
more_metadata() :: :constant | :undeletable

More key metadata options represented as atoms

Types

  • :constant - key cannot changed after creation (save for deletion)
  • :undeletable - key cannot be deleted (through this API)

Represents the types of values that keys can hold. Since all values are stored in Slack, they are all returned as strings (or a list of strings in the case of key_type :multiple)

Link to this section Functions

Link to this function

append(server_name, channel_name, key_phrase, value) View Source
append(String.t(), String.t(), String.t(), value()) ::
  {:error, String.t()} | [tuple()]

Appends values to the current thread of the key (maintaining history)

You can use this to append to the list of keys with type :multiple. Or to add voting options to :voting keys. Or to change the value of :single_back keys

This function returns an error tuple or a list of tuples indicating the result of posting each value.

Example

iex> SlackDB.append("dog_shelter", "adopted", "Chihuahuas", "Ren")
[
  ok: %{
    "channel" => "CHU427918",
    "message" => %{...},
    "ok" => true,
    "ts" => "1556129092.000800"
  }
]
Link to this function

archive_channel(server_name, channel_name) View Source
archive_channel(String.t(), String.t()) :: {:error, String.t()} | {:ok, map()}

Archives a channel and removes it from the state of the database

Example

iex> SlackDB.archive_channel("dog_shelter", "coops-winter-2019")
{:ok, "channel archived"}

Returns a specification to start this module under a supervisor.

See Supervisor.

Link to this function

create(server_name, channel_name, key_phrase, value, key_type, add_metadata \\ []) View Source
create(String.t(), String.t(), String.t(), value(), key_type(), [
  more_metadata()
]) :: {:error, String.t()} | [tuple()]

Create a key/value pair in the specified server and channel of the given type

This essentially overwrites the key if it already exist. It posts a new message that will always be prioritized by read/4 because it is more recent.

The value passed in may be either a String or a list of Strings that will be posted in the key's thread, in order. You can specify additional metadata to be added to the key using an optional list.

This function returns an error tuple or a list of tuples indicating the result of posting each value. The channel that is specified must exist in the scope of the server.

Example

iex> SlackDB.create("dog_shelter", "adopted", "Beagles", ["Buddy", "Rufus"], :multiple, [:undeletable])
[
  ok: %{
    "channel" => "CHU427918",
    "message" => %{...},
    "ok" => true,
    "ts" => "1556129092.000800"
  },
  ok: %{
    "channel" => "CHU427918",
    "message" => %{...},
    "ok" => true,
    "ts" => "1556129093.001000"
  }
]
Link to this function

delete(server_name, channel_name, key_phrase) View Source
delete(String.t(), String.t(), String.t()) :: {:error, String.t()} | [tuple()]

Deletes a key and it's associated thread

Beware of rate_limiting issues discussed in the README

This function returns an error tuple or a list of tuples indicating the result of deleting each message in the thread.

Example

iex> SlackDB.delete("dog_shelter", "yet-to-be-adopted", "Chihuahuas")
[
  ok: %{
    "channel" => "CHU427918",
    "message" => %{...},
    "ok" => true,
    "ts" => "1556129092.000800"
  },
]

Returns a map representing the current state of the database

Example

iex> SlackDB.dump()
%{
  "dog_shelter" => %{
    bot_name: "Jeanie",
    bot_token: "xoxb-shhh...",
    user_token: "xoxp-shhh..."
    channels: %{
      "adopted" => "CHU427918",
      "yet-to-be-adopted" => "CJ57Z7QS1"
    },
    supervisor_channel_id: "CFC6MRQ06",
    supervisor_channel_name: "slackdb-admin",
  }
}
Link to this function

include_channel(server_name, channel_name) View Source
include_channel(String.t(), String.t()) :: {:error, String.t()} | {:ok, map()}

Includes an existing channel and updates the state of the database

A channel must exist in the current state of the databse to create keys or to invite users Since bots cannot add themselves to channels, you must also add the bot manually once the channel is included.

Example

iex> SlackDB.include_channel("dog_shelter", "employees")
{:ok, "channel added"}
Link to this function

invite_supervisors(server_name, user_id) View Source
invite_supervisors(String.t(), String.t() | [String.t()]) ::
  {:error, String.t()} | {:ok, map()}

Invites a user_id or a list of user_ids to the supervisor channel of a specified server

Example

iex> SlackDB.invite_supervisors("dog_shelter", ["USERID1", "USERID2"])
{:ok, %{"name" => "adopted", "id" => "CHU427918"}}
Link to this function

invite_to_channel(server_name, channel_name, user_id) View Source
invite_to_channel(String.t(), String.t(), String.t() | [String.t()]) ::
  {:error, String.t()} | {:ok, map()}

Invites a user_id or a list of user_ids to a specified channel

Example

iex> SlackDB.invite_to_channel("dog_shelter", "adopted", ["USERID1", "USERID2"])
{:ok, %{"name" => "adopted", "id" => "CHU427918"}}
Link to this function

new_channel(server_name, channel_name, is_private?) View Source
new_channel(String.t(), String.t(), boolean()) ::
  {:error, String.t()} | {:ok, map()}

Creates a new channel and updates the current state of the database

A channel must exist in the current state of the databse to create keys or to invite users. Since bots cannot add themselves to channels, you must also add the bot manually once the channel is created.

Example

iex> SlackDB.new_channel("dog_shelter", "volunteers", false)
{:ok, "channel added"}
Link to this function

read(server_name, channel_name, key_phrase, only_bot? \\ true) View Source
read(String.t(), String.t(), String.t(), boolean()) ::
  {:error, String.t()} | {:ok, value()}

Reads a key in the given server and channel

This will always pull from the most recently posted message that matches the key schema.

Setting only_bot? to true will search only for keys posted under the bot name specified in the config.

Example

iex> SlackDB.read("dog_shelter", "adopted", "Beagles")
{:ok, ["Buddy", "Rufus"]}
Link to this function

read!(server_name, channel_name, key_phrase, only_bot? \\ true) View Source
read!(String.t(), String.t(), String.t(), boolean()) :: value()

Reads a key in the given server and channel, raising an error if anything went wrong

This will always pull from the most recently posted message that matches the key schema.

Setting only_bot? to true will search only for keys posted under the bot name specified in the config.

Example

iex> SlackDB.read!("dog_shelter", "adopted", "Beagles")
["Buddy", "Rufus"]

Start genserver, pull server config from application environment and pass to init/1

Link to this function

update(server_name, channel_name, key_phrase, value) View Source
update(String.t(), String.t(), String.t(), value()) ::
  {:error, String.t()} | [tuple()]

Overwrites the current value of the key by deleting the current thread and posting new values (sacrificing rollback)

This is the only way to change the value of a :single_front key.

This function returns an error tuple or a list of tuples indicating the result of posting each value.

Example

iex> SlackDB.update("dog_shelter", "adopted", "Chihuahuas", "Ren")
[
  ok: %{
    "channel" => "CHU427918",
    "message" => %{...},
    "ok" => true,
    "ts" => "1556129092.000800"
  },
]