Программное добавление твитта с изображением на C#

Программирование

Tagged Under : , ,

Понадобилось коллеге выполнить в рамках одной из задач добавление сообщения в twitter вместе с картинкой. Примеров не нашёл, но я после непродолжительного поиска нашёл данный исходный код.
Добавил сюда, чтобы потом не искать больше.

OAuth + ASP.NET (Часть 1): авторизуемся через twitter, google и yahoo по протоколу OAuth 1.0

Программирование, Проекты

Tagged Under : , , , , , , , ,

Собственно, понадобилось сделать авторизацию через аккаунты различных популярных сервисов: twitter, facebook, mail.ru, google, yandex и по возможности ещё каких-нибудь. Так как я являюсь ярым сторонником подхода: если есть достаточно времени, то лучше сделать самому, – я решил реализовать это самостоятельно: изобрести велосипед в очередной раз.

Функционал будет минимальным: пройти авторизацию, получить маркер доступа (access_token) и идентификатор пользователя, ник, опционально что-нибудь ещё, например, email.

Итак, начиная с этой статьи, посвященной авторизации через twitter, google и yahoo (взят для дополнительного примера), используя и постигая OAuth 1.0, я попробую начать серию статей об OAuth-авторизации (в том числе и версии протокола 2.0 с отдельным классом и примерами для mail.ru, yandex’а, фейсбука и т.д.) через различные сервисы, поддерживающие её. При этом результатом будет небольшая библиотека с описанной функциональностью.
Читать дальше »

Постинг новостей, сообщений и т.п. в twitter

Программирование

Tagged Under : ,

Весьма популярным в нынешнее время является дублирование сообщений, новостей, статей и т.д. в твиттер. Существует масса библиотек, которые успешно справляются с этой задачей, но я решил написать свою собственную реализацию, чтобы разобраться как это вообще реализуется от начала и до конца.
Итак, нам понадобится добавить веб-приложение к твиттер-аккаунту и получить consumer key, consumer secret, access token и access token secret. Далее я написал следующий класс, у которого всего один публичный статический метод, отправляющий сообщение в твиттер:

public static class TwitterPost
{
/* задаем значения переменным полученные ранее при регистрации веб-приложения*/
    static string consumerkey = "";
    static string access_token = "";
    static string secret_token = "";
    static string consumer_secret = "";

/* энкодим строку, подсмотрено где-то и чуть изменено*/
    static string unreservedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~";

    static string UrlEncode(string value)
    {
        StringBuilder result = new StringBuilder();

        foreach (char symbol in value)
        {
            if (unreservedChars.IndexOf(symbol) != -1)
            {
                result.Append(symbol);
            }
            else
            {
                if (symbol == ' ')
                    result.Append("%20");
                else
                    result.Append(HttpUtility.UrlEncode(symbol.ToString(), Encoding.UTF8).ToUpper());
            }
        }

        return result.ToString();
    }
/*получаем подпись запроса*/
    static string getHMACSHA1(string key, string sourceStr)
    {
        UTF8Encoding encoding = new UTF8Encoding();
        string token_secret = secret_token;

        HMACSHA1 hmacsha1 = new HMACSHA1(encoding.GetBytes(HttpUtility.UrlEncode(key) + "&" + HttpUtility.UrlEncode(token_secret)));
        byte[] encoded = hmacsha1.ComputeHash(encoding.GetBytes(sourceStr));
        return Convert.ToBase64String(encoded);
    }

    static string getNonce()
    {
        Random rnd = new Random();
        int nonce = rnd.Next(1, Int32.MaxValue);
        return nonce.ToString();
    }

/* получаем дельту времени между сервером и твиттером, необходимо, иначе будет ругаться твиттер 401 ошибкой */
    static string getTimestamp()
    {
        int delta = GetTimestampDelta();
        return (((TimeSpan)(DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0))).TotalSeconds + delta).ToString();
    }

/* генерим базовую строку запроса на основе словаря параметров, метода и адреса */
    static string getBasesign(string method, string baseUrl, Dictionary<string, string> items)
    {
        StringBuilder sb = new StringBuilder();
        foreach (KeyValuePair<string, string> item in items.OrderBy(x => x.Key))
            if (sb.Length > 0)
                sb.AppendFormat("%26{0}%3D{1}", UrlEncode(item.Key), UrlEncode(item.Value));
            else sb.AppendFormat("{0}%3D{1}", UrlEncode(item.Key), UrlEncode(item.Value));
        return string.Format("{2}&{0}&{1}", UrlEncode(baseUrl), sb.ToString(), method);
    }

/* на выходе получим значение заголовка запроса Authorization, надо, конечно, все контстантные строки запрятать в строку форматирования */
    static string getAuthorization(string oauth_nonce, string oauth_signature_method, string oauth_timestamp, string oauth_signature, string oauth_version)
    {
        return string.Format("OAuth {0}="{1}", {2}="{3}", {4}="{5}", {6}="{7}",  {12}="{13}", {8}="{9}", {10}="{11}"", "oauth_nonce", oauth_nonce, "oauth_signature_method", oauth_signature_method, "oauth_timestamp", oauth_timestamp, "oauth_consumer_key", consumerkey, "oauth_token", access_token, "oauth_signature", oauth_signature, "oauth_version", oauth_version);
    }

/* получаем timestamp твиттера и вычисляем разницу с нашим и сохраняем в Application, чтобы потом не запрашивать */
    private static int GetTimestampDelta()
    {
        int delta = 0;
        if (HttpContext.Current.Application["twitterTimeDelta"] == null)
        {
            string toUrl = "http://api.twitter.com/1/help/test.json";
            string method = "GET";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(toUrl);
            req.Method = method;
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            delta = int.Parse(resp.Headers["X-Transaction"].Split('-')[0]);
            int serverTimestamp = (int)((TimeSpan)(Convert.ToDateTime(resp.Headers["Date"]) - new DateTime(1970, 1, 1, 0, 0, 0))).TotalSeconds;
            delta = delta - serverTimestamp;
            HttpContext.Current.Application["twitterTimeDelta"] = delta;
        }
        else
            delta = (int)HttpContext.Current.Application["twitterTimeDelta"];
        return delta;
    }

/* отправляем твитт */
    public static void UpdateStatus(string text)
    {
        string toUrl = "http://api.twitter.com/1/statuses/update.json";
        string method = "POST";
        string timestamp = getTimestamp().Split(',')[0];
        string nonce = getNonce();
        Dictionary<string, string> items = new Dictionary<string, string>();
        items.Add("oauth_consumer_key", consumerkey);
        items.Add("oauth_nonce", nonce);
        items.Add("oauth_version", "1.0");
        items.Add("oauth_signature_method", "HMAC-SHA1");
        items.Add("oauth_timestamp", timestamp);
        items.Add("oauth_token", access_token);
        items.Add("status", UrlEncode(text));

        string basesign = getBasesign(method,
                                        toUrl,
                                        items);
        string sign = getHMACSHA1(consumer_secret,
                        basesign);

        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(toUrl);
        req.Method = method;
        string auth = getAuthorization(nonce, "HMAC-SHA1", timestamp, UrlEncode(sign), "1.0");
        req.Headers.Add("Authorization", auth);
        byte[] data = Encoding.UTF8.GetBytes("status=" + UrlEncode(text));
        req.ContentLength = data.Length;
        req.ContentType = "application/x-www-form-urlencoded";
        req.ServicePoint.Expect100Continue = false;
        req.GetRequestStream().Write(data, 0, data.Length);
/*на всякий случай ловим исключение, вдруг ошибка 401*/
        try
        {
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
        }
        catch (Exception)
        {
        }
    }
}

Используем так:

TwitterPost.UpdateStatus(text);

Впринципе оказалось несложно, проблему вызвала только необходимость синхронизации с твиттером timestamp’а и то, только потому что я не думал, что это может повлиять на работу.

Длину сообщения надо регулировать самостоятельно, поскольку твиттер не будет его обрезать, оно просто не будет проходить.

Пример работы тут, а вот результат

Эксперимент: автоматическое продвижение в твиттере

Разное

Tagged Under : ,

Продвигают, как выяснилось, и в твиттере.

Недавно кинул в твиттер текст, с упоминанием слова «блог» и «твиттер», и тут же получил двух фолловеров. Такая реакция заставила меня погуглить и в результате я нашел сервис для автоматического продвижения в твиттере pdpp.ru.

Авторы сервиса сконцентрировались на ключевых словах, поэтому появилась мысль немного поэкспериментировать:

  1. Выяснить насколько сервис адекватен;
  2. Возможно ли получить таким путём «нормальных» фолловеров (утопическая идея);
  3. Продвинуть свои ссылки через фолловеров.

Для начала решил создать экспериментальный аккаунт и употребить «популярные» слова, например: секс, наркотики, рок-н-ролл, блог, твиттер и т.д. Все слова упоминались единожды.
Потребовалось где-то 9-10 сообщений, чтобы всё, что пришло в голову, упомянуть. А дальше пришлось немного подождать. В итоге к утру ко мне добавилось 42 фолловера.

На втором шаге эксперимента, я всех добавил, чтобы не отвалились и заполучил ещё 6. Итого 48 фолловеров. После добавления лента моего экспериментального аккаунта наполнилась кучей спама и ссылок. Даже странно после этого видеть сообщения, в которых пользователи, использующие автоматическое продвижение, недоумевают почему их не фолловят.

На заключительном этапе удалил всю ерунду и бросил ссылку на старую игрушку — идея провальна была изначально, но решил таки попробовать. В результате метрика и аналитикс показали 0 результат.

В итоге сделал следующие выводы:

  • Сервис неадекватен: одного упоминания ключевого слова недостаточно, надо проверять его наличие в нескольких сообщениях, желательно разбросанных по времени
  • Автофолловеров «нормальных» можно сказать нет: от всех идёт только реклама
  • 0 выгода, т.к. по ссылкам никто не переходит

В том виде, в котором на данный момент сервис существует продвинуться сложно: нет достаточного соответствия ключевых слов и интересов пользователей, что приводит к тому, что сообщения фолловеров выглядят похожими на спам, а зачастую им и являются, и как следствие – отсутствие взаимного фолловинга.

P.S.: экспериментальный аккаунт в твиттере

Очередной глюк твиттера (Видео): псевдорост кол-ва новых сообщений

Разное

Tagged Under : , , ,

Очередной глюк твиттера: псевдорост кол-ва новых сообщений

Разное

Tagged Under : , , ,

Поймал сегодня, скрины ниже. Кол-во сообщений растёт и не останавливается. Смотрим на время.

много скринов чуть ниже