-
Notifications
You must be signed in to change notification settings - Fork 166
Add script to get OTP delivery logs for SMS, Voice #9019
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,147 @@ | ||
| #!/usr/bin/env ruby | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'active_support' | ||
| require 'active_support/core_ext/integer/time' | ||
| require 'optparse' | ||
|
|
||
| $LOAD_PATH.unshift(File.expand_path(File.join(__dir__, '../../lib'))) | ||
| require 'script_base' | ||
| require 'reporting/cloudwatch_client' | ||
| require 'reporting/cloudwatch_query_quoting' | ||
| require 'reporting/unknown_progress_bar' | ||
|
|
||
| class OtpDeliveries | ||
| include Reporting::CloudwatchQueryQuoting | ||
|
|
||
| # @return [OtpDeliveries] | ||
| def self.parse!(argv: ARGV, out: STDOUT) | ||
| show_help = false | ||
| output_format = :table | ||
| filter = nil | ||
|
|
||
| parser = OptionParser.new do |opts| | ||
| opts.banner = <<~EOM | ||
| Usage: #{$PROGRAM_NAME} uuid1 [uuid2...] | ||
|
|
||
| Looks up OTP delivery attempts for SMS/Voice by user UUID, within the last 72 hours | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would we want hours to be configurable? I suppose we could add that later.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For AWS pinpoint support, they need logs within the last 72 hours so IMO not worth it?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wasn't aware of that. Makes sense with the context. |
||
|
|
||
| Options: | ||
| EOM | ||
|
|
||
| opts.on('--csv') do | ||
| output_format = :csv | ||
| end | ||
|
|
||
| opts.on('--table', 'Output format as an ASCII table (default)') do | ||
| output_format = :table | ||
| end | ||
|
|
||
| opts.on('--json') do | ||
| output_format = :json | ||
| end | ||
|
|
||
| opts.on('--filter=FILTER', 'Filters output to be only SMS or VOICE') do |filter_v| | ||
| filter = filter_v | ||
| end | ||
|
|
||
| opts.on('--help', 'Show this help message') do | ||
| show_help = true | ||
| end | ||
| end | ||
|
|
||
| uuids = parser.parse!(argv) | ||
|
|
||
| if uuids.empty? || show_help | ||
| out.puts parser | ||
| exit 1 | ||
| end | ||
|
|
||
| new(uuids: uuids, filter: filter, output_format: output_format) | ||
| end | ||
|
|
||
| attr_reader :uuids, :output_format, :filter | ||
|
|
||
| def initialize(uuids:, output_format:, filter: nil, progress_bar: true) | ||
| @uuids = uuids | ||
| @output_format = output_format | ||
| @filter = filter | ||
| @progress_bar = progress_bar | ||
| end | ||
|
|
||
| def progress_bar? | ||
| @progress_bar | ||
| end | ||
|
|
||
| def run(out: STDOUT) | ||
| results = query_data(uuids) | ||
|
|
||
| table = [] | ||
| table << %w[user_id timestamp message_id delivery_preference country_code] | ||
| results.each do |result| | ||
| table << [ | ||
| result.user_id, | ||
| result.timestamp, | ||
| result.message_id, | ||
| result.delivery_preference, | ||
| result.country_code, | ||
| ] | ||
| end | ||
|
|
||
| ScriptBase.render_output(table, format: output_format, stdout: out) | ||
| end | ||
|
|
||
| Result = Struct.new( | ||
| :user_id, | ||
| :timestamp, | ||
| :message_id, | ||
| :delivery_preference, | ||
| :country_code, | ||
| keyword_init: true, | ||
| ) | ||
|
|
||
| # @return [Array<Result>] | ||
| def query_data(uuids) | ||
| Reporting::UnknownProgressBar.wrap(show_bar: progress_bar?, title: 'Querying logs') do | ||
| cloudwatch_client.fetch( | ||
| query: <<~EOS, | ||
| fields | ||
| @timestamp | ||
| , properties.user_id | ||
| , properties.event_properties.telephony_response.message_id | ||
| , properties.event_properties.otp_delivery_preference | ||
| , properties.event_properties.telephony_response.delivery_status | ||
| , properties.event_properties.country_code | ||
| | filter name = 'Telephony: OTP sent' | ||
| #{filter ? | ||
| "| filter properties.event_properties.otp_delivery_preference = '#{filter.downcase}'" : | ||
| nil} | ||
| | filter properties.user_id IN #{quote(uuids)} | ||
| | limit 10000 | ||
| EOS | ||
| from: 72.hours.ago, | ||
| to: Time.now, | ||
| ).map do |row| | ||
| Result.new( | ||
| user_id: row['properties.user_id'], | ||
| timestamp: row['@timestamp'], | ||
| message_id: row['properties.event_properties.telephony_response.message_id'], | ||
| delivery_preference: row['properties.event_properties.otp_delivery_preference'], | ||
| country_code: row['properties.event_properties.country_code'], | ||
| ) | ||
| end | ||
| end | ||
| end | ||
|
|
||
| def cloudwatch_client | ||
| @cloudwatch_client ||= Reporting::CloudwatchClient.new( | ||
| ensure_complete_logs: false, | ||
| slice_interval: nil, | ||
| progress: false, | ||
| ) | ||
| end | ||
| end | ||
|
|
||
| if $PROGRAM_NAME == __FILE__ | ||
| OtpDeliveries.parse!.run | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| require 'ruby-progressbar' | ||
|
|
||
| module Reporting | ||
| # Small wrapper around ruby-progressbar | ||
| class UnknownProgressBar | ||
| # Wraps a block and displays a progress bar while the block executes | ||
| # Returns the value from the block | ||
| def self.wrap(show_bar:, title: 'Waiting', output: STDERR) | ||
| if show_bar | ||
| bar = ProgressBar.create( | ||
| title: title, | ||
| total: nil, | ||
| format: '[ %t ] %B %a', | ||
| output: output, | ||
| ) | ||
| thread = Thread.fork do | ||
| loop do | ||
| sleep 0.1 | ||
| bar.increment | ||
| end | ||
| end | ||
| end | ||
|
|
||
| yield | ||
| ensure | ||
| thread&.kill | ||
| bar&.stop | ||
| end | ||
| end | ||
| end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
recommend viewing this with
?w=1whitespace diff hidden