class Tweet {
  constructor(sparrowbot) {
    this.controller = sparrowbot.controller;
    this.client = sparrowbot.twitterClient;
  }

  run() {
    this.controller.on('interactive_message_callback', (bot, msg) => {
      switch (msg.actions[0].name) {
        case 'tweet-post':
          this.handleTweetButton(bot, msg);
          break;
        case 'tweet-cancel':
          this.handleCancelButton(bot, msg);
          break;
        default:
          // do nothing
      }
    });
  }

  handleTweetButton(bot, msg) {
    this.client.post('statuses/update', {
      status: msg.actions[0].value,
      in_reply_to_status_id: msg.callback_id,
    }, (err) => {
      const nextMsg = msg.original_message;

      if (err) {
        console.log(err);
        nextMsg.text = `Oops :persevere: ${err[0].message}`;
        nextMsg.attachments[0].actions = null;
        nextMsg.attachments[0].color = '#D0012A';
        bot.replyInteractive(msg, nextMsg);
        return;
      }

      nextMsg.text = 'Tweeted :dizzy:';
      nextMsg.attachments[0].actions = null;
      bot.replyInteractive(msg, nextMsg);
    });
  }

  handleCancelButton(bot, msg) {
    const nextMsg = msg.original_message;
    nextMsg.text = 'Cancelled :no_mouth:';
    nextMsg.attachments[0].actions = null;
    nextMsg.attachments[0].color = null;
    bot.replyInteractive(msg, nextMsg);
  }
}

module.exports = Tweet;

@@ -655,16 +655,23 @@
  %7D, (err
+, tweet
 ) =%3E %7B%0A 
@@ -1065,24 +1065,398 @@
 ons = null;%0A
+      nextMsg.attachments%5B0%5D.author_link = %60https://twitter.com/$%7Btweet.user.screen_name%7D/status/$%7Btweet.id_str%7D%60;%0A      nextMsg.attachments%5B0%5D.footer = 'Twitter';%0A      nextMsg.attachments%5B0%5D.footer_icon = 'https://a.slack-edge.com/6e067/img/services/twitter_pixel_snapped_32.png';%0A      nextMsg.attachments%5B0%5D.ts = new Date(Date.parse(tweet.created_at)).getTime() / 1000;%0A
       bot.re

Tweak attachment