I started this blog in order to learn how to use Twitter API and also because i love going to the cinema 🙌. Im from Uruguay 🇺🇾, and here we have a cinema called "Movie Center". After checking their request, I started to investigate what we can get from them
Investigation 🕵️
After checking their request I found out that I can use that information for the Twitter bot.
Creating the app 👨💻
Let’s start by creating our Phoenix app
mix phx.new movies_uy
cd movies_uy
mix ecto.create
iex -S mix phx.server
Now Im going to add the following dependencies that are needed for the bot:
# mix.exs
defp deps do
[
{:finch, "~> 0.13"},
{:oauther, "~> 1.1"},
{:extwitter, "~> 0.12"},
{:oban, "~> 2.13"}
]
end
- Finch for doing request to the "Movie Center" API.
- ExTwitter it's a Twitter Client for using Twitter API
- Oban for creating jobs that run whenever we want (in our case once a day)
After adding this don't forget to run mix deps.get
.
Config Finch
Let’s configure Finch by adding this, note that you can follow this from the Finch repo too.
# lib/movies_uy/application.ex
def start(_type, _args) do
children = [
...
{Finch, name: MoviesUyFinch}
]
end
Config ExTwitter 🧵
# config/config.exs
config :extwitter, :oauth, [
consumer_key: System.get_env("TWITTER_CONSUMER_KEY"),
consumer_secret: System.get_env("TWITTER_CONSUMER_SECRET"),
access_token: System.get_env("TWITTER_ACCESS_TOKEN"),
access_token_secret: System.get_env("TWITTER_ACCESS_TOKEN_SECRET")
]
Getting Movies 🎬
Let's add the following code that will search for all the movies from the Movie Center API.
# lib/movies_uy/movie_center.ex
defmodule MoviesUy.MovieCenter do
require Logger
def fetch_movies do
movie_url = "https://api.movie.com.uy/api/billboard/cinema/weekly?nextReleases=false"
request = Finch.build(:get, movie_url) |> Finch.request(MoviesUyFinch)
with {:ok, %Finch.Response{body: data}} <- request,
%{"items" => movies} <- Jason.decode!(data) do
movies
|> Enum.map(fn %{"content" => %{"title" => title, "id" => id, "urlSlug" => slug}}} ->
"#{title} - https://www.movie.com.uy/movie/#{id}/#{slug}"
end)
else
_ ->
Logger.error "Error!"
end
end
end
You can also check if this is working correctly by running the following line on your iex
$ iex> MoviesUy.MovieCenter.fetch_movies # this should show all the movies from Movie center API
Using ExTwitter 🧵
Now is time to build the messages and post them on Twitter using ExTwitter.
What Im going to do is create a tweet that contains the current date, and the comments of this twitter will be the movies with their current url on Movie Center.
# lib/movies_uy/movie_center.ex
defmodule MoviesUy.MovieCenter do
require Logger
def fetch_movies do
movie_url = "https://api.movie.com.uy/api/billboard/cinema/weekly?nextReleases=false"
request = Finch.build(:get, movie_url) |> Finch.request(MoviesUyFinch)
with {:ok, %Finch.Response{body: data}} <- request,
%{"items" => movies} <- Jason.decode!(data),
%ExTwitter.Model.Tweet{id: tweet_id} <- post_message()
do
movies
|> Enum.map(&post_thread_message(&1, tweet_id))
else
error ->
Logger.error error
end
end
defp post_thread_message(%{"content" => %{"title" => title, "id" => id, "urlSlug" => slug}}, tweet_id) do
"#{title} - https://www.movie.com.uy/movie/#{id}/#{slug}"
|> ExTwitter.update(in_reply_to_status_id: tweet_id)
end
defp post_message do
%Date{day: day, month: month, year: year} = Date.utc_today
"Cartelera de Movie Center del #{day}/#{month}/#{year}"
|> ExTwitter.update
end
end
We can run this using the same function as before and we should be able to see that is posting correctly on Twitter.
Config Oban 📅
It’s time to use Oban, this will allow us to create a worker that runs our code whenever we want, in our case once a day! Lets config Oban (you can also read the docs).
$ mix ecto.gen.migration add_oban_jobs_table
Then open the generated migration and update it:
defmodule MoviesUy.Repo.Migrations.AddObanJobsTable do
use Ecto.Migration
def up do
Oban.Migrations.up(version: 11)
end
# We specify `version: 1` in `down`, ensuring that we'll roll all the way back down if
# necessary, regardless of which version we've migrated `up` to.
def down do
Oban.Migrations.down(version: 1)
end
end
And finally lets run this
$ mix ecto.migrate
Lets add this
#config/config.exs
config :movies_uy, Oban,
repo: MoviesUy.Repo,
plugins: [
Oban.Plugins.Pruner,
{Oban.Plugins.Cron,
crontab: [
{"@daily", MoviesUy.DailyWorker, max_attempts: 1},
]}
],
queues: [default: 10]
# lib/my_app/application.ex
def start(_type, _args) do
children = [
...
{Oban, Application.fetch_env!(:movies_uy, Oban)}
]
end
# lib/movies_uy/workers/daily_worker.ex
defmodule MoviesUy.DailyWorker do
use Oban.Worker, queue: :default
@impl Oban.Worker
def perform(_) do
MoviesUy.MovieCenter.fetch_movies()
end
end
Thats it! you can see this Twitter bot working visiting: https://twitter.com/movies_uy
Note: you can also create just a mix app and this guide will work too. I used
phx
because Im planning to do another thing in the future with it
Things we used here:
Visit the bot:
Twitter bot: https://twitter.com/movies_uy
Top comments (0)