<commit_before>module Sisimai::Bite::Email
  # Sisimai::Bite::Email::GSuite parses a bounce email which created by G Suite.
  # Methods in the module are called from only Sisimai::Message.
  module GSuite
    class << self
      # Imported from p5-Sisimail/lib/Sisimai/Bite/Email/GSuite.pm
      require 'sisimai/bite/email'

      Indicators = Sisimai::Bite::Email.INDICATORS
      MarkingsOf = {
        message: %r/\A[*][*][ ].+[ ][*][*]\z/,
        rfc822:  %r{\AContent-Type:[ ]*(?:message/rfc822|text/rfc822-headers)\z},
        error:   %r/\AThe[ ]response([ ]from[ ]the[ ]remote[ ]server)?[ ]was:\z/,
        html:    %r{\AContent-Type:[ ]*text/html;[ ]*charset=['"]?(?:UTF|utf)[-]8['"]?\z},
      }.freeze
      MessagesOf = {
        userunknown:  ["because the address couldn't be found"],
        notaccept:    ['Null MX'],
        networkerror: [' responded with code NXDOMAIN'],
      }.freeze

      def description; return 'G Suite: https://gsuite.google.com'; end
      def smtpagent;   return Sisimai::Bite.smtpagent(self); end
      def headerlist;  return ['X-Gm-Message-State']; end

      # Parse bounce messages from G Suite (Transfer from G Suite to a destinaion host)
      # @param         [Hash] mhead       Message headers of a bounce email
      # @options mhead [String] from      From header
      # @options mhead [String] date      Date header
      # @options mhead [String] subject   Subject header
      # @options mhead [Array]  received  Received headers
      # @options mhead [String] others    Other required headers
      # @param         [String] mbody     Message body of a bounce email
      # @return        [Hash, Nil]        Bounce data list and message/rfc822
      #                                   part or nil if it failed to parse or
      #                                   the arguments are missing
      def scan(mhead, mbody)
        return nil unless mhead
        return nil unless mbody

        return nil unless mhead['from'].end_with?('<<EMAIL>>')
        return nil unless mhead['subject'].start_with?('Delivery Status Notification')
        return nil unless mhead['x-gm-message-state']

        require 'sisimai/address'
        dscontents = [Sisimai::Bite.DELIVERYSTATUS]<commit_msg>Update an error message pattern for "userunknown" on GSuite<commit_after>module Sisimai::Bite::Email
  # Sisimai::Bite::Email::GSuite parses a bounce email which created by G Suite.
  # Methods in the module are called from only Sisimai::Message.
  module GSuite
    class << self
      # Imported from p5-Sisimail/lib/Sisimai/Bite/Email/GSuite.pm
      require 'sisimai/bite/email'

      Indicators = Sisimai::Bite::Email.INDICATORS
      MarkingsOf = {
        message: %r/\A[*][*][ ].+[ ][*][*]\z/,
        rfc822:  %r{\AContent-Type:[ ]*(?:message/rfc822|text/rfc822-headers)\z},
        error:   %r/\AThe[ ]response([ ]from[ ]the[ ]remote[ ]server)?[ ]was:\z/,
        html:    %r{\AContent-Type:[ ]*text/html;[ ]*charset=['"]?(?:UTF|utf)[-]8['"]?\z},
      }.freeze
      MessagesOf = {
        userunknown:  ["because the address couldn't be found. Check for typos or unnecessary spaces and try again."],
        notaccept:    ['Null MX'],
        networkerror: [' responded with code NXDOMAIN'],
      }.freeze

      def description; return 'G Suite: https://gsuite.google.com'; end
      def smtpagent;   return Sisimai::Bite.smtpagent(self); end
      def headerlist;  return ['X-Gm-Message-State']; end

      # Parse bounce messages from G Suite (Transfer from G Suite to a destinaion host)
      # @param         [Hash] mhead       Message headers of a bounce email
      # @options mhead [String] from      From header
      # @options mhead [String] date      Date header
      # @options mhead [String] subject   Subject header
      # @options mhead [Array]  received  Received headers
      # @options mhead [String] others    Other required headers
      # @param         [String] mbody     Message body of a bounce email
      # @return        [Hash, Nil]        Bounce data list and message/rfc822
      #                                   part or nil if it failed to parse or
      #                                   the arguments are missing
      def scan(mhead, mbody)
        return nil unless mhead
        return nil unless mbody

        return nil unless mhead['from'].end_with?('<<EMAIL>>')
        return nil unless mhead['subject'].start_with?('Delivery Status Notification')
        return nil unless mhead['x-gm-message-state']

        require 'sisimai/address'
        dscontents = [Sisimai::Bite.DELIVERYSTATUS]
{'fraction_non_alphanumeric': 0.12163336229365769, 'fraction_numerical': 0.006081668114682885, 'mean_word_length': 2.396017699115044, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 7, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7369243', 'n_tokens_mistral': 1444, 'n_tokens_neox': 1383, 'n_words': 414}