Ostatnio opisałem jak możemy odebrać trackback, teraz pora na jego wysyłanie :)

Oczywiście, stoimy przed tymi samymi problemami co w przypadku wysyłania pingback. Do tego, jeżeli mamy zaimplementowany pingback, warto ustalić pewną kolejność wykonywanych poleceń – najpierw trackback a potem pingback czy na odwrót? Powinniśmy także wysłać tylko jedną rzecz, po co zaśmiecać i spamować inne blogi/źródła.

Cały proces wysyłania trackback jest bardzo podobny do tego z pingback:

  1. Pobieramy wszystkie URLe z naszego tekstu i robimy na nich distinct
  2. Dla każdego urla
    1. Pobieramy stronę
    2. Sprawdzamy czy istnieje RDF (i opcjonalnie rel=trackback)
    3. Wywołujemy metodę HTTP POST/PUT

Pierwszy krok jest taki sam jak przy pingback, więc go pomijam tutaj.

Wysyłanie trackbacka

Ponownie, RestSharp for rescue:

private static readonly Regex UrlsRegex = new Regex(
    @"<a.*?href=[""'](?<url>.*?)[""'].*?>(?<name>.*?)</a>"
    , RegexOptions.IgnoreCase | RegexOptions.Compiled
);

public void Send(Post post, Uri itemUri)
{
    var uris = get_uris(post.Content);
    foreach (var uri in uris)
    {
        var trackback = send_trackback(post, itemUri, uri);

        if (!trackback)
        {
            send_ping(itemUri, uri);
        }
    }
}

private bool send_trackback(Post post, Uri itemUri, Uri targetUri)
{
    if (itemUri == null
        || targetUri == null)
    {
        return false;
    }

    try
    {
        var request = new RestRequest(Method.GET);
        _restClient.BaseUrl = targetUri.AbsoluteUri;
        var response = _restClient.Execute(request);

        var trackbackUri = trackabck_uri(response.Content);

        if (trackbackUri == null)
        {
            return false;
        }

        request = new RestRequest(Method.POST);
        _restClient.BaseUrl = trackbackUri.AbsoluteUri;
        request.AddParameter("title", post.Title);
        request.AddParameter("url", itemUri.AbsoluteUri);
        request.AddParameter("excerpt", post.Description);
        // method query db for blog configuration etc.
        request.AddParameter("blog_name", get_blog_name());

        response = _restClient.Execute(request);

        // we can parse error etc, but this should be enough
        return response.StatusCode == HttpStatusCode.OK 
            && response.Content.Contains("<error>0</error>");

    }
    catch (Exception ex)
    {
        _log.ErrorException("Error occured during sending trackback from: {0} to {1}"
            .FormatWith(itemUri, targetUri), ex);
    }

    return false;
}

private Uri trackabck_uri(string content)
{
    var url = TrackbackLinkRegex.Match(content).Groups[1].ToString().Trim();
    Uri uri;

    return Uri.TryCreate(url, UriKind.Absolute, out uri) ? uri : null;
}

Podsumowanie

Nie było tak żle? :) to chyba kończy temat związany z linkbackami.

Uwagi? Sugestie? Czy uważacie, że w ogóle warto się w to bawić? Czy może to nie ma sensu i wystarczy tylko i wyłącznie implementacja pingback?