Initial commit
This commit is contained in:
commit
39d9292f1c
11 changed files with 225 additions and 0 deletions
5
.formatter.exs
Normal file
5
.formatter.exs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Used by "mix format"
|
||||||
|
[
|
||||||
|
inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}"],
|
||||||
|
locals_without_parens: [plug: 1, plug: 2]
|
||||||
|
]
|
24
.gitignore
vendored
Normal file
24
.gitignore
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# The directory Mix will write compiled artifacts to.
|
||||||
|
/_build/
|
||||||
|
|
||||||
|
# If you run "mix test --cover", coverage assets end up here.
|
||||||
|
/cover/
|
||||||
|
|
||||||
|
# The directory Mix downloads your dependencies sources to.
|
||||||
|
/deps/
|
||||||
|
|
||||||
|
# Where 3rd-party dependencies like ExDoc output generated docs.
|
||||||
|
/doc/
|
||||||
|
|
||||||
|
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||||
|
/.fetch
|
||||||
|
|
||||||
|
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||||
|
erl_crash.dump
|
||||||
|
|
||||||
|
# Also ignore archive artifacts (built via "mix archive.build").
|
||||||
|
*.ez
|
||||||
|
|
||||||
|
# Ignore package tarball (built via "mix hex.build").
|
||||||
|
advent-*.tar
|
||||||
|
|
3
README.md
Normal file
3
README.md
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
# Advent
|
||||||
|
|
||||||
|
An Example Clova Skill written in Elixir
|
31
config/config.exs
Normal file
31
config/config.exs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# This file is responsible for configuring your application
|
||||||
|
# and its dependencies with the aid of the Mix.Config module.
|
||||||
|
use Mix.Config
|
||||||
|
|
||||||
|
config :advent, force_signature_valid: Mix.env() !== :prod
|
||||||
|
# This configuration is loaded before any dependency and is restricted
|
||||||
|
# to this project. If another project depends on this project, this
|
||||||
|
# file won't be loaded nor affect the parent project. For this reason,
|
||||||
|
# if you want to provide default values for your application for
|
||||||
|
# 3rd-party users, it should be done in your "mix.exs" file.
|
||||||
|
|
||||||
|
# You can configure your application as:
|
||||||
|
#
|
||||||
|
# config :advent, key: :value
|
||||||
|
#
|
||||||
|
# and access this configuration in your application as:
|
||||||
|
#
|
||||||
|
# Application.get_env(:advent, :key)
|
||||||
|
#
|
||||||
|
# You can also configure a 3rd-party app:
|
||||||
|
#
|
||||||
|
# config :logger, level: :info
|
||||||
|
#
|
||||||
|
|
||||||
|
# It is also possible to import configuration files, relative to this
|
||||||
|
# directory. For example, you can emulate configuration per environment
|
||||||
|
# by uncommenting the line below and defining dev.exs, test.exs and such.
|
||||||
|
# Configuration from the imported file will override the ones defined
|
||||||
|
# here (which is why it is important to import them last).
|
||||||
|
#
|
||||||
|
# import_config "#{Mix.env()}.exs"
|
58
lib/advent.ex
Normal file
58
lib/advent.ex
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
defmodule Advent do
|
||||||
|
use Clova
|
||||||
|
|
||||||
|
def handle_launch(_req, resp) do
|
||||||
|
resp
|
||||||
|
|> add_speech("今日は#{say_date(today())}です")
|
||||||
|
|> add_speech(days_to_christmas() |> say_days_to_christmas())
|
||||||
|
|> add_speech(prompt_for_another())
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_intent("different_day", req, resp) do
|
||||||
|
with potential_date when not is_nil(potential_date) <- get_slot(req, "date"),
|
||||||
|
{:ok, date} <- Date.from_iso8601(potential_date) do
|
||||||
|
resp
|
||||||
|
|> add_speech("#{say_date(date)}まで計算しますか?")
|
||||||
|
|> put_session_attributes(%{"date" => date})
|
||||||
|
|> add_reprompt("#{date.month}月#{date.day}日まで計算したい場合、「はい」と言ってください。")
|
||||||
|
|> add_reprompt(prompt_for_another())
|
||||||
|
else
|
||||||
|
_ -> add_speech(resp, "それは日付だと思いますがもっとわかりやすく言ってくださいね")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_intent("Clova.YesIntent", req, resp) do
|
||||||
|
with %{"date" => iso_date} <- get_session_attributes(req),
|
||||||
|
{:ok, date} <- Date.from_iso8601(iso_date) do
|
||||||
|
resp
|
||||||
|
|> add_speech(say_days_to(date))
|
||||||
|
|> add_speech(prompt_for_another())
|
||||||
|
else
|
||||||
|
_ -> end_session(resp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_intent(_name, _req, resp), do: end_session(resp)
|
||||||
|
|
||||||
|
defp prompt_for_another(), do: "違う日まで計算したい場合、日付けを言ってください"
|
||||||
|
|
||||||
|
defp say_days_to_christmas(0), do: "クリスマスの日です!メリークリスマス!"
|
||||||
|
defp say_days_to_christmas(days) when days < 0, do: "クリスマスはもうすぎました。来年まで楽しみましょう。"
|
||||||
|
defp say_days_to_christmas(days), do: "クリスマスまであと#{days}日です!"
|
||||||
|
|
||||||
|
defp today, do: Timex.now("Asia/Tokyo") |> DateTime.to_date()
|
||||||
|
|
||||||
|
defp say_date(date), do: "#{date.year}年#{date.month}月#{date.day}日"
|
||||||
|
|
||||||
|
defp days_to(date), do: Date.diff(date, today())
|
||||||
|
|
||||||
|
defp say_days_to(date), do: say_days_to(date, days_to(date))
|
||||||
|
defp say_days_to(date, 0), do: "#{say_date(date)}は今日です!"
|
||||||
|
defp say_days_to(date, days) when days < 0, do: "#{say_date(date)}から#{-days}日すぎました。"
|
||||||
|
defp say_days_to(date, days), do: "#{say_date(date)}まであと#{days}日です。"
|
||||||
|
|
||||||
|
defp days_to_christmas do
|
||||||
|
{:ok, xmas} = Date.new(today().year, 12, 25)
|
||||||
|
days_to(xmas)
|
||||||
|
end
|
||||||
|
end
|
19
lib/advent/application.ex
Normal file
19
lib/advent/application.ex
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
defmodule Advent.Application do
|
||||||
|
# See https://hexdocs.pm/elixir/Application.html
|
||||||
|
# for more information on OTP Applications
|
||||||
|
@moduledoc false
|
||||||
|
|
||||||
|
use Application
|
||||||
|
|
||||||
|
def start(_type, _args) do
|
||||||
|
# List all child processes to be supervised
|
||||||
|
children = [
|
||||||
|
{Plug.Adapters.Cowboy, scheme: :http, plug: Advent.Router, options: [port: 4000]}
|
||||||
|
]
|
||||||
|
|
||||||
|
# See https://hexdocs.pm/elixir/Supervisor.html
|
||||||
|
# for other strategies and supported options
|
||||||
|
opts = [strategy: :one_for_one, name: Advent.Supervisor]
|
||||||
|
Supervisor.start_link(children, opts)
|
||||||
|
end
|
||||||
|
end
|
26
lib/advent/router.ex
Normal file
26
lib/advent/router.ex
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
defmodule Advent.Router do
|
||||||
|
use Plug.Router
|
||||||
|
use Plug.ErrorHandler
|
||||||
|
|
||||||
|
plug Plug.Logger
|
||||||
|
|
||||||
|
plug Clova.SkillPlug,
|
||||||
|
dispatch_to: Advent,
|
||||||
|
app_id: "com.example.advent",
|
||||||
|
json_module: Poison,
|
||||||
|
force_signature_valid: Application.get_env(:advent, :force_signature_valid, false)
|
||||||
|
|
||||||
|
plug :match
|
||||||
|
plug :dispatch
|
||||||
|
|
||||||
|
post "/clova" do
|
||||||
|
send_resp(conn)
|
||||||
|
end
|
||||||
|
|
||||||
|
match("/clova", do: send_resp(conn, :method_not_allowed, ""))
|
||||||
|
match(_, do: send_resp(conn, :not_found, ""))
|
||||||
|
|
||||||
|
def handle_errors(conn, %{kind: :error, reason: reason}) do
|
||||||
|
send_resp(conn, conn.status, Exception.message(reason))
|
||||||
|
end
|
||||||
|
end
|
31
mix.exs
Normal file
31
mix.exs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
defmodule Advent.MixProject do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[
|
||||||
|
app: :advent,
|
||||||
|
version: "0.1.0",
|
||||||
|
elixir: "~> 1.7",
|
||||||
|
start_permanent: Mix.env() == :prod,
|
||||||
|
deps: deps()
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help compile.app" to learn about applications.
|
||||||
|
def application do
|
||||||
|
[
|
||||||
|
extra_applications: [:logger],
|
||||||
|
mod: {Advent.Application, []}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help deps" to learn about dependencies.
|
||||||
|
defp deps do
|
||||||
|
[
|
||||||
|
{:clova, "~> 0.5.0"},
|
||||||
|
{:plug_cowboy, "~> 2.0"},
|
||||||
|
{:poison, "~> 3.1"},
|
||||||
|
{:timex, "~> 3.4.2"}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
23
mix.lock
Normal file
23
mix.lock
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
%{
|
||||||
|
"certifi": {:hex, :certifi, "2.4.2", "75424ff0f3baaccfd34b1214184b6ef616d89e420b258bb0a5ea7d7bc628f7f0", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"clova": {:hex, :clova, "0.5.0", "899ddfda81fcc2a10d0cceb571f8f429d4c0ca152b8c83cc33769b1b28a631c9", [:mix], [{:plug, "~> 1.6", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm"},
|
||||||
|
"cowboy": {:hex, :cowboy, "2.6.0", "dc1ff5354c89e36a3e3ef8d10433396dcff0dcbb1d4223b58c64c2d51a6d88d9", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"},
|
||||||
|
"gettext": {:hex, :gettext, "0.16.1", "e2130b25eebcbe02bb343b119a07ae2c7e28bd4b146c4a154da2ffb2b3507af2", [:mix], [], "hexpm"},
|
||||||
|
"hackney": {:hex, :hackney, "1.14.3", "b5f6f5dcc4f1fba340762738759209e21914516df6be440d85772542d4a5e412", [:rebar3], [{:certifi, "2.4.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.4", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm"},
|
||||||
|
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"},
|
||||||
|
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], [], "hexpm"},
|
||||||
|
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"},
|
||||||
|
"plug": {:hex, :plug, "1.7.1", "8516d565fb84a6a8b2ca722e74e2cd25ca0fc9d64f364ec9dbec09d33eb78ccd", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"plug_cowboy": {:hex, :plug_cowboy, "2.0.0", "ab0c92728f2ba43c544cce85f0f220d8d30fc0c90eaa1e6203683ab039655062", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
|
||||||
|
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"},
|
||||||
|
"ranch": {:hex, :ranch, "1.7.0", "9583f47160ca62af7f8d5db11454068eaa32b56eeadf984d4f46e61a076df5f2", [:rebar3], [], "hexpm"},
|
||||||
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"},
|
||||||
|
"timex": {:hex, :timex, "3.4.2", "d74649c93ad0e12ce5b17cf5e11fbd1fb1b24a3d114643e86dba194b64439547", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"tzdata": {:hex, :tzdata, "0.5.19", "7962a3997bf06303b7d1772988ede22260f3dae1bf897408ebdac2b4435f4e6a", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm"},
|
||||||
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.4.1", "d869e4c68901dd9531385bb0c8c40444ebf624e60b6962d95952775cac5e90cd", [:rebar3], [], "hexpm"},
|
||||||
|
}
|
4
test/advent_test.exs
Normal file
4
test/advent_test.exs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
defmodule AdventTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
doctest Advent
|
||||||
|
end
|
1
test/test_helper.exs
Normal file
1
test/test_helper.exs
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ExUnit.start()
|
Loading…
Reference in a new issue