Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Кросспостинг в Twitter, Facebook, Livejournal, Vkontakte

Автор: chernikov

Когда я писал проект crafthunters.com, я заметил что для раскрутки клиенты используют социальные сети. Пользовались виджетами и лайками, но по хорошему надо было попадать в ленту новостей. Кроме того, популярный вконтакте вывел новости на главную страницу в сентябре. Т.е. для распространения контента надо было адаптировать standalone блог для представления в социальных сетях, используя простую истину: попасть в ленту новостей популярных социальных сетей. Вначале это происходило вручную и приносило более половины траффика. Потом пришла идея это всё автоматизировать. 

Популярными социальными сетями у нас были:

                • facebook
                • вконтакте
                • livejournal
                • твиттер


Предстояло настроить автоматический кросспостинг в каждую из социальных сетей, который до этого вели вручную. Нужно еще уточнить, что размещать записи в социальных сетях необходимо было не у себя на стене\бложике, а в группе\сообществе.

Далее я хочу представить реализацию кросспостинга под эти четыре социальные сети для asp.net mvc.


0. Основные принципы.

Перво-наперво необходимо получить права и сохранить их в базе данных для последующего использования. Вторым шагом было установка в какую группу\сообщество будет добавляться контент (задача по сути только для вконтакта). Третьим шагом было создание записи в группе\сообществе с активной ссылкой на оригинальный пост.

Для твиттера, фейсбука и вконтакте используется API на основе OAuth и для работы с ними надо было зарегистировать приложение в каждой социальной сети для этих целей.

Чтобы не повторяться, я сразу расскажу как происходит работа c OAuth (для twitter xAuth). Вначале мы передаем id приложения и список прав, которые хотим получить. Список прав — это к каким ресурсам мы разрешаем доступ нашего приложения. Выглядит это так:



После разрешения, мы получаем код по которому получаем токен доступа. К каждому обращению на сервер мы передаем этот токен и тем самым провайдер услуг (вконтакте, фейсбук и твиттер) знают что нам можно доверять и разрешают совершить действие (в нашем случае — кросспостинг).

1. Livejournal

ЖЖ уже давно используется для кросспостинга и делает он это через XML-RPC команды. Почитав документацию (http://www.livejournal.com/doc/server/ljp.csp.xml-rpc.protocol.html) использовав библиотеку для .net xml-rpc (http://www.xml-rpc.net/) я приступил к реализации.

Создаем интерфейс взаимодействия:

Код:
[XmlRpcUrl("http://www.livejournal.com/interface/xmlrpc")]
 public interface ILj : IXmlRpcProxy
 {
 [XmlRpcMethod("LJ.XMLRPC.login")]
 LjUserInfo Login(UserPassword user);
 [XmlRpcMethod("LJ.XMLRPC.postevent")]
 PostLjAnswer Post(PostLj post);
 }

Получение доступа

Логин и пароль передаются в открытом виде и передаются по протоколу веб-сервиса. Создаем класс для получения прав. 

Код:
public class UserPassword
{
 [JsonProperty("username")]
 public string username { get; set; }
[JsonProperty("password")]
 public string password { get; set; }
public int ver
 {
 get
 {
 return 1;
 }
 }
}

При каждой публикации логин и пароль также передаются, так что метод Login по сути только проверяет правильность пары логин\пароль.

Проверка доступа.

Код:
public LjUserInfo Auth(UserPassword username)
{
 ILj proxy = XmlRpcProxyGen.Create<ILj>();
 var ans = proxy.Login(username);
 return ans;
}

Ответ ans мы анализируем на положительный ответ иначе выдаем ошибку.

Добавление записи столь же тривиально:

Код:
public void Publish(UserPassword username, Post message, string ljgroup = null)
{
 ILj proxy = XmlRpcProxyGen.Create<ILj>();
 var post = new PostLj();
 post.username = username.username;
 post.password = username.password;
 post.ver = 1;
 post.@event = message.Content;
 post.subject = message.Title;
 post.lineendings = "pc";
 post.year = DateTime.Now.Year;
 post.mon = DateTime.Now.Month;
 post.day = DateTime.Now.Day;
 post.hour = DateTime.Now.Hour;
 post.min = DateTime.Now.Minute;
 if (!string.IsNullOrWhiteSpace(ljgroup))
 {
 post.usejournal = ljgroup;
 }
 else
 {
 post.usejournal = username.username;
 }
 var ans = proxy.Post(post);
}

Собственно всё очень просто. Конечно, есть очень много дополнительных опций и библиотека достаточно обширна, но задача — добавить наш пост в ЖЖ — решается легко.

Что не понравилось — передача пароля в открытом виде или в md5 по незащищеному каналу.

2. Твиттер

Для твиттера я использовал популярную библиотеку www.twitterizer.net/ но для начала надо было зарегистрировать приложение по адресу: dev.twitter.com/apps.

Права которые будет запрашивать приложение — как на чтение так и на запись. Кроме всего прочего, приложение получает бесконечный по сроку истечения токен для использования. Этот токен необходимо сохранить в БД. (Таблица Social.JsonResource)

Получение прав присходит по следующему сценарию:

Код:
public string Authorize(string redirectTo)
{
 OAuthTokenResponse requestToken = OAuthUtility.GetRequestToken(Config.twitterConsumerKey, Config.twitterConsumerSecret, redirectTo);
// Direct or instruct the user to the following address:
 Uri authorizationUri = OAuthUtility.BuildAuthorizationUri(requestToken.Token);
return authorizationUri.ToString();
}

Мы передаем два ключа (ключ приложения и секретный ключ), и переходим на страницу твиттера для подтверждения прав. Твиттер запрашивает права и возвращает нас по адресу redirectTo куда дополнительно передает код. По этому коду мы получаем токен доступа. Далее мы обновляем статус (создаем короткое сообщение) через приложение:

Код:
public void Publish(Post post)
{
 var tokens = new OAuthTokens();
 tokens.ConsumerKey = Config.twitterConsumerKey;
 tokens.ConsumerSecret = Config.twitterConsumerSecret;
 tokens.AccessToken = twitterAccessToken.Token;
 tokens.AccessTokenSecret = twitterAccessToken.TokenSecret;
TwitterStatus.Update(tokens, post.TwitterText);
}

3. Facebook

Регистрируем приложение по адресу: developers.facebook.com/apps

Получаем токен доступа. Вначале отправляем для получения разрешения прав:

Код:
public string Authorize(string redirectTo)
{
 return string.Format(AuthorizeUri, Config.AppId, redirectTo);
}
public ActionResult GetFbCode()
{
 var fbSocial = currentUser.Socials.Where(p => p.Provider == "facebook").FirstOrDefault();
 if (fbSocial != null)
 {
 return RedirectToAction("Index");
 }
 else
 {
 return Redirect(fbProvider.Authorize("http://" + HostName + "/Social/SaveFbCode"));
 }
}

Обрабатываем код для получения токена доступа:

Код:
public ActionResult SaveFbCode()
{
 if (Request.Params.AllKeys.Contains("code"))
 {
 var code = Request.Params["code"];
 if (ProcessFbCode(code))
 {
 return RedirectToAction("Index");
 }
 }
 return View("CantInitialize");
}
protected bool ProcessFbCode(string code)
{
 if (fbProvider.GetAccessToken(code, "http://" + HostName + "/Social/SaveFbCode"))
 {
 var jObj = fbProvider.GetUserInfo();
 var fbUserInfo = JsonConvert.DeserializeObject<FbUserInfo>(jObj.ToString());
var fbAccess = new FbAccessToken()
 {
 AccessToken = fbProvider.AccessToken
 };
 var jsonFbAccess = JsonConvert.SerializeObject(fbAccess);
 var fbSocial = currentUser.Socials.Where(p => p.Provider == "facebook").FirstOrDefault();
 if (fbSocial == null)
 {
 fbSocial = new Models.Social()
 {
 UserID = currentUser.ID,
 JsonResource = jsonFbAccess.ToString(),
 Provider = "facebook",
 UserInfo = jObj.ToString()
 };
 repository.CreateSocial(fbSocial);
 }
 else
 {
 fbSocial.UserInfo = jObj.ToString();
 repository.UpdateSocial(fbSocial);
 }
 return true;
 }
 return false;
}

Тут важная деталь при получении бессрочного токена доступа мы в параметре запроса параметров должны запросить &scope=...,offline тем самым избавив себя запрашивать этот токен постоянно, но для большей секретности этот фрагмент можно переделать и для использования токена с истекаемым сроком годности.

Создание поста

Код:
public ActionResult CrossPostFb(int id)
{
 var post = repository.Posts.Where(p => p.ID == id).FirstOrDefault();
var fbSocial = currentUser.SocialGetByProvider("facebook");
 if (post != null && post.UserID == currentUser.ID && fbSocial != null)
 {
 var postSocial = new Social.Post();
 if (!string.IsNullOrWhiteSpace(post.PreviewUrl))
 {
 //ссылка на изображение
 postSocial.Preview = "http://" + HostName + post.PreviewUrl;
 }
 postSocial.Title = post.Title;
 postSocial.Teaser = post.Subtitle;
 //ссылка на оригинал статьи
 postSocial.Link = "http://" + HostName + "/Post/" + post.ID.ToString();
//устанавливаем сохраненые токены
 var fbAccess = JsonConvert.DeserializeObject<FbAccessToken>(fbSocial.JsonResource);
 fbProvider.AccessToken = fbAccess.AccessToken;
//публикуем пост
 fbProvider.Publish(postSocial);
 repository.CrossPost(post, Post.CrossProvider.facebook);
 }
 return RedirectToAction("Index");
}

В зависимости от установленных параметров создастся запись. При установке активной ссылки facebook самостоятельно выберет нужную ему картинку

4. Вконтакте

Вконтакте предлагает самый непростой алгоритм взаимодействия.

Начнем по порядку: создавать посты как у себя на стене так и на стене группы может только Standalone приложение (а не веб), поэтому регистрировать приложение (http://vkontakte.ru/editapp?act=create&site=1) нужно указывать [x] Standalone-приложение.

Второе: для добавления к записи картинки ее нужно предварительно загрузить.

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

Четвертое: ссылка на оригинальный пост размещается в параметре attachments и при добавлении ссылки не гарантирует добавление заметки.

Собственно остальное всё так же, так что приступим и получим права:

Код:
public ActionResult GetVkCode()
{
 var vkSocial = currentUser.Socials.Where(p => p.Provider == "vkontakte").FirstOrDefault();
 if (vkSocial != null)
 {
 return RedirectToAction("Index");
 }
 else
 {
 return Redirect(vkProvider.Authorize("http://" + HostName + "/Social/SaveVkCode"));
 }
}
public string Authorize(string redirectTo)
{
 return string.Format(AuthorizeUri, Config.AppKey, redirectTo);
}

Для нашего кросспостинга мы запрашиваем следующие уровни доступа: photos, groups, wall, offline. Т.е. можем загружать фоточки в группы на стену в любое время.

Публикация

Перед публикацией на стену группы нам нужно узнать номер этой группы по имени (groups.getById). Удивительно то, что группы (а также персональные страницы) нумеруются в отрицательную сторону. Т.е. 
после получения результата значение gid надо умножить на -1.

Потом мы запрашиваем сервер для загрузки фотографий: photos.getWallUploadServer, а не photos.getUploadServer — хоть они и идентичны почти.

Далее мы через post по полученному url-запросу посылаем фотографию на сервер вконтакте. Я использовал библиотеку UploadHelper (http://aspnetupload.com/).

После загрузки на сервер надо передать команду о сохранении этого изображения: photos.saveWallPhoto — на что получаем id фотографии. Если вы использовали photos.getUploadServer вместо photos.getWallUploadServer — то фотография не сохранится.

И уже следующим этапом мы добавляем фотографию на стену группы/или персональной страницы (wall.post).

Собственно всё.

5. Плюшки

Попробовать можно тут: http://cocosanka.ru (после регистрации, можно записать что-то бессмысленное в блог, и потом откросспостить).

Скачать исходники тут: https://bitbucket.org/chernikov/cocosanka2

Для работы с данными я использовал библиотеку Json.net(http://json.codeplex.com/) переводя автоматически полученные строки в объекты. 

Ключи приложений хранятся в Web.config, но необходимо будет прописать свои.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
90K
06 апреля 2013 года
Василий Гиричев
0 / / 06.04.2013
+3 / -0
Мне нравитсяМне не нравится
6 апреля 2013, 21:47:45
Ничего так статья. Понравилась ))

Но можно я расскажу о простом и многофункциональном кросспостинге из Google Plus, если вы не против. В тему поста, так сказать.
Ссылка на сервис: http://it-brainbox.kz/gplus/

Сервис справляется с функционалом описанным
тут: http://goo.gl/kxjRl
тут: http://goo.gl/o0YXS
и тут: http://goo.gl/GWmW2

Если кратко: Система позволяет настроить умный кросспостинг из Google+ в VK и Twitter с картинками.
А также отслеживать последние хэштег - тренды среди активных пользователей Google Plus. То есть в данном случае можно рассматривать G+ как универсальную площадку для постинга материала во все поддерживаемые сети сразу. Скоро будет написан механизм для Facebook
Скриншоты и примеры работы сервиса по ссылкам выше

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


Ссылка на сервис: http://it-brainbox.kz/gplus/
2.
86K
19 октября 2012 года
Фима Бессарабский
0 / / 19.10.2012
Мне нравитсяМне не нравится
19 октября 2012, 10:35:31
Разжевали, спасибо.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог