| defmodule Mix.Tasks.SendPageview do |
| @moduledoc """ |
| It's often necessary to generate fake events for development and testing purposes. This Mix Task provides a quick and easy |
| way to generate a pageview or custom event, either in your development environment or a remote Plausible instance. |
| |
| See Mix.Tasks.SendPageview.usage/1 for more detailed documentation. |
| """ |
|
|
| use Mix.Task |
|
|
| @default_host "http://localhost:8000" |
| @default_ip_address "127.0.0.1" |
| @default_user_agent "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36 OPR/71.0.3770.284" |
| @default_domain "dummy.site" |
| @default_page "/" |
| @default_referrer "https://google.com" |
| @default_event "pageview" |
| @default_props "{}" |
| @default_queryparams "" |
| @default_interactive true |
| @options [ |
| ip: :string, |
| user_agent: :string, |
| domain: :string, |
| page: :string, |
| referrer: :string, |
| host: :string, |
| hostname: :string, |
| event: :string, |
| props: :string, |
| revenue_currency: :string, |
| revenue_amount: :string, |
| queryparams: :string, |
| interactive: :string |
| ] |
|
|
| def run(opts) do |
| Finch.start_link(name: Plausible.Finch) |
|
|
| {parsed, _, invalid} = OptionParser.parse(opts, strict: @options) |
|
|
| case invalid do |
| [] -> |
| do_send_pageview(parsed) |
|
|
| [invalid_option | _] -> |
| {key, _val} = invalid_option |
| IO.puts("Invalid option #{key}. Aborting.") |
| IO.puts(usage()) |
| end |
| end |
|
|
| defp do_send_pageview(parsed_opts) do |
| ip = Keyword.get(parsed_opts, :ip, @default_ip_address) |
| user_agent = Keyword.get(parsed_opts, :user_agent, @default_user_agent) |
| host = Keyword.get(parsed_opts, :host, @default_host) |
|
|
| url = get_url(host) |
| headers = get_headers(ip, user_agent) |
| body = get_body(parsed_opts) |
|
|
| case Plausible.HTTPClient.post(url, headers, body) do |
| {:ok, resp} -> |
| IO.puts( |
| "✅ Successfully sent #{body[:name]} event to #{url} ✅ \n\nip=#{ip}\nuser_agent=#{user_agent}\nbody= #{inspect(body, pretty: true)}" |
| ) |
|
|
| IO.puts("Response headers: " <> inspect(resp.headers, pretty: true)) |
|
|
| {:error, e} -> |
| IO.puts("❌ Could not send event to #{url}. Got the following error: \n\n #{inspect(e)}") |
| end |
| end |
|
|
| defp get_url(host) do |
| Path.join(host, "/api/event") |
| end |
|
|
| defp get_headers(ip, user_agent) do |
| [ |
| {"x-forwarded-for", ip}, |
| {"user-agent", user_agent}, |
| {"content-type", "text/plain"} |
| ] |
| end |
|
|
| defp get_body(opts) do |
| domain = Keyword.get(opts, :domain, @default_domain) |
| page = Keyword.get(opts, :page, @default_page) |
| referrer = Keyword.get(opts, :referrer, @default_referrer) |
| event = Keyword.get(opts, :event, @default_event) |
| props = Keyword.get(opts, :props, @default_props) |
| hostname = Keyword.get(opts, :hostname, domain) |
| queryparams = Keyword.get(opts, :queryparams, @default_queryparams) |
|
|
| interactive = |
| if Keyword.get(opts, :interactive) == "false" do |
| false |
| else |
| @default_interactive |
| end |
|
|
| revenue = |
| if Keyword.get(opts, :revenue_currency) do |
| %{ |
| currency: Keyword.get(opts, :revenue_currency), |
| amount: Keyword.get(opts, :revenue_amount) |
| } |
| end |
|
|
| %{ |
| name: event, |
| url: "http://#{hostname}#{page}?#{queryparams}", |
| domain: domain, |
| referrer: referrer, |
| props: props, |
| revenue: revenue, |
| interactive: interactive |
| } |
| end |
|
|
| defp usage() do |
| """ |
| usage: $ mix send_pageview [--domain domain] [--ip ip_address]" |
| options: #{inspect(@options, pretty: true)} |
| """ |
| end |
| end |
|
|