# 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.