README.md

# GiveAway

GiveAway is a small, modularly extensible library for generating social media sharing URLs. It offers a simple API that can be used to add new channels easily.

To generate sharing urls, you'll need a URL to share in the first place. However, the parameter names differ for different services and imlementations. For example, the url parameter for Facebook and Instapaper is `u`, but in Twitter and pocket it's called `url`. The only parameters you really need for sharing are the URL, a title and/or description and sometimes an image (not everybody uses open graph tags. That's why GiveAway declares `url`, `title`, `description` and `image` as the default parameters that are simply translated to the actual parameter name in the channel module.

## An example

This is how the Twitter module that GiveAway ships with is implemented:

```elixir
  defmodule Twitter do
    use GiveAway.Channel

    def base_uri do
      "https://twitter.com/intent/tweet"
    end

    def valid_params do
      ~w([url text hashtags via related in_reply_to)
    end

    def parse_param(tuple) do
      case tuple do
        {"title", value} -> {"text", value}
        tuple -> tuple
      end
    end
  end
```

You can create a working sharing URL for this channel by calling:

```elixir
  GiveAway.url(Twitter, %{
    "url" => "http://example.com",
    "title" => "Look at this:"
  })
```

This yields: 

```elixir
  "https://twitter.com/intent/tweet?text=Look+at+this%3A&url=http%3A%2F%2Fexample.com"
```

This works, because we translated our generalized parameter `title` to `text`, a valid URL parameter in the Twitter sharing URL.

We could have translated `description` to `text`, but `descriptions` are supposed to be longer and are thus more likely to exceed the 140 character limit along with the value for the `url` parameter, which we didn't translate, because it's a valid Twitter sharing URL parameter.

As you can see, every new channel module starts with `use GiveAway.Channel` and implements the following three simple functions:

### base_uri

As its name says, `base_uri` function that returns the base uri for the sharing URL.

### valid_params

A function that returns a list of valid parameter names for this channel as strings.

### parse_param

The function that translates our generalized paramters to valid sharing URL parameters, as described above.

## Create your own channel module

Assuming we want to create new sharing channel module for [Pinterest](https://pinterest.com/pin/create/bookmarklet?description=Look+at+this+image&media=http%3A%2F%2Fplacehold.it%2F400x300&url=http%3A%2F%2Fexample.com). The base URL is `https://pinterest.com/pin/create/bookmarklet` and the paramters we need are `url`, which is the URL to share, `media` which is a URL to an image and `description`. That's all the information we need to implement the module:

```elixir
defmodule Pinterest do
  use GiveAway.Channel

  def base_uri do
    "https://pinterest.com/pin/create/bookmarklet"
  end

  def valid_params do
    ~w(url media description)
  end

  def parse_param(tuple) do
    case tuple do
      {"image", value} -> {"media", value}
      tuple -> tuple
    end
  end
end
```

We don't need to remap `url` and `description`, but `image` can be mapped to `media` and all three parameters will work.

We can now get the URL like this:

```elixir
  GiveAway.url(Pinterest, %{
    "url" => "http://example.com",
    "description" => "Look at this image",
    "image" => "http://placehold.it/400x300"
  })
```

or, since every Module that uses `GiveAway.Channel` gets assigned `uri/0` implicitly, get the sharing URL directly via the channel module:

```elixir
  Pinterest.uri(%{
    "url" => "http://example.com",
    "description" => "Look at this image",
    "image" => "http://placehold.it/400x300"
  })
```

Which should give the same [result](https://pinterest.com/pin/create/bookmarklet?description=Look+at+this+image&media=http%3A%2F%2Fplacehold.it%2F400x300&url=http%3A%2F%2Fexample.com).

## Create a list of URLs

You can create a whole list of URLs with `GiveAway.urls/2`:

```elixir
channels = [pinterest: Pinterest, facebook: Facebook, twitter: Twitter]

parameters = %{
  "url" => "https://elixir-lang.org/",
  "title" => "The Elixir Programming Language",
  "description" => "",
  "image" => "http://placehold.it/400x300"
}

GiveAway.urls(channels, parameters)
```

This yields:

```elixir
[pinterest: "https://pinterest.com/pin/create/bookmarklet?description=&media=http%3A%2F%2Fplacehold.it%2F400x300&url=https%3A%2F%2Felixir-lang.org%2F",
 facebook: "https://www.facebook.com/sharer/sharer.php?description=&picture=http%3A%2F%2Fplacehold.it%2F400x300&title=The+Elixir+Programming+Language&u=https%3A%2F%2Felixir-lang.org%2F",
 twitter: "https://twitter.com/intent/tweet?text=The+Elixir+Programming+Language&url=https%3A%2F%2Felixir-lang.org%2F"]
```

## Done

And there you have it! Questions? Ideas? Am I doing something wrong? Improvements? Drop me a line or send me a pull request.