nexmo-oas-renderer 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +16 -7
- data/lib/nexmo/oas/renderer/app.rb +2 -4
- data/lib/nexmo/oas/renderer/presenters/api_specification.rb +1 -1
- data/lib/nexmo/oas/renderer/presenters/open_api_specification.rb +1 -1
- data/lib/nexmo/oas/renderer/public/assets/stylesheets/nexmo-oas-renderer.css +1 -1
- data/lib/nexmo/oas/renderer/version.rb +1 -1
- data/lib/nexmo/oas/renderer/views/open_api/_model.erb +1 -1
- data/lib/nexmo/oas/renderer/views/open_api/_parameter_groups.erb +7 -37
- data/lib/nexmo/oas/renderer/views/open_api/_tabbed_parameters.erb +53 -0
- data/nexmo-oas-renderer.gemspec +1 -0
- metadata +17 -53
- data/lib/nexmo/oas/renderer/filters/anchor.rb +0 -17
- data/lib/nexmo/oas/renderer/filters/audio.rb +0 -21
- data/lib/nexmo/oas/renderer/filters/block_escape.rb +0 -24
- data/lib/nexmo/oas/renderer/filters/break.rb +0 -13
- data/lib/nexmo/oas/renderer/filters/code.rb +0 -64
- data/lib/nexmo/oas/renderer/filters/code_snippet.rb +0 -194
- data/lib/nexmo/oas/renderer/filters/code_snippet_list.rb +0 -33
- data/lib/nexmo/oas/renderer/filters/code_snippets.rb +0 -158
- data/lib/nexmo/oas/renderer/filters/collapsible.rb +0 -27
- data/lib/nexmo/oas/renderer/filters/columns.rb +0 -50
- data/lib/nexmo/oas/renderer/filters/concept_list.rb +0 -33
- data/lib/nexmo/oas/renderer/filters/dynamic_content.rb +0 -30
- data/lib/nexmo/oas/renderer/filters/external_link.rb +0 -32
- data/lib/nexmo/oas/renderer/filters/frontmatter.rb +0 -14
- data/lib/nexmo/oas/renderer/filters/heading.rb +0 -61
- data/lib/nexmo/oas/renderer/filters/icon.rb +0 -22
- data/lib/nexmo/oas/renderer/filters/indent.rb +0 -20
- data/lib/nexmo/oas/renderer/filters/inline_escape.rb +0 -17
- data/lib/nexmo/oas/renderer/filters/js_sequence_diagram.rb +0 -21
- data/lib/nexmo/oas/renderer/filters/label.rb +0 -32
- data/lib/nexmo/oas/renderer/filters/language.rb +0 -15
- data/lib/nexmo/oas/renderer/filters/markdown.rb +0 -85
- data/lib/nexmo/oas/renderer/filters/modal.rb +0 -41
- data/lib/nexmo/oas/renderer/filters/partial.rb +0 -28
- data/lib/nexmo/oas/renderer/filters/php_inliner.rb +0 -15
- data/lib/nexmo/oas/renderer/filters/screenshot.rb +0 -26
- data/lib/nexmo/oas/renderer/filters/tab.rb +0 -250
- data/lib/nexmo/oas/renderer/filters/techio.rb +0 -24
- data/lib/nexmo/oas/renderer/filters/tooltip.rb +0 -22
- data/lib/nexmo/oas/renderer/filters/tutorial_link.rb +0 -27
- data/lib/nexmo/oas/renderer/filters/tutorials.rb +0 -28
- data/lib/nexmo/oas/renderer/filters/unfreeze.rb +0 -20
- data/lib/nexmo/oas/renderer/filters/user_personalization.rb +0 -43
- data/lib/nexmo/oas/renderer/lib/core_ext/string.rb +0 -14
- data/lib/nexmo/oas/renderer/lib/redcarpet.rb +0 -14
- data/lib/nexmo/oas/renderer/models/code_snippet.rb +0 -75
- data/lib/nexmo/oas/renderer/models/tutorial.rb +0 -83
- data/lib/nexmo/oas/renderer/pipelines/markdown_pipeline.rb +0 -52
- data/lib/nexmo/oas/renderer/services/code_language_api.rb +0 -98
- data/lib/nexmo/oas/renderer/views/code_snippets/_application_messages_dispatch.html.erb +0 -9
- data/lib/nexmo/oas/renderer/views/code_snippets/_application_rtc.html.erb +0 -41
- data/lib/nexmo/oas/renderer/views/code_snippets/_application_voice.html.erb +0 -24
- data/lib/nexmo/oas/renderer/views/code_snippets/_code_only.html.erb +0 -6
- data/lib/nexmo/oas/renderer/views/code_snippets/_configure_client.html.erb +0 -20
- data/lib/nexmo/oas/renderer/views/code_snippets/_dependencies.html.erb +0 -11
- data/lib/nexmo/oas/renderer/views/code_snippets/_write_code.html.erb +0 -13
- data/lib/nexmo/oas/renderer/views/code_snippets/list/plain.html.erb +0 -10
- data/lib/nexmo/oas/renderer/views/tutorials/_index.html.erb +0 -32
- data/lib/nexmo/oas/renderer/views/tutorials/index.html.erb +0 -7
- data/lib/nexmo/oas/renderer/views/tutorials/list/plain.html.erb +0 -5
- data/lib/nexmo/oas/renderer/views/tutorials/show.html.erb +0 -8
@@ -1,20 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class Unfreeze < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
input.gsub!('FREEZESTARTFREEZEEND', '')
|
8
|
-
input.gsub!('<p>FREEZESTART', 'FREEZESTART')
|
9
|
-
input.gsub!('FREEZEEND</p>', 'FREEZEEND')
|
10
|
-
|
11
|
-
input.gsub!(/FREEZESTART(.+?)FREEZEEND/m) do |_s|
|
12
|
-
Base64.urlsafe_decode64($1).force_encoding(Encoding::UTF_8)
|
13
|
-
end
|
14
|
-
input
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Filters
|
5
|
-
class UserPersonalization < Banzai::Filter
|
6
|
-
def call(input)
|
7
|
-
return input unless options[:current_user]
|
8
|
-
return input if options[:current_user].api_key.blank?
|
9
|
-
return input if options[:current_user].api_secret.blank?
|
10
|
-
|
11
|
-
@input = input
|
12
|
-
document.css('pre code').each do |code|
|
13
|
-
html = code.to_s
|
14
|
-
|
15
|
-
html.gsub!(/(['|"])?NEXMO_API_(KEY|SECRET)['|"]?/) do
|
16
|
-
quote = $1 || "'"
|
17
|
-
value = (
|
18
|
-
case $2
|
19
|
-
when 'KEY' then options[:current_user].api_key
|
20
|
-
when 'SECRET' then options[:current_user].api_secret
|
21
|
-
end
|
22
|
-
)
|
23
|
-
"#{quote}#{value}#{quote}"
|
24
|
-
end
|
25
|
-
|
26
|
-
html.gsub!('NEXMO_API_SECRET', "'#{options[:current_user].api_secret}'")
|
27
|
-
|
28
|
-
code.replace(html)
|
29
|
-
end
|
30
|
-
|
31
|
-
@document.to_html
|
32
|
-
end
|
33
|
-
|
34
|
-
private
|
35
|
-
|
36
|
-
def document
|
37
|
-
@document ||= Nokogiri::HTML::DocumentFragment.parse(@input)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,14 +0,0 @@
|
|
1
|
-
class String
|
2
|
-
def render_markdown(options = {})
|
3
|
-
Nexmo::OAS::Renderer::MarkdownPipeline.new(options).call(self).html_safe
|
4
|
-
end
|
5
|
-
|
6
|
-
def unindent
|
7
|
-
indent = squeeze("\n").lines.map { |line| line.index(/[^\s]/) }.compact.min || 0
|
8
|
-
gsub(/^[[:blank:]]{#{indent}}/, '')
|
9
|
-
end
|
10
|
-
|
11
|
-
def unindent!
|
12
|
-
replace(unindent)
|
13
|
-
end
|
14
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Models
|
5
|
-
class CodeSnippet
|
6
|
-
include ActiveModel::Model
|
7
|
-
attr_accessor :title, :product, :category, :navigation_weight, :document_path, :url
|
8
|
-
|
9
|
-
def self.by_product(product)
|
10
|
-
all.select do |block|
|
11
|
-
block.product == product
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.all
|
16
|
-
blocks = files.map do |document_path|
|
17
|
-
document = File.read(document_path)
|
18
|
-
product = extract_product(document_path)
|
19
|
-
|
20
|
-
frontmatter = YAML.safe_load(document)
|
21
|
-
|
22
|
-
new({
|
23
|
-
title: frontmatter['title'],
|
24
|
-
navigation_weight: frontmatter['navigation_weight'] || 999,
|
25
|
-
product: product,
|
26
|
-
document_path: document_path,
|
27
|
-
category: extract_category(document_path),
|
28
|
-
url: generate_url(document_path),
|
29
|
-
})
|
30
|
-
end
|
31
|
-
|
32
|
-
blocks.sort_by(&:navigation_weight)
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.generate_url(path)
|
36
|
-
'/' + path.gsub("#{origin}/", '').gsub('.md', '')
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.extract_product(path)
|
40
|
-
# Remove the prefix
|
41
|
-
path = path.gsub!("#{origin}/", '')
|
42
|
-
|
43
|
-
# Each file is in the form code-snippets/<title>.md, so let's remove everything after code-snippets
|
44
|
-
path = path.gsub(%r{/code-snippets/.*}, '')
|
45
|
-
|
46
|
-
path
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.extract_category(path)
|
50
|
-
# Remove the prefix
|
51
|
-
path = path.gsub("#{origin}/", '')
|
52
|
-
|
53
|
-
# Each file is in the form code-snippets/<title>.md, so let's capture everything after code-snippets
|
54
|
-
path = path.gsub(%r{.*/code-snippets/(.*)$}, '\1')
|
55
|
-
|
56
|
-
parts = path.split('/')
|
57
|
-
parts = parts[0...-1]
|
58
|
-
|
59
|
-
return nil if parts.empty?
|
60
|
-
|
61
|
-
parts.join('/').tr('-', ' ').humanize
|
62
|
-
end
|
63
|
-
|
64
|
-
def self.files
|
65
|
-
Dir.glob("#{origin}/**/code-snippets/**/*.md")
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.origin
|
69
|
-
"_documentation"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
module Nexmo
|
2
|
-
module OAS
|
3
|
-
module Renderer
|
4
|
-
module Models
|
5
|
-
class Tutorial
|
6
|
-
|
7
|
-
include ActiveModel::Model
|
8
|
-
attr_accessor :title, :description, :external_link, :products, :document_path, :languages
|
9
|
-
|
10
|
-
def body
|
11
|
-
File.read(document_path)
|
12
|
-
end
|
13
|
-
|
14
|
-
def path
|
15
|
-
return external_link if external_link
|
16
|
-
"/tutorials/#{document_path.relative_path_from(self.class.origin)}".gsub('.md', '')
|
17
|
-
end
|
18
|
-
|
19
|
-
def subtitle
|
20
|
-
normalized_products = products.map do |product|
|
21
|
-
normalise_product_title(product)
|
22
|
-
end
|
23
|
-
|
24
|
-
normalized_products.sort.to_sentence
|
25
|
-
end
|
26
|
-
|
27
|
-
def normalise_product_title(product)
|
28
|
-
return 'SMS' if product == 'messaging/sms'
|
29
|
-
return 'Voice' if product == 'voice/voice-api'
|
30
|
-
return 'Number Insight' if product == 'number-insight'
|
31
|
-
return 'Messages' if product == 'messages'
|
32
|
-
return 'Dispatch' if product == 'dispatch'
|
33
|
-
return 'Client SDK' if product == 'client-sdk'
|
34
|
-
product.camelcase
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.by_product(product, tutorials = [])
|
38
|
-
tutorials = all if tutorials.empty?
|
39
|
-
tutorials.select do |tutorial|
|
40
|
-
tutorial.products.include? product
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.by_language(language, tutorials = [])
|
45
|
-
language = language.downcase
|
46
|
-
tutorials = all if tutorials.empty?
|
47
|
-
|
48
|
-
tutorials.select do |tutorial|
|
49
|
-
tutorial.languages.map(&:downcase).include? language
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.origin
|
54
|
-
Pathname.new("_tutorials")
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.all
|
58
|
-
files.map do |document_path|
|
59
|
-
document_path = Pathname.new(document_path)
|
60
|
-
document = File.read(document_path)
|
61
|
-
frontmatter = YAML.safe_load(document)
|
62
|
-
|
63
|
-
new({
|
64
|
-
title: frontmatter['title'],
|
65
|
-
description: frontmatter['description'],
|
66
|
-
external_link: frontmatter['external_link'],
|
67
|
-
products: frontmatter['products'].split(',').map(&:strip),
|
68
|
-
languages: frontmatter['languages'] || [],
|
69
|
-
document_path: document_path,
|
70
|
-
})
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
private
|
75
|
-
|
76
|
-
private_class_method def self.files
|
77
|
-
Dir.glob("#{origin}/**/*.md")
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require 'banzai'
|
2
|
-
|
3
|
-
Dir[File.join(__dir__, '../filters', '*.rb')].each { |f| require_relative f }
|
4
|
-
|
5
|
-
module Nexmo
|
6
|
-
module OAS
|
7
|
-
module Renderer
|
8
|
-
class MarkdownPipeline < Banzai::Pipeline
|
9
|
-
def initialize(options = {})
|
10
|
-
super(
|
11
|
-
# As Markdown
|
12
|
-
Filters::Frontmatter,
|
13
|
-
Filters::PHPInliner,
|
14
|
-
Filters::InlineEscape,
|
15
|
-
Filters::BlockEscape,
|
16
|
-
Filters::Screenshot,
|
17
|
-
Filters::Anchor,
|
18
|
-
Filters::Audio,
|
19
|
-
Filters::DynamicContent,
|
20
|
-
Filters::Tooltip,
|
21
|
-
Filters::Collapsible,
|
22
|
-
Filters::Tab.new(options),
|
23
|
-
Filters::CodeSnippets.new(options),
|
24
|
-
Filters::CodeSnippet.new(options),
|
25
|
-
Filters::Code,
|
26
|
-
Filters::Indent,
|
27
|
-
Filters::Modal,
|
28
|
-
Filters::JsSequenceDiagram,
|
29
|
-
Filters::Partial.new(options),
|
30
|
-
Filters::Techio,
|
31
|
-
Filters::Tutorials,
|
32
|
-
Filters::CodeSnippetList,
|
33
|
-
Filters::ConceptList,
|
34
|
-
Filters::Language,
|
35
|
-
Filters::Columns,
|
36
|
-
Filters::Markdown.new(options),
|
37
|
-
|
38
|
-
# As HTML
|
39
|
-
Filters::UserPersonalization.new(options),
|
40
|
-
Filters::Heading,
|
41
|
-
Filters::Label.new(options),
|
42
|
-
Filters::Break,
|
43
|
-
Filters::Unfreeze,
|
44
|
-
Filters::Icon,
|
45
|
-
Filters::ExternalLink,
|
46
|
-
Filters::TutorialLink
|
47
|
-
)
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
@@ -1,98 +0,0 @@
|
|
1
|
-
require 'rouge'
|
2
|
-
|
3
|
-
module Nexmo
|
4
|
-
module OAS
|
5
|
-
module Renderer
|
6
|
-
class CodeLanguageAPI
|
7
|
-
attr_accessor :key, :label, :type, :dependencies, :unindent, :icon, :run_command
|
8
|
-
attr_writer :weight, :linkable, :languages, :lexer
|
9
|
-
|
10
|
-
def initialize(attributes = {})
|
11
|
-
@key = attributes["key"]
|
12
|
-
@label = attributes["label"]
|
13
|
-
@type = attributes["type"]
|
14
|
-
@dependencies = attributes["dependencies"]
|
15
|
-
@unindent = attributes["unindent"]
|
16
|
-
@icon = attributes["icon"]
|
17
|
-
@run_command = attributes["run_command"]
|
18
|
-
@lexer = attributes["lexer"]
|
19
|
-
@languages = attributes["languages"]
|
20
|
-
@weight = attributes["weight"]
|
21
|
-
@linkable = attributes["linkable"]
|
22
|
-
end
|
23
|
-
|
24
|
-
def weight
|
25
|
-
@weight || 999
|
26
|
-
end
|
27
|
-
|
28
|
-
def linkable?
|
29
|
-
return true if @linkable.nil?
|
30
|
-
@linkable
|
31
|
-
end
|
32
|
-
|
33
|
-
def lexer
|
34
|
-
return Rouge::Lexers::PHP.new({ start_inline: true }) if @lexer == 'php'
|
35
|
-
Rouge::Lexer.find(@lexer) || Rouge::Lexer.find('text')
|
36
|
-
end
|
37
|
-
|
38
|
-
def languages
|
39
|
-
@languages ||= []
|
40
|
-
@languages.map do |language|
|
41
|
-
self.class.find(language)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def self.languages
|
46
|
-
where_type('languages')
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.frameworks
|
50
|
-
where_type('platforms')
|
51
|
-
end
|
52
|
-
|
53
|
-
def self.terminal_programs
|
54
|
-
where_type('terminal_programs')
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.data
|
58
|
-
where_type('data')
|
59
|
-
end
|
60
|
-
|
61
|
-
def self.all
|
62
|
-
languages + frameworks + terminal_programs + data
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.find(key)
|
66
|
-
raise 'Key is missing' unless key
|
67
|
-
code_language = all.detect { |lang| lang.key == key }
|
68
|
-
raise "Language #{key} does not exist." unless code_language
|
69
|
-
code_language
|
70
|
-
end
|
71
|
-
|
72
|
-
def self.linkable
|
73
|
-
all.select(&:linkable?)
|
74
|
-
end
|
75
|
-
|
76
|
-
def self.match?(code_language)
|
77
|
-
return true if code_language.nil?
|
78
|
-
|
79
|
-
route_constraint[:code_language].match?(code_language)
|
80
|
-
end
|
81
|
-
|
82
|
-
def self.route_constraint
|
83
|
-
{ code_language: Regexp.new("^(#{linkable.map(&:key).compact.join('|')})$") }
|
84
|
-
end
|
85
|
-
|
86
|
-
private_class_method def self.where_type(type)
|
87
|
-
config[type].map do |key, attributes|
|
88
|
-
new(attributes.merge({ "key" => key, "type" => type }))
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
private_class_method def self.config
|
93
|
-
@config ||= YAML.load_file("#{API.root}/config/code_languages.yml")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,9 +0,0 @@
|
|
1
|
-
<div class="Vlt-box Vlt-box--lesspadding Nxd-accordion-emphasis">
|
2
|
-
<h5 class="Vlt-js-accordion__trigger Vlt-accordion__trigger" data-accordion="acc<%= id %>" tabindex="0">
|
3
|
-
<%= app['use_existing'] ? 'Use your existing application' : 'Create an application' %>
|
4
|
-
</h5>
|
5
|
-
|
6
|
-
<div id="acc<%=id %>" class="Vlt-js-accordion__content Vlt-accordion__content Vlt-accordion__content--noborder">
|
7
|
-
If you do not have an application you can <a href="/messages/code-snippets/create-an-application">create one</a>. Make sure you also <a href="/messages/code-snippets/configure-webhooks">configure your webhooks</a>.
|
8
|
-
</div>
|
9
|
-
</div>
|
@@ -1,41 +0,0 @@
|
|
1
|
-
<div class="Vlt-box Vlt-box--lesspadding Nxd-accordion-emphasis">
|
2
|
-
<h5 class="Vlt-js-accordion__trigger Vlt-accordion__trigger" data-accordion="acc<%= id %>" tabindex="0">
|
3
|
-
Create an application
|
4
|
-
</h5>
|
5
|
-
|
6
|
-
<div id="acc<%=id %>" class="Vlt-js-accordion__content Vlt-accordion__content Vlt-accordion__content--noborder">
|
7
|
-
<p>A Nexmo application contains the required configuration for your project. You can create an application
|
8
|
-
using the <a href="https://github.com/Nexmo/nexmo-cli">Nexmo CLI</a> (see below) or <a href="https://dashboard.nexmo.com/voice/create-application">via
|
9
|
-
the dashboard</a>. To learn more about applications <a href="/concepts/guides/applications">see our
|
10
|
-
Nexmo concepts guide</a>.</p>
|
11
|
-
<h4>Install the CLI</h4>
|
12
|
-
<pre class="highlight shell"><code>$ npm install -g nexmo-cli</code></pre>
|
13
|
-
|
14
|
-
<h4>Create an application</h4>
|
15
|
-
<p>Once you have the CLI installed you can use it to create a Nexmo application. Run the following command and
|
16
|
-
make a note of the application ID that it returns. This is the value to use in <code>NEXMO_APPLICATION_ID</code>
|
17
|
-
in the example below. It will also create <code>private.key</code> in the current directory which you will
|
18
|
-
need in the <em>Initialize your dependencies</em> step</p>
|
19
|
-
|
20
|
-
<% unless app['disable_ngrok'] %>
|
21
|
-
<p>Nexmo needs to connect to your local machine to access your <code>answer_url</code>. We recommend using <a
|
22
|
-
href="https://www.nexmo.com/blog/2017/07/04/local-development-nexmo-ngrok-tunnel-dr/">ngrok</a> to do
|
23
|
-
this. Make sure to change <code>demo.ngrok.io</code> in the examples below to your own ngrok URL.</p>
|
24
|
-
<% end %>
|
25
|
-
|
26
|
-
<pre class="highlight shell"><code>$ nexmo app:create "<%=app['name'] %>" <%=app['answer_url'] %> <%=app['event_url'] %> --keyfile=private.key --type=rtc</code></pre>
|
27
|
-
|
28
|
-
<h4>Or to use your existing Nexmo application</h4>
|
29
|
-
|
30
|
-
<p>You will need to use an existing Nexmo application and
|
31
|
-
authenticate a User in order to achieve results here.</p>
|
32
|
-
<p>See the <a href="https://developer.nexmo.com/conversation/overview">Conversation API docs</a>
|
33
|
-
for information
|
34
|
-
on how to create an Application and Users on your backend server.</p>
|
35
|
-
<p>Alternatively you can review the <a href="https://developer.nexmo.com/tutorials/client-sdk-generate-test-credentials">tutorial
|
36
|
-
on getting started with generating an Application and
|
37
|
-
credentials</a>.</p>
|
38
|
-
</div>
|
39
|
-
|
40
|
-
|
41
|
-
</div>
|