Ruby JSON парсинг от AWS Lambda 785: неожиданный токен - PullRequest
0 голосов
/ 27 января 2020

У меня есть веб-крючок Джира, подключенный к лямбде AWS. В ответ от webhook я получил файл JSON, но я не знаю, как его проанализировать, чтобы получить такое значение, как user_email или user_id.

JSON из файла Ответ огромен, вот пример:

"{\"resource\"=>\"/event\", \"path\"=>\"/event\", \"httpMethod\"=>\"POST\", \"headers\"=>{\"Accept\"=>\"*/*\", \"Accept-Encoding\"=>\"gzip,deflate\", \"CloudFront-Forwarded-Proto\"=>\"https\", \"CloudFront-Is-Desktop-Viewer\"=>\"true\", \"CloudFront-Is-Mobile-Viewer\"=>\"false\", \"CloudFront-Is-SmartTV-Viewer\"=>\"false\", \"CloudFront-Is-Tablet-Viewer\"=>\"false\", \"CloudFront-Viewer-Country\"=>\"IE\", \"Content-Type\"=>\"application/json; charset=UTF-8\", \"Host\"=>\"ongnx6d1vk.execute-api.eu-central-1.amazonaws.com\", \"User-Agent\"=>\"Atlassian Webhook HTTP Client\", \"Via\"=>\"1.1 1234.1234.net (CloudFront)\", \"X-Amz-Cf-Id\"=>\"fdgsfds==\", \"X-Amzn-Trace-Id\"=>\"Root=1-fsdafaaf\", \"X-Atlassian-Webhook-Identifier\"=>\"12345\", \"X-B3-Sampled\"=>\"1\", \"X-B3-SpanId\"=>\"13421a324\", \"X-B3-TraceId\"=>\"1fdasfjkl\", \"X-Forwarded-For\"=>\"32423, 342141\", \"X-Forwarded-Port\"=>\"443\"}"

Из-за лямбда-ограничений в отладке я скачал JSON в файл, поэтому я попытался использовать метод разбора, но безрезультатно:

  class JiraParser
    def initialize
      @event = JSON.parse(File.read("../devops-bot/lambda_response.json"))
    end

    def call
      puts parse_reporter_email
    end

    private

    attr_reader :event

    def parse_reporter_email
      event.dig('issue', 'reporter', 'emailAddress')
    end
  end

С этим кодом у меня ошибка

parse_reporter_email ': неопределенный метод `dig' для строки

Я пытался изменить parse метод для:

response = JSON.parse(File.read("../devops-ticket-bot/lambda_response.json"))
@event = JSON.parse(response["body"])

Но он выдал ошибку:

785: неожиданный токен в 'body' (JSON :: ParserError)

Ответы [ 2 ]

1 голос
/ 27 января 2020

"{\"resource\"=>\"/event\" ..." не является действительным JSON. Допустимое значение JSON будет "{\"resource\":\"/event\" ...} (обратите внимание, что двоеточие не является хеш-ракетой.)

Вероятно, это вызвано тем, что вы сбросили данные теста как hash.inspect вместо JSON.dump(hash).

0 голосов
/ 27 января 2020

Я предполагаю, что ваш первый кодовый блок - это то, что буквально присутствует в файле.

данных. json

"data"

Вышеприведенный код действителен JSON, независимо от содержимого строки. В вашем случае строка содержит Ruby структуру данных.

Когда вы анализируете файл, вы получите строку:

require "json"

data = JSON.parse(File.read("data.json"))
#=> "data"

Когда вы попытаетесь вызвать dig on В результате возникает исключение, поскольку строка не отвечает методу dig. Однако он отвечает на [].

data["ta"]
#=> "ta"

Когда вы передаете результат response["body"] в JSON.parse, вы просто предоставляете строку "body" (или nil, если "body" can ' не может быть найдено в строке). Поскольку body недопустимо JSON, возникает исключение.

JSON может быть строкой, числом, объектом, массивом, true, false или null. Литерал body не подходит ни к одному из упомянутых ранее.


Чтобы получить данные по назначению, нужно оценить код Ruby:

ruby_code = JSON.parse(File.read("../devops-bot/lambda_response.json"))
response = eval(ruby_code)
response.dig('issue', 'reporter', 'emailAddress')
#=> ...

Это должно вернуть вам структуру.

Обратите внимание, что вы должны доверять файлу, так как он может выполнять все, что захочет.


Лучший вопрос: : Почему данные сохраняются таким странным образом в файл? Я хотел бы взглянуть на код, который записывает файлы, и убедиться, что вы выводите фактический JSON или YAML в файл, поскольку это безопасно для чтения без использования eval.

...