Esempio n. 1
0
        public static MessageBuildResult Build(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            decimal amount,
            DateTime time,
            object distinctId,
            MixpanelConfig config)
        {
            MessageBuildResult messageBuildResult = PeopleMessageBuilderBase.CreateMessage(
                token,
                superProperties,
                null,
                distinctId,
                config,
                "$append",
                rawValue => throw new InvalidOperationException());

            if (!messageBuildResult.Success)
            {
                return(messageBuildResult);
            }

            messageBuildResult.Message["$append"] = new Dictionary <string, object>(1)
            {
                {
                    "$transactions", new Dictionary <string, object>(2)
                    {
                        { "$time", TimeParser.ParseMixpanelFormat(time).Value },
                        { "$amount", amount }
                    }
                }
            };

            return(messageBuildResult);
        }
Esempio n. 2
0
 private void AssertDefault(MixpanelConfig config = null)
 {
     AssertFormattedProperties(
         config,
         ("SomeCoolProperty", "SomeCoolProperty"),
         ("someCoolProperty", "someCoolProperty"));
 }
Esempio n. 3
0
        public void When_NameFormattingConfigured_Then_FormattingAppliedToPropertyNames()
        {
            var config = new MixpanelConfig {
                MixpanelPropertyNameFormat = MixpanelPropertyNameFormat.TitleCase
            };

            var superProperties = CreateSuperProperties(
                // Must be overwritten by message property
                ObjectProperty.Default("PropertyA", PropertyOrigin.SuperProperty, 10),
                ObjectProperty.Default("PropertyC", PropertyOrigin.SuperProperty, 3));

            var rawProperties = new
            {
                PropertyA = 1,
                PropertyB = 2
            };

            MessageBuildResult messageBuildResult =
                TrackMessageBuilder.Build(Token, Event, superProperties, rawProperties, DistinctId, config);

            AssertMessageSuccess(
                messageBuildResult,
                Token,
                Event,
                DistinctId,
                new KeyValuePair <string, object>("Property A", 1),
                new KeyValuePair <string, object>("Property B", 2),
                new KeyValuePair <string, object>("Property C", 3));
        }
 public static MessageBuildResult BuildSetOnce(
     string token,
     IEnumerable <ObjectProperty> superProperties,
     object rawProperties,
     object distinctId,
     MixpanelConfig config)
 {
     return(Build("$set_once", token, superProperties, rawProperties, distinctId, config));
 }
Esempio n. 5
0
 private void AssertLowerCase(MixpanelConfig config = null)
 {
     AssertFormattedProperties(
         config,
         ("SomeCoolProperty", "some cool property"),
         ("someCoolProperty", "some cool property"),
         ("prop", "prop"),
         ("PropP", "prop p"),
         ("Some Cool Property", "some cool property"));
 }
Esempio n. 6
0
 private void AssertTitleCase(MixpanelConfig config = null)
 {
     AssertFormattedProperties(
         config,
         ("SomeCoolProperty", "Some Cool Property"),
         ("someCoolProperty", "Some Cool Property"),
         ("prop", "Prop"),
         ("PropP", "Prop P"),
         ("Some Cool Property", "Some Cool Property"));
 }
Esempio n. 7
0
        public static MessageCandidate CreateValidMessageCandidate(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config,
            out string errorMessage)
        {
            var messageCandidate = new MessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                PeopleSpecialPropertyMapper.RawNameToSpecialProperty);

            ObjectProperty tokenProp = messageCandidate.GetSpecialProperty(PeopleSpecialProperty.Token);

            if (tokenProp == null)
            {
                errorMessage = $"'{PeopleSpecialProperty.Token}' is not set.";
                return(null);
            }

            ValueParseResult tokenParseResult =
                PeopleSpecialPropertyParser.Parse(PeopleSpecialProperty.Token, tokenProp.Value);

            if (!tokenParseResult.Success)
            {
                errorMessage = $"Error parsing '{PeopleSpecialProperty.Token}'. {tokenParseResult.ErrorDetails}";
                return(null);
            }

            ObjectProperty distinctIdProp = messageCandidate.GetSpecialProperty(PeopleSpecialProperty.DistinctId);

            if (distinctIdProp == null)
            {
                errorMessage = $"'{PeopleSpecialProperty.DistinctId}' is not set.";
                return(null);
            }

            ValueParseResult distinctIdParseResult =
                PeopleSpecialPropertyParser.Parse(PeopleSpecialProperty.DistinctId, distinctIdProp.Value);

            if (!distinctIdParseResult.Success)
            {
                errorMessage = $"Error parsing '{PeopleSpecialProperty.DistinctId}'. {distinctIdParseResult.ErrorDetails}";
                return(null);
            }

            errorMessage = null;
            return(messageCandidate);
        }
        public static string Format(
            string propertyName,
            PropertyNameSource propertyNameSource,
            MixpanelConfig config = null)
        {
            MixpanelPropertyNameFormat propertyNameFormat =
                ConfigHelper.GetMixpanelPropertyNameFormat(config);

            if (propertyNameFormat == MixpanelPropertyNameFormat.None ||
                propertyNameSource != PropertyNameSource.Default)
            {
                return(propertyName);
            }

            bool sentenceCase = propertyNameFormat == MixpanelPropertyNameFormat.SentenceCase;
            bool titleCase    = propertyNameFormat == MixpanelPropertyNameFormat.TitleCase;
            bool lowerCase    = propertyNameFormat == MixpanelPropertyNameFormat.LowerCase;

            var newName = new StringBuilder(propertyName.Length + 5);

            var firstLetter = propertyName[0];

            if ((sentenceCase || titleCase) && !char.IsUpper(firstLetter))
            {
                firstLetter = char.ToUpper(firstLetter);
            }
            else if (lowerCase && !char.IsLower(firstLetter))
            {
                firstLetter = char.ToLower(firstLetter);
            }
            newName.Append(firstLetter);

            for (int i = 1; i < propertyName.Length; i++)
            {
                var letter = propertyName[i];
                if (char.IsUpper(letter))
                {
                    // Do not add space if previous letter is space
                    if (propertyName[i - 1] != ' ')
                    {
                        newName.Append(' ');
                    }

                    if (sentenceCase || lowerCase)
                    {
                        letter = char.ToLower(letter);
                    }
                }
                newName.Append(letter);
            }

            return(newName.ToString());
        }
        private static MessageBuildResult Build(
            string operation,
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config)
        {
            MessageCandidate messageCandidate = PeopleMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>();
            var set     = new Dictionary <string, object>();

            message[operation] = set;

            // Special properties
            PeopleMessageBuilderBase.RunForValidSpecialProperties(
                messageCandidate,
                (specialPropertyName, isMessageSpecialProperty, value) =>
            {
                if (isMessageSpecialProperty)
                {
                    message[specialPropertyName] = value;
                }
                else
                {
                    set[specialPropertyName] = value;
                }
            });

            // User properties
            PeopleMessageBuilderBase.RunForValidUserProperties(
                messageCandidate,
                rawValue => GenericPropertyParser.Parse(rawValue, allowCollections: true),
                (formattedPropertyName, value) =>
            {
                set[formattedPropertyName] = value;
            });

            return(MessageBuildResult.CreateSuccess(message));
        }
Esempio n. 10
0
        public static MessageBuildResult CreateMessage(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config,
            string actionName,
            Func <object, ValueParseResult> userPropertyParseFn)
        {
            MessageCandidate messageCandidate = CreateValidMessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>();
            var action  = new Dictionary <string, object>();

            message[actionName] = action;

            // Special properties
            RunForValidSpecialProperties(
                messageCandidate,
                (specialPropertyName, isMessageSpecialProperty, value) =>
            {
                // Ignore non-message specific special properties as they are not valid in profile update messages
                if (isMessageSpecialProperty)
                {
                    message[specialPropertyName] = value;
                }
            });

            // User properties
            RunForValidUserProperties(
                messageCandidate,
                userPropertyParseFn,
                (formattedPropertyName, value) =>
            {
                action[formattedPropertyName] = value;
            });

            return(MessageBuildResult.CreateSuccess(message));
        }
 public static MessageBuildResult Build(
     string token,
     IEnumerable <ObjectProperty> superProperties,
     object rawProperties,
     object distinctId,
     MixpanelConfig config)
 {
     return(PeopleMessageBuilderBase.CreateMessage(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                "$union",
                rawValue => CollectionParser.Parse(rawValue, _ => GenericPropertyParser.Parse(_, allowCollections: false))));
 }
 public static MessageBuildResult Build(
     string token,
     IEnumerable <ObjectProperty> superProperties,
     object rawProperties,
     object distinctId,
     MixpanelConfig config)
 {
     return(PeopleMessageBuilderBase.CreateMessage(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                "$add",
                NumberParser.Parse));
 }
Esempio n. 13
0
        public MessageData(
            IDictionary<string, string> specialPropsBindings,
            IDictionary<string, string> distinctIdPropsBindings,
            MessagePropetiesRules messagePropetiesRules,
            SuperPropertiesRules superPropertiesRules,
            MixpanelConfig config = null)
        {
            _specialPropsBindings = specialPropsBindings ?? new Dictionary<string, string>();
            _distinctIdPropsBindings = distinctIdPropsBindings ?? new Dictionary<string, string>();
            _messagePropetiesRules = messagePropetiesRules;
            _superPropertiesRules = superPropertiesRules;
            _valueParser = new ValueParser();
            _nameFormatter = new PropertyNameFormatter(config);
            _propertiesDigger = new PropertiesDigger();

            SpecialProps = new Dictionary<string, object>();
            Props = new Dictionary<string, object>();
        }
Esempio n. 14
0
        public MessageData(
            IDictionary <string, string> specialPropsBindings,
            IDictionary <string, string> distinctIdPropsBindings,
            MessagePropetiesRules messagePropetiesRules,
            SuperPropertiesRules superPropertiesRules,
            MixpanelConfig config = null)
        {
            _specialPropsBindings    = specialPropsBindings ?? new Dictionary <string, string>();
            _distinctIdPropsBindings = distinctIdPropsBindings ?? new Dictionary <string, string>();
            _messagePropetiesRules   = messagePropetiesRules;
            _superPropertiesRules    = superPropertiesRules;
            _valueParser             = new ValueParser();
            _nameFormatter           = new PropertyNameFormatter(config);
            _propertiesDigger        = new PropertiesDigger();

            SpecialProps = new Dictionary <string, object>();
            Props        = new Dictionary <string, object>();
        }
Esempio n. 15
0
        public MessageCandidate(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config,
            Func <string, string> mapRawNameToSpecialPropertyFn)
        {
            this.config = config;
            this.mapRawNameToSpecialPropertyFn = mapRawNameToSpecialPropertyFn;

            SpecialProperties = new Dictionary <string, ObjectProperty>();
            UserProperties    = new Dictionary <string, ObjectProperty>();

            ProcessSuperProperties(superProperties);
            ProcessRawProperties(rawProperties);
            ProcessToken(token);
            ProcessDistinctId(distinctId);
        }
        // Message example:
        // {
        //     "$token": "36ada5b10da39a1347559321baf13063",
        //     "$distinct_id": "13793",
        //     "$unset": [ "Days Overdue" ]
        // }

        public static MessageBuildResult Build(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            IEnumerable <string> propertyNames,
            object distinctId,
            MixpanelConfig config)
        {
            MessageCandidate messageCandidate = PeopleMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                null,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>();

            // Special properties
            PeopleMessageBuilderBase.RunForValidSpecialProperties(
                messageCandidate,
                (specialPropertyName, isMessageSpecialProperty, value) =>
            {
                // Ignore non-message specific special properties as they are not valid in profile update messages
                if (isMessageSpecialProperty)
                {
                    message[specialPropertyName] = value;
                }
            });

            message["$unset"] = propertyNames ?? new string[0];

            return(MessageBuildResult.CreateSuccess(message));
        }
        public static MessageBuildResult Build(
            string token,
            IEnumerable <ObjectProperty> superProperties,
            object distinctId,
            MixpanelConfig config)
        {
            MessageBuildResult messageBuildResult = PeopleMessageBuilderBase.CreateMessage(
                token,
                superProperties,
                null,
                distinctId,
                config,
                "$delete",
                rawValue => throw new InvalidOperationException());

            if (!messageBuildResult.Success)
            {
                return(messageBuildResult);
            }

            messageBuildResult.Message["$delete"] = Empty;
            return(messageBuildResult);
        }
 public PeopleUnionMessageBuilder(MixpanelConfig config = null)
     : base(config)
 {
 }
 public PropertyNameFormatter(MixpanelConfig config = null)
 {
     _config = config;
 }
 public static string Format(
     ObjectProperty objectProperty,
     MixpanelConfig config = null)
 {
     return(Format(objectProperty.PropertyName, objectProperty.PropertyNameSource, config));
 }
 public PeopleDeleteMessageBuilder(MixpanelConfig config = null)
     : base(config)
 {
 }
Esempio n. 22
0
 public PropertyNameFormatter(MixpanelConfig config = null)
 {
     _config = config;
 }
 public PeopleSetOnceMessageBuilder(MixpanelConfig config = null)
     : base(config)
 {
 }
 protected PeopleMessageBuilderBase(MixpanelConfig config = null)
     : base(config)
 {
 }
 public AliasMessageBuilder(MixpanelConfig config = null)
     : base(config)
 {
 }
 protected TrackMessageBuilderBase(MixpanelConfig config = null)
     : base(config)
 {
 }
 public PeopleAppendMessageBuilder(MixpanelConfig config = null)
     : base(config)
 {
 }
Esempio n. 28
0
        public static MessageBuildResult Build(
            string token,
            string @event,
            IEnumerable <ObjectProperty> superProperties,
            object rawProperties,
            object distinctId,
            MixpanelConfig config)
        {
            if (string.IsNullOrWhiteSpace(@event))
            {
                return(MessageBuildResult.CreateFail($"'{nameof(@event)}' is not set."));
            }

            MessageCandidate messageCandidate = TrackMessageBuilderBase.CreateValidMessageCandidate(
                token,
                superProperties,
                rawProperties,
                distinctId,
                config,
                out string messageCandidateErrorMessage);

            if (messageCandidate == null)
            {
                return(MessageBuildResult.CreateFail(messageCandidateErrorMessage));
            }

            var message = new Dictionary <string, object>(2);

            message["event"] = @event;

            var properties = new Dictionary <string, object>();

            message["properties"] = properties;

            // Special properties
            foreach (KeyValuePair <string, ObjectProperty> pair in messageCandidate.SpecialProperties)
            {
                string         specialPropertyName = pair.Key;
                ObjectProperty objectProperty      = pair.Value;

                ValueParseResult result =
                    TrackSpecialPropertyParser.Parse(specialPropertyName, objectProperty.Value);
                if (!result.Success)
                {
                    // The only required special properties are 'event' and 'token' which are controlled separately
                    continue;
                }

                properties[specialPropertyName] = result.Value;
            }

            // User properties
            foreach (KeyValuePair <string, ObjectProperty> pair in messageCandidate.UserProperties)
            {
                string         formattedPropertyName = pair.Key;
                ObjectProperty objectProperty        = pair.Value;

                ValueParseResult result = GenericPropertyParser.Parse(objectProperty.Value, allowCollections: true);
                if (!result.Success)
                {
                    continue;
                }

                properties[formattedPropertyName] = result.Value;
            }

            return(MessageBuildResult.CreateSuccess(message));
        }
 public TrackMessageBuilder(MixpanelConfig config = null)
     : base(config)
 {
 }
 protected MessageBuilderBase(MixpanelConfig config = null)
 {
     Config = config;
     ValueParser = new ValueParser();
     PropertyNameFormatter = new PropertyNameFormatter(config);
 }
Esempio n. 31
0
 private void AssertFormattedProperties(
     MixpanelConfig config = null,
     params (string original, string expected)[] props)