lib/j7w1/sns_push_client.rb in j7w1-0.0.25 vs lib/j7w1/sns_push_client.rb in j7w1-0.0.26

- old
+ new

@@ -2,12 +2,15 @@ module SNSPushClient def create_sns_client(configuration = J7W1.configuration) AWS::SNS.new configuration.account end - APNS_MAX_MESSAGE_SIZE = 40 + APNS_MAX_PAYLOAD = 256 + SHORTEN_REPLACEMENT = '...'.freeze + SHORTEN_REPLACEMENT_LENGTH = SHORTEN_REPLACEMENT.length + INPUT_PAYLOAD_TABLE = { ios: { message: :alert, badge: :badge, sound: :sound, @@ -85,10 +88,24 @@ sns_client.client.delete_endpoint(endpoint_arn: device_endpoint_arn) rescue nil end + def create_topic(name, options) + sns_client = options[:sns_client] + sns_client ||= create_sns_client(sns_configuration || J7W1.configuration) + + sns_client.topics.create name + end + + def subscribe_topic(topic_name, endpoint_arn, options) + sns_client = options[:sns_client] + sns_client ||= create_sns_client(sns_configuration || J7W1.configuration) + + sns_client.topics[name] + end + def push(endpoint_arn, platform, options = {}) return unless endpoint_arn && platform message = options[:message] badge = options[:badge] @@ -131,19 +148,40 @@ def ios_payload_for(message_value, data) prefix = J7W1.configuration.ios_endpoint.sandbox? ? :APNS_SANDBOX : :APNS - if message_value[:message] && message_value[:message].length > APNS_MAX_MESSAGE_SIZE - message_value[:message] = message_value[:message][0...(APNS_MAX_MESSAGE_SIZE - 3)] + '...' - end - content = { aps: message_content(message_value, platform: :ios), } content.merge! data: data if data - {prefix => content.to_json} + {prefix => ios_truncated_payload(content)} + end + + def ios_truncated_payload(data) + payload = data.to_json + + # Truncation is skipped when the payload is sufficiently lightweight. + return payload if (limit_break = payload.bytesize - APNX_MAX_PAYLOAD) >= 0 + + # Raise error if shortening of the alert cannot make the payload sufficiently short. + size_to_reduce = limit_break + SHORTEN_REPLACEMENT_LENGTH + raise "Payload is too heavy (#{payload.length})" unless + data[:alert] && data[:alert].bytesize > size_to_reduce + + # Chopping the alert from its last -> first to avoid destroying the character's border + # and keep its content as long as possible. + chopped_length = 0 + chopped_count = 0 + while chopped_length < size_to_reduce + chopped_length += data[:alert][-1].bytesize + chopped_count += 1 + end + data[:alert][-chopped_count..-1] = SHORTEN_REPLACEMENT + # Problem won't be occur because at least a character is truncated. + + data.to_json end def android_payload_for(message_value, data) message_value.merge!(data: data) {