Tweet automatically your blog's posts with ghost's tags as hashtags



In this post I will show you how to tweet automatically your blog posts in twitter with your post tags as twitter hashtags using rss and IFTTT (If This Then That) platform.

We can simply use IFTTT (If This Then That) platform to connect our blog rss to twitter but the rss generated by ghost platform doesn't contain your post tags in a single String, tags are declared in tag category and IFTTT doesn't support advanced transformation like loop and adding # character.

My solution is to build another rss which contains in the description element a string containing the post's tags with # in the beginning, rather than all post's content in the description element.

The ghost rss is available at amgohan.agileasoft.com/rss, my new rss will be available in amgohan.agileasoft.com/social.

In the following I describe step by step how to do this :

  • Add a new controller social like rss in core/server/controllers/frontend.js with this implementation :

    social: function (req, res, next) {
    function isPaginated() {
        return req.route.path.indexOf(':page') !== -1;
    }
    function isTag() {
        return req.route.path.indexOf('/tag/') !== -1;
    }
    function isAuthor() {
        return req.route.path.indexOf('/author/') !== -1;
    }
    // Initialize RSS
    var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1,
        slugParam = req.params.slug,
        baseUrl = config.paths.subdir;
    if (isTag()) {
        baseUrl += '/tag/' + slugParam + '/rss/';
    } else if (isAuthor()) {
        baseUrl += '/author/' + slugParam + '/rss/';
    } else {
        baseUrl += '/rss/';
    }
    // No negative pages, or page 1
    if (isNaN(pageParam) || pageParam < 1 || (pageParam === 1 && isPaginated())) {
        return res.redirect(baseUrl);
    }
    return Promise.all([
        api.settings.read('title'),
        api.settings.read('description'),
        api.settings.read('permalinks')
    ]).then(function (result) {
        var options = {};
        if (pageParam) { options.page = pageParam; }
        if (isTag()) { options.tag = slugParam; }
        if (isAuthor()) { options.author = slugParam; }
        options.include = 'author,tags,fields';
        return api.posts.browse(options).then(function (page) {
            var title = result[0].settings[0].value,
                description = result[1].settings[0].value,
                permalinks = result[2].settings[0],
                majorMinor = /^(\d+\.)?(\d+)/,
                trimmedVersion = res.locals.version,
                siteUrl = config.urlFor('home', {secure: req.secure}, true),
                feedUrl = config.urlFor('rss', {secure: req.secure}, true),
                maxPage = page.meta.pagination.pages,
                feed;
            trimmedVersion = trimmedVersion ? trimmedVersion.match(majorMinor)[0] : '?';
            if (isTag()) {
                if (page.meta.filters.tags) {
                    title = page.meta.filters.tags[0].name + ' - ' + title;
                    feedUrl = siteUrl + 'tag/' + page.meta.filters.tags[0].slug + '/rss/';
                }
            }
            if (isAuthor()) {
                if (page.meta.filters.author) {
                    title = page.meta.filters.author.name + ' - ' + title;
                    feedUrl = siteUrl + 'author/' + page.meta.filters.author.slug + '/rss/';
                }
            }
            feed = new RSS({
                title: title,
                description: description,
                generator: 'Ghost ' + trimmedVersion,
                feed_url: feedUrl,
                site_url: siteUrl,
                ttl: '60'
            });
            // If page is greater than number of pages we have, redirect to last page
            if (pageParam > maxPage) {
                return res.redirect(baseUrl + maxPage + '/');
            }
            setReqCtx(req, page.posts);
            setResponseContext(req, res);
            filters.doFilter('prePostsRender', page.posts).then(function (posts) {
                posts.forEach(function (post) {
                    var item = {
                            title: post.title,
                            guid: post.uuid,
                            url: config.urlFor('post', {post: post, permalinks: permalinks}, true),
                            date: post.published_at,
                            categories: _.pluck(post.tags, 'name'),
                            author: post.author ? post.author.name : null
                        },
                        htmlContent = cheerio.load(post.html, {decodeEntities: false});
                    // convert relative resource urls to absolute
                    // amgohan - start : here we will replace HTML content with hashtags
                    /*['href', 'src'].forEach(function (attributeName) {
                        htmlContent('[' + attributeName + ']').each(function (ix, el) {
                            el = htmlContent(el);
                            var attributeValue = el.attr(attributeName);
                            attributeValue = url.resolve(siteUrl, attributeValue);
                            el.attr(attributeName, attributeValue);
                        });
                    });*/
                    var hashtags = _.reduce(item.categories, function(hashtags, tag) { console.log(hashtags); return hashtags + ' #' + tag;});
                    item.description = (hashtags == null || hashtags.length == 0)? '' : '#' + hashtags.toLowerCase();
                    // amgohan - end : here we will replace HTML content with hashtags
                    feed.item(item);
                });
            }).then(function () {
                res.set('Content-Type', 'text/xml; charset=UTF-8');
                res.send(feed.xml());
            });
        });
    }).catch(handleError(next));
    }
    

    see what I did between //amgohan - start and //amgohan - end.

  • Add a new route social just after the route rss in core/server/routes/frontend.js : router.get('/social/', frontend.social);

after restarting your nodejs server you will see something like this in yourBlog.com/social :

  • Create your recipe If Feed Then Twitter like this :

  • Example using my twitter account :

That's it.




comments powered by Disqus