Чтобы решить вашу проблему, вы должны быть осторожны, избегая всего с Shellwords.escape
, а затем не заключать их в кавычки.
<<~`SHELL`
curl -s "#{CANVAS_URI}/api/v1/courses/#{COURSE_ID}/quizzes/#{quiz_id}/questions" \
-X POST \
-H "Content-Type: application/json" \
-d #{Shellwords.escape(myJson)} \
-H "Authorization: Bearer #{CANVAS_TOKEN}"
SHELL
Но это утомительно и подвержено ошибкам, а на самом деле не ваша проблема.
Все это обходной путь публикации вложенного json в ruby.Flat jsons работает в большинстве гемов http, но получение вложенного json является редкой необходимостью, и я боюсь, что большинство гемов не проверяли его ...
Вложенный JSON нередко, и не должно быть никаких причин, по которым http-клиент все равно заботится о содержимом вашего JSON.Это просто передача строки.
Ваш JSON деформирован.В частности, здесь:
"comments_html": "<p>Please post your questions to a <a href="#{CANVAS_URI}/courses/#{COURSE_ID}/discussion_topics">discussion</a>.</p>"
У вас есть неохраняемая цитата.Вероятно, это потому, что вы собираете вложенный JSON вручную.Как и в случае с curl, это подвержено ошибкам.
Вместо этого создайте хэш Ruby и преобразуйте его в JSON.Тогда вы получите все преимущества проверки синтаксиса Ruby.
payload = {
question: {
question_type: "multiple_choice_question",
question_text: "<p>Is everything clear?</p>",
points_possible: 1,
answers: [
{
text: "I read and understood",
html: "",
weight: 100
}, {
text: "I have questions",
comments_html: %Q[<p>Please post your questions to a <a href="#{CANVAS_URI}/courses/#{COURSE_ID}/discussion_topics">discussion</a>.</p>],
weight: 0
}
]
}
}
require "json"
json_payload = JSON.generate(payload)
И вместо вызова curl
используйте библиотеку http.Поскольку вы вызываете REST API, вы можете использовать RestClient .
require "rest-client"
response = RestClient.post(
"#{CANVAS_URI}/api/v1/courses/#{COURSE_ID}/quizzes/#{quiz_id}/questions",
json_payload,
{ content_type: :json, authorization: "Bearer #{CANVAS_TOKEN}" }
)
Или, что еще лучше, использовать canvas-api gem , который заботится опреобразование JSON и может использовать функции API, такие как нумерация страниц.
canvas = Canvas::API.new(:host => CANVAS_URI, :token => CANVAS_TOKEN)
response = canvas.post(
"/api/v1/courses/#{COURSE_ID}/quizzes/#{quiz_id}/questions",
payload
)