README.md

# ExTrello [![Build Status](https://travis-ci.org/ChrisYammine/ex_trello.svg?branch=master)](https://travis-ci.org/ChrisYammine/ex_trello)[![Coverage Status](https://coveralls.io/repos/github/ChrisYammine/ex_trello/badge.svg)](https://coveralls.io/github/ChrisYammine/ex_trello)[![Hex.pm](https://img.shields.io/hexpm/v/ex_trello.svg?maxAge=2592000)](https://hex.pm/packages/ex_trello)[![Hex.pm Downloads](https://img.shields.io/hexpm/dt/ex_trello.svg?maxAge=2592000)](https://hex.pm/packages/ex_trello)[![Deps Status](https://beta.hexfaktor.org/badge/all/github/ChrisYammine/ex_trello.svg)](https://beta.hexfaktor.org/github/ChrisYammine/ex_trello)[![Inline docs](http://inch-ci.org/github/ChrisYammine/ex_trello.svg?branch=master&style=shields)](http://inch-ci.org/github/ChrisYammine/ex_trello)

A library for interfacing with the Trello API.

Heavily influenced by https://github.com/parroty/extwitter with some stuff straight ripped out of it.

## **Important! Migration from 0.x -> 1.x**
Since this change will break all existing projects using ExTrello upon upgrading this deserves a spot at the top :)

All calls to the Trello API will now be wrapped in a tuple with the first element either being `:ok`, `:error`, or `:connection_error`
Regular errors will no longer raise exceptions as that is not idiomatic.

Here's an example(just a little sample):
```elixir
# Old and bad
boards = ExTrello.boards()
# New and great
{:ok, boards} = ExTrello.boards()

# Old and bad, yuck!
try do
  ExTrello.get("potato/2")
rescue
  %ExTrello.Error{code: code, message: message} -> IO.puts "ERROR[#{code}] - #{message}"
end

# New and fantastic
case ExTrello.get("potato/2") do
  {:ok, response} -> response
  {:error, %ExTrello.Error{code: code, message: message}} -> IO.puts "ERROR[#{code}] - #{message}"
  {:connection_error, %ExTrello.ConnectionError{reason: _, message: message}} -> IO.puts "#{message} We should retry."
end
```

## Documentation
- https://hexdocs.pm/ex_trello


## Installation


  1. Add `ex_trello` to your list of dependencies in `mix.exs`:

    ```elixir
    def deps do
      [
        ...,
        {:ex_trello, "~> 1.1.0"}
      ]
    end
    ```

  2. Ensure `ex_trello` is started before your application:

    ```elixir
    def application do
      [applications: [:ex_trello]]
    end
    ```
  3. Run `mix deps.get`

## Usage
1. Make sure you've completed [installation.](#installation)
2. Use `ExTrello.configure` to setup Trello's OAuth authentication parameters.
3. Call functions in the `ExTrello` module. (e.g. `ExTrello.boards()`)

### Configuration
The default behavior is for ExTrello to use the application environment:

In `config/<env>.exs` add:

```elixir
# I like using ENV vars to populate my configuration. But fill this out however you'd like :)
config :ex_trello, :oauth, [
  consumer_key:    System.get_env("TRELLO_CONSUMER_KEY"),
  consumer_secret: System.get_env("TRELLO_CONSUMER_SECRET"),
  token:           System.get_env("TRELLO_ACCESS_TOKEN"),
  token_secret:    System.get_env("TRELLO_ACCESS_SECRET")
]
```

You can also manually configure it at runtime:
```elixir
ExTrello.configure(consumer_key: "...", ...)
```

You can also configure for the current process only:
```elixir
defmodule TrelloServer do
  use GenServer

  def start_link(user) do
    GenServer.start_link(__MODULE__, user, [])
  end

  def init(%User{token: token, token_secret: token_secret}) do
    :ok = ExTrello.configure(
      :process,
      consumer_key: System.get_env("TRELLO_CONSUMER_KEY"),
      consumer_secret: System.get_env("TRELLO_CONSUMER_SECRET"),
      token: token,
      token_secret: token_secret
    )
    {:ok, %{boards: []}}
  end

  # Rest of your code...
end
```

## Samples

#### Authorize your application

Example for authorization. This is a naive solution that only works for demonstration.
TODO: Set up example application.
```elixir
# First we have to get a request token from Trello.
{:ok, token} = ExTrello.request_token("http://localhost:4000/auth/trello/callback/1234")
# We have to store this token because we need the `oauth_token_secret` after the callback to obtain our access token & secret.
# e.g. TokenAgent.store("1234", token.oauth_token_secret)

# Generate the url for authorization
{:ok, auth_url} = ExTrello.authorize_url(token.oauth_token, %{return_url: "http://localhost:4000/auth/trello/callback/1234", scope: "read,write", expiration: "never", name: "Your Application Name here"})

# Copy the url and visit it using your browser.
IO.puts auth_url
```
After signing in/authorizing the application you will be redirected to the callback URL you specified in the Request token & authorize URL.

Example:
```
http://localhost:4000/auth/trello/callback/1234?oauth_token=**copy_this**&oauth_verifier=**copy_this**
```

Copy the `oauth_token` and `oauth_verifier` above:
```elixir
oauth_token = "copied_oauth_token"
oauth_verifier = "copied_oauth_verifier"
oauth_token_secret = retrieve_oauth_token_secret_from_before() # e.g. TokenAgent.retrieve("1234") from hypothetical TokenAgent

{:ok, access_token} = ExTrello.access_token(oauth_verifier, oauth_token, oauth_token_secret)

# Let's configure ExTrello with our newly obtained access token
ExTrello.configure(
  consumer_key: System.get_env("TRELLO_CONSUMER_KEY"),
  consumer_secret: System.get_env("TRELLO_CONSUMER_SECRET"),
  token: access_token.oauth_token,
  token_secret: access_token.oauth_token_secret
)

# Testing our token!
{:ok, member} = ExTrello.member() # Fetches the authenticated member record from Trello
```

## TODO:
- [ ] Add models for ~~label~~, ~~checklist~~, ~~member~~, notification, ~~organization~~, session, token, ~~action~~
- [ ] Pagination
- [ ] Code Cleanup! (Perhaps remove `defapicall` macro and use the `with` keyword instead? Have to evaluate.)
- [ ] Example Application
- [ ] Investigate handling storage of request_token.oauth_token_secret instead of leaving that up to the dev.