Back to "La Comisión Consultiva recomienda que el Secretario General apruebe el siguiente proyecto de resolución:"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET Umami

La Comisión Consultiva recomienda que el Secretario General apruebe el siguiente proyecto de resolución:

Thursday, 12 September 2024

El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

Por lo tanto, la Comisión Consultiva recomienda que se apruebe el proyecto de presupuesto por programas para el bienio 2008-2009. posted a LOT en el pasado sobre la utilización de Umami para las analyticas en un entorno auto“-” administrado y incluso publicó La Comisión Consultiva observa con preocupación que, pese a los esfuerzos realizados por el Departamento de Operaciones de Mantenimiento de la Paz y la Oficina del Alto Comisionado de las Naciones Unidas para los Refugiados (ACNUR), no se han producido progresos significativos en la aplicación de las recomendaciones contenidas en su informe.. Sin embargo, estaba teniendo un problema en el que quería seguir a los usuarios de mi feed RSS; este post va en el sentido de por qué y cómo lo he resuelto

El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

El problema es que los lectores de RSS intentan pasar El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en el empleo, incluida la eliminación del trabajo forzoso. Agentes de usuario al solicitar el feed. Esto permite El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. a los proveedores para rastrear el número de usuarios y el tipo de usuarios que consumen el feed. Sin embargoM SK1 esto también significa que Umami identificará estas peticiones como El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre hombres y mujeres en el acceso a los servicios de salud reproductiva. peticiones. Esta es una cuestión para mi uso, ya que resulta en que la petición se ignora y no se sigue.

El agente de usuario de Feedbin es el siguiente:

Feedbin feed-id:1234 - 21 subscribers

Así que es bastante útil derecho, pasa algunos detalles útiles sobre lo que su id de feed es, el número de usuarios y el agente de usuarioM SK2 Sin embargoMSC3 esto también es un problema porque significa que Umami ignorará la petición ; de hecho, esSSK5 le devolverá un estado MNK6, pero el contenido contiene {"beep": "boop"} lo que significa que esto se identifica como una petición de bot. Esto es molesto porque no puedo manejarlo a través del manejo normal de errores M SK2it'es un 200, no decir un \403 etcMSC6

Cuando miramos el cuadro de mando de Umami después de hacer esta modificación ahora puedo ver los Usuarios originales que solicitó el feed:

El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la protección de los derechos humanos y las libertades fundamentales, incluidos los derechos económicos, sociales y culturales.

Así que podemos ver allí's ahora un grupo que habría desencadenado la detección del robot pero ahora podemos ver estos Y seguir las peticiones.

El Presidente (habla en inglés): De conformidad con el entendimiento alcanzado en las consultas previas del Consejo, consideraré que la Asamblea General desea concluir su examen de este tema del programa.

Por lo tanto, ¿qué' es la solución a estoM SK1 puedo' no analizar manualmente todas estas peticiones y detectar si Umami las detectará como un bot ; utiliza IsBot MSSK4httpsMSC5wwwMSP6npmjsMST7comMSV8paqueteM SV9isbotMSS10 para detectar si una petición es un bot o no MSS11 HayM SS12 no es equivalente al CS SV13 y esM S SV14 es una lista cambiante por lo que yo puedo M S SV15 ni siquiera usar esa lista M SS16 en el futuro podré ser ingenuo y usar la lista para detener si una solicitud es un robot o no Así que tengo que interceptar la petición antes de que llegue a Umami y cambiar el agente de usuario a algo que Umami aceptará para peticiones específicas.

Así que ahora he añadido algunos parámetros adicionales a mis métodos de seguimiento en Umami.Net. Estos permiten especificar el nuevo M SK2Agente de UsuarioDefault ' que se enviará a Umami en lugar del Agente Usuario OriginalMSC4 Esto me permite especificar que el Agente de usuario debe ser cambiado a un valor específico para peticiones específicasMNK5

El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. UmamiBackgroundSender Añadí el siguiente:

   public async Task TrackPageView(string url, string title, UmamiPayload? payload = null,
        UmamiEventData? eventData = null, bool useDefaultUserAgent = false)

Esto existe en todos los métodos de seguimiento y sólo establece un parámetro en el UmamiPayload El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre hombres y mujeres en materia de empleo, incluida la eliminación del trabajo forzoso.

El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en materia de empleo, incluida la eliminación de la discriminación por motivos de raza, color, sexo, idioma, religión o creencias. UmamiClient Estos pueden fijarse de la siguiente manera:

    [Fact]
    public async Task TrackPageView_WithUrl()
    {
        var handler = JwtResponseHandler.Create();
        var umamiClient = GetServices(handler);
        var response = await umamiClient.TrackPageViewAndDecode("https://example.com", "Example Page",
            new UmamiPayload { UseDefaultUserAgent = true });
        Assert.NotNull(response);
        Assert.Equal(UmamiDataResponse.ResponseStatus.Success, response.Status);
    }

En este test uso el nuevo TrackPageViewAndDecode El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. UmamiDataResponse object. Este objeto contiene un token JWT descodificado (que es inválido si es un bot, por lo que resulta útil para comprobarM SK3 y el estado de la solicitud .

PayloadService

Esto es todo gestionado en el Payload Servicio que es responsable de popular el objeto de carga de trabajo. Aquí está donde el UseDefaultUserAgent El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

Por defecto, asigno la carga de pago desde el HttpContext por lo que normalmente se obtiene este conjunto correctamente; IM SK1 mostraré más adelante dónde esto es retirado de Umami.

    private UmamiPayload GetPayload(string? url = null, UmamiEventData? data = null)
    {
        var httpContext = httpContextAccessor.HttpContext;
        var request = httpContext?.Request;

        var payload = new UmamiPayload
        {
            Website = settings.WebsiteId,
            Data = data,
            Url = url ?? httpContext?.Request?.Path.Value,
            IpAddress = httpContext?.Connection?.RemoteIpAddress?.ToString(),
            UserAgent = request?.Headers["User-Agent"].FirstOrDefault(),
            Referrer = request?.Headers["Referer"].FirstOrDefault(),
            Hostname = request?.Host.Host
        };

        return payload;
    }

Entonces tengo un fragmento de código llamado PopulateFromPayload que es donde el objeto de solicitud lo obtiene'la configuración de datos:

    public static string DefaultUserAgent =>
        $"Mozilla/5.0 (Windows 11)  Umami.Net/{Assembly.GetAssembly(typeof(UmamiClient))!.GetName().Version}";

    public UmamiPayload PopulateFromPayload(UmamiPayload? payload, UmamiEventData? data)
    {
        var newPayload = GetPayload(data: data);
        ...
        
        newPayload.UserAgent = payload.UserAgent ?? DefaultUserAgent;

        if (payload.UseDefaultUserAgent)
        {
            var userData = newPayload.Data ?? new UmamiEventData();
            userData.TryAdd("OriginalUserAgent", newPayload.UserAgent ?? "");
            newPayload.UserAgent = DefaultUserAgent;
            newPayload.Data = userData;
        }


        logger.LogInformation("Using UserAgent: {UserAgent}", newPayload.UserAgent);
     }        
        

Usted verá que esto define un nuevo agente de usuario en la parte superior del archivo (que yo he confirmado no es El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la protección de los derechos humanos y las libertades fundamentales, en particular los derechos económicos, sociales y culturales. detected as a bot). Entonces en la metodología detecta si el UserAgent es nulo (que no deberíaM SK2t suceder a menos que se llama de código sin un Contexto Http ) o si el UseDefaultUserAgent se fija. Si es así, entonces se fije el UserAgent por defecto y se añade al objeto de datos el Usuario original.

Esto es entonces registrado para poder ver qué UserAgent está siendo utilizado.

El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre los hombres y las mujeres en materia de empleo, incluida la adopción de medidas legislativas, administrativas, judiciales y de otra índole.

En Umami.Net M SK1 he añadido un número de nuevos métodos 'AndDecode' que devolven una UmamiDataResponse Objecto. Este objeto contiene el símbolo JWT descodificadoM SK1

    public async Task<UmamiDataResponse?> TrackPageViewAndDecode(
        string? url = "",
        string? title = "",
        UmamiPayload? payload = null,
        UmamiEventData? eventData = null)
    {
        var response = await TrackPageView(url, title, payload, eventData);
        return await DecodeResponse(response);
    }
    
        private async Task<UmamiDataResponse?> DecodeResponse(HttpResponseMessage responseMessage)
    {
        var responseString = await responseMessage.Content.ReadAsStringAsync();

        switch (responseMessage.IsSuccessStatusCode)
        {
            case false:
                return new UmamiDataResponse(UmamiDataResponse.ResponseStatus.Failed);
            case true when responseString.Contains("beep") && responseString.Contains("boop"):
                logger.LogWarning("Bot detected data not stored in Umami");
                return new UmamiDataResponse(UmamiDataResponse.ResponseStatus.BotDetected);

            case true:
                var decoded = await jwtDecoder.DecodeResponse(responseString);
                if (decoded == null)
                {
                    logger.LogError("Failed to decode response from Umami");
                    return null;
                }

                var payload = UmamiDataResponse.Decode(decoded);

                return payload;
        }
    }

Pueden ver que esto llama al normal TrackPageView el método entonces llama un método llamado DecodeResponse El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. beep El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer. boop strings (for bot detection). Si los encuentra entonces registra un aviso y devolve una BotDetected Status. Si no lo encuentra, entonces descubre el token JWT y devolve la carga de pago.

El token JWT en sí mismo es sólo una cadena codificadoa Base64 que contiene los datos que Umami ha almacenado. Esto se descodifica y se devolve como un UmamiDataResponse El Comité recomienda que el Estado Parte adopte todas las medidas necesarias para garantizar la igualdad de oportunidades entre hombres y mujeres en materia de empleo, incluida la eliminación del trabajo forzoso.

La fuente completa de este es a continuación:

Response Decoder
using System.IdentityModel.Tokens.Jwt;

namespace Umami.Net.Models;

public class UmamiDataResponse
{
    public enum ResponseStatus
    {
        Failed,
        BotDetected,
        Success
    }

    public UmamiDataResponse(ResponseStatus status)
    {
        Status = status;
    }

    public ResponseStatus Status { get; set; }

    public Guid Id { get; set; }
    public Guid WebsiteId { get; set; }
    public string? Hostname { get; set; }
    public string? Browser { get; set; }
    public string? Os { get; set; }
    public string? Device { get; set; }
    public string? Screen { get; set; }
    public string? Language { get; set; }
    public string? Country { get; set; }
    public string? Subdivision1 { get; set; }
    public string? Subdivision2 { get; set; }
    public string? City { get; set; }
    public DateTime CreatedAt { get; set; }
    public Guid VisitId { get; set; }
    public long Iat { get; set; }

    public static UmamiDataResponse Decode(JwtPayload? payload)
    {
        if (payload == null) return new UmamiDataResponse(ResponseStatus.Failed);
        payload.TryGetValue("visitId", out var visitIdObj);
        payload.TryGetValue("iat", out var iatObj);
        //This should only happen then the payload is dummy.
        if (payload.Count == 2)
        {
            var visitId = visitIdObj != null ? Guid.Parse(visitIdObj.ToString()!) : Guid.Empty;
            var iat = iatObj != null ? long.Parse(iatObj.ToString()!) : 0;

            return new UmamiDataResponse(ResponseStatus.Success)
            {
                VisitId = visitId,
                Iat = iat
            };
        }

        payload.TryGetValue("id", out var idObj);
        payload.TryGetValue("websiteId", out var websiteIdObj);
        payload.TryGetValue("hostname", out var hostnameObj);
        payload.TryGetValue("browser", out var browserObj);
        payload.TryGetValue("os", out var osObj);
        payload.TryGetValue("device", out var deviceObj);
        payload.TryGetValue("screen", out var screenObj);
        payload.TryGetValue("language", out var languageObj);
        payload.TryGetValue("country", out var countryObj);
        payload.TryGetValue("subdivision1", out var subdivision1Obj);
        payload.TryGetValue("subdivision2", out var subdivision2Obj);
        payload.TryGetValue("city", out var cityObj);
        payload.TryGetValue("createdAt", out var createdAtObj);

        return new UmamiDataResponse(ResponseStatus.Success)
        {
            Id = idObj != null ? Guid.Parse(idObj.ToString()!) : Guid.Empty,
            WebsiteId = websiteIdObj != null ? Guid.Parse(websiteIdObj.ToString()!) : Guid.Empty,
            Hostname = hostnameObj?.ToString(),
            Browser = browserObj?.ToString(),
            Os = osObj?.ToString(),
            Device = deviceObj?.ToString(),
            Screen = screenObj?.ToString(),
            Language = languageObj?.ToString(),
            Country = countryObj?.ToString(),
            Subdivision1 = subdivision1Obj?.ToString(),
            Subdivision2 = subdivision2Obj?.ToString(),
            City = cityObj?.ToString(),
            CreatedAt = createdAtObj != null ? DateTime.Parse(createdAtObj.ToString()!) : DateTime.MinValue,
            VisitId = visitIdObj != null ? Guid.Parse(visitIdObj.ToString()!) : Guid.Empty,
            Iat = iatObj != null ? long.Parse(iatObj.ToString()!) : 0
        };
    }
}
Usted puede ver que esto contiene una gran cantidad de información útil sobre la petición que Umami ha almacenado. Si deseaba por ejemplo mostrar un contenido diferente basado en locale, idiomaM SK2 navegador etc. esto le permite hacerlo .
    public Guid Id { get; set; }
    public Guid WebsiteId { get; set; }
    public string? Hostname { get; set; }
    public string? Browser { get; set; }
    public string? Os { get; set; }
    public string? Device { get; set; }
    public string? Screen { get; set; }
    public string? Language { get; set; }
    public string? Country { get; set; }
    public string? Subdivision1 { get; set; }
    public string? Subdivision2 { get; set; }
    public string? City { get; set; }
    public DateTime CreatedAt { get; set; }
    public Guid VisitId { get; set; }
    public long Iat { get; set; }

El Comité recomienda al Estado Parte que adopte todas las medidas necesarias para garantizar la igualdad entre los géneros y el empoderamiento de la mujer.

Así que sólo un breve post que cubre alguna nueva funcionalidad en Umami.Net 0.4.0 que le permite especificar un agente de usuario por defecto para peticiones específicas . Esto es útil para seguir las peticiones que Umami ignoraría de otro modoM SK3

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.