-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
aa96d3c
commit 49f44b8
Showing
11 changed files
with
254 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# editorconfig.org | ||
root = true | ||
|
||
[*] | ||
indent_size = 2 | ||
indent_style = space | ||
end_of_line = lf | ||
charset = utf-8 | ||
trim_trailing_whitespace = true | ||
insert_final_newline = true | ||
|
||
[*.md] | ||
trim_trailing_whitespace = false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,3 +22,4 @@ erl_crash.dump | |
# Ignore package tarball (built via "mix hex.build"). | ||
tmi-*.tar | ||
|
||
secret.exs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,21 +1,38 @@ | ||
# tmi.ex | ||
|
||
**TODO: Add description** | ||
Connect to Twitch chat with Elixir. | ||
|
||
Inspired by [tmi.js](https://github.com/tmijs/tmi.js). | ||
|
||
## Installation | ||
|
||
If [available in Hex](https://hex.pm/docs/publish), the package can be installed | ||
by adding `tmi` to your list of dependencies in `mix.exs`: | ||
The package can be installed by adding `tmi` to your list of dependencies in `mix.exs`: | ||
|
||
```elixir | ||
def deps do | ||
[ | ||
{:tmi, "~> 0.1.0"} | ||
{:tmi, "~> 0.1.0"}, | ||
] | ||
end | ||
``` | ||
|
||
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) | ||
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can | ||
be found at [https://hexdocs.pm/tmi](https://hexdocs.pm/tmi). | ||
Documentation can be found at [https://hexdocs.pm/tmi/readme.html](https://hexdocs.pm/tmi/readme.html). | ||
|
||
## Usage | ||
|
||
You can use your own Twitch username, but it is recommended to make a new twitch account just for your bot. | ||
You'll also need an OAuth token for the password. | ||
|
||
The simplest method to get an OAuth token (while logged in to the account your bot will be) use the [Twitch Chat OAuth Password Generator](https://twitchapps.com/tmi/). | ||
|
||
To connect, start the supervisor with: | ||
|
||
```elixir | ||
user = "mybotusername" | ||
pass = "oauth:mybotoauthtoken" | ||
chats = ["mychat", "myfriendschat"] | ||
|
||
{:ok, _pid} = TMI.Supervisor.start_link(user, pass, chats) | ||
``` | ||
|
||
#### TODO: All the typical bot stuff. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,3 @@ | ||
defmodule TMI do | ||
@moduledoc """ | ||
Documentation for `TMI`. | ||
""" | ||
|
||
@doc """ | ||
Hello world. | ||
## Examples | ||
iex> TMI.hello() | ||
:world | ||
""" | ||
def hello do | ||
:world | ||
end | ||
@moduledoc false | ||
end |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
defmodule TMI.Conn do | ||
@moduledoc false | ||
|
||
defstruct( | ||
server: "irc.chat.twitch.tv", | ||
port: 6697, | ||
pass: nil, | ||
nick: nil, | ||
user: nil, | ||
name: nil, | ||
client: nil, | ||
channels: [] | ||
) | ||
|
||
@type t :: %__MODULE__{ | ||
server: String.t(), | ||
port: integer, | ||
pass: String.t(), | ||
nick: String.t(), | ||
user: String.t(), | ||
name: String.t(), | ||
client: pid, | ||
channels: [String.t()] | ||
} | ||
|
||
def new(client, user, pass, channels) do | ||
%__MODULE__{ | ||
client: client, | ||
name: user, | ||
nick: user, | ||
user: user, | ||
pass: pass, | ||
channels: channels | ||
} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
defmodule TMI.Handlers.ConnectionHandler do | ||
@moduledoc false | ||
use GenServer | ||
|
||
require Logger | ||
|
||
alias TMI.Conn | ||
|
||
def start_link(%Conn{} = conn) do | ||
GenServer.start_link(__MODULE__, conn, name: __MODULE__) | ||
end | ||
|
||
## Callbacks | ||
|
||
@impl GenServer | ||
def init(%Conn{} = conn) do | ||
Logger.debug("Connecting to #{conn.server}:#{conn.port}") | ||
|
||
ExIRC.Client.add_handler(conn.client, self()) | ||
ExIRC.Client.connect_ssl!(conn.client, conn.server, conn.port) | ||
|
||
{:ok, conn} | ||
end | ||
|
||
@impl GenServer | ||
def handle_info({:connected, server, port}, conn) do | ||
Logger.debug("Connected to #{server}:#{port}. Logging in as #{conn.nick}") | ||
Logger.debug("Logging in as #{conn.nick}..") | ||
ExIRC.Client.logon(conn.client, conn.pass, conn.nick, conn.user, conn.name) | ||
{:noreply, conn} | ||
end | ||
|
||
def handle_info(:disconnected, conn) do | ||
Logger.debug("Disconnected from #{conn.server}:#{conn.port}") | ||
{:stop, :normal, conn} | ||
end | ||
|
||
# Catch-all for messages you don't care about | ||
def handle_info(_msg, conn) do | ||
{:noreply, conn} | ||
end | ||
|
||
@impl GenServer | ||
def terminate(_, conn) do | ||
# Quit the channels and close the underlying client connection when the process is terminating | ||
Logger.warn("Terminating...") | ||
ExIRC.Client.quit(conn.client, "Goodbye, cruel world.") | ||
ExIRC.Client.stop!(conn.client) | ||
:ok | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
defmodule TMI.Handlers.LoginHandler do | ||
@moduledoc false | ||
|
||
use GenServer | ||
|
||
require Logger | ||
|
||
alias TMI.Conn | ||
|
||
@tmi_capabilities ['membership', 'tags', 'commands'] | ||
|
||
def start_link(%Conn{} = conn) do | ||
GenServer.start_link(__MODULE__, conn) | ||
end | ||
|
||
## Callbacks | ||
|
||
@impl true | ||
def init(%Conn{} = conn) do | ||
ExIRC.Client.add_handler(conn.client, self()) | ||
{:ok, conn} | ||
end | ||
|
||
@impl true | ||
def handle_info(:logged_in, conn) do | ||
Logger.debug("Logged in to #{conn.server}:#{conn.port}") | ||
|
||
Logger.debug("Requesting capabilities...") | ||
Enum.each(@tmi_capabilities, &request_capabilities(conn.client, &1)) | ||
|
||
Logger.debug("Joining channels...") | ||
Enum.map(conn.channels, &ExIRC.Client.join(conn.client, &1)) | ||
|
||
{:noreply, conn} | ||
end | ||
|
||
# Catch-all for messages you don't care about | ||
def handle_info(msg, conn) do | ||
Logger.debug("Unhandled msg: #{inspect(msg)}") | ||
{:noreply, conn} | ||
end | ||
|
||
# Twitch Membership capability | ||
# < CAP REQ :twitch.tv/membership | ||
# > :tmi.twitch.tv CAP * ACK :twitch.tv/membership | ||
# | ||
# Twitch Tags capability | ||
# < CAP REQ :twitch.tv/tags | ||
# > :tmi.twitch.tv CAP * ACK :twitch.tv/tags | ||
# | ||
# Twitch Commands capability | ||
# < CAP REQ :twitch.tv/commands | ||
# > :tmi.twitch.tv CAP * ACK :twitch.tv/commands | ||
defp request_capabilities(client, cap) do | ||
cmd = ExIRC.Commands.command!('CAP REQ :twitch.tv/#{cap}') | ||
:ok = ExIRC.Client.cmd(client, cmd) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
defmodule TMI.Supervisor do | ||
@moduledoc false | ||
|
||
use Supervisor | ||
|
||
def start_link(config) do | ||
Supervisor.start_link(__MODULE__, config, name: __MODULE__) | ||
end | ||
|
||
@impl true | ||
def init(config) do | ||
user = Keyword.fetch!(config, :user) | ||
pass = Keyword.fetch!(config, :pass) | ||
channels = Keyword.get(config, :channels, []) | ||
|
||
{:ok, client} = ExIRC.start_link!() | ||
|
||
conn = TMI.Conn.new(client, user, pass, channels) | ||
|
||
children = [ | ||
{TMI.Handlers.ConnectionHandler, conn}, | ||
{TMI.Handlers.LoginHandler, conn} | ||
] | ||
|
||
Supervisor.init(children, strategy: :one_for_one) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
%{ | ||
"earmark_parser": {:hex, :earmark_parser, "1.4.10", "6603d7a603b9c18d3d20db69921527f82ef09990885ed7525003c7fe7dc86c56", [:mix], [], "hexpm", "8e2d5370b732385db2c9b22215c3f59c84ac7dda7ed7e544d7c459496ae519c0"}, | ||
"ex_doc": {:hex, :ex_doc, "0.22.2", "03a2a58bdd2ba0d83d004507c4ee113b9c521956938298eba16e55cc4aba4a6c", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "cf60e1b3e2efe317095b6bb79651f83a2c1b3edcb4d319c421d7fcda8b3aff26"}, | ||
"exirc": {:hex, :exirc, "2.0.0", "6b3b8da6d56096a2a613f3688ef05ed52d235a95566e889e885409c307b218b6", [:mix], [], "hexpm", "aba949c7e60ce4bbf1954d78ede33825ffe2fa01e840edd843ddc8f3775e7390"}, | ||
"makeup": {:hex, :makeup, "1.0.3", "e339e2f766d12e7260e6672dd4047405963c5ec99661abdc432e6ec67d29ef95", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "2e9b4996d11832947731f7608fed7ad2f9443011b3b479ae288011265cdd3dad"}, | ||
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, | ||
"nimble_parsec": {:hex, :nimble_parsec, "0.6.0", "32111b3bf39137144abd7ba1cce0914533b2d16ef35e8abc5ec8be6122944263", [:mix], [], "hexpm", "27eac315a94909d4dc68bc07a4a83e06c8379237c5ea528a9acff4ca1c873c52"}, | ||
} |