Post to Twitter with auto-shorten URLs (with code)

Sharing and discussing custom actions for LaunchBar
Post Reply
ctwise
Rank 1
Rank 1
Posts: 21
Joined: Tue Apr 14, 2009 3:19 pm

Post to Twitter with auto-shorten URLs (with code)

Post by ctwise » Tue Apr 14, 2009 3:24 pm

I made some minor modifications to @ptujec's script for posting to Twitter. The minor modification was auto-shortening URLs. I'm including the updated source or you can find more information on my blog at http://tedwise.com/2009/04/14/send-tweets-from-launchbar.

Code: Select all

--   This script was put together with the help of the following sources:
--   http://blog.codahale.com/2007/01/15/tweet-twitter-quicksilver/ by Coda Hale
--   http://i.grahamenglish.net/540/iquicktwitter-my-quicksilver-twitter-ichat-growl-hack/ by Graham English
--   http://www.leancrew.com/all-this/2009/02/url-shortening-scripts-fixed-i-think/ by @drdrang (fix for &ampersand issues)
--   put together and adapted by @ptujec to work with LaunchBar
--   minor changes to convert urls to tiny versions by @ctwise (http://tedwise.com)
-----------------------------------------------------------------------   
 
-- take string from LaunchBar
on handle_string(tweet)
    -- shorten urls
    set tweet to replace_http(tweet)
 
    -- do wordcount
    set wordcount to do shell script "echo " & quoted form of tweet & " | wc -c"
    set wordcount to do shell script "echo " & quoted form of wordcount & " | sed 's/^[     ]*//'"
 
    if wordcount as integer > 140 then
       -- notify when tweet contains more than 140 characters
       my growlRegister()
       growlNotify("Tweet too long", "(" & wordcount & ") characters")
       return nothing
    end if
 
    --do tweetescape
    set tweet_new to tweetescape(tweet)
 
    -- take logininformation from keychain
    tell application "Keychain Scripting"
       set twitter_key to first Internet key of current keychain whose server is "twitter.com"
       set twitter_login to quoted form of (account of twitter_key & ":" & password of twitter_key)
    end tell
 
    -- update twitter
    set twitter_status to quoted form of ("source=launchbarat&status=" & tweet_new)
    set results to do shell script "curl --user " & twitter_login & " --data-binary " & twitter_status & " http://twitter.com/statuses/update.json"
 
    -- display dialog results
    my growlRegister()
    -- you can change "Tweet" into a diffent text e.g. "Zwitscher"
    growlNotify("Tweet", tweet)
end handle_string
 
-- fix for &ampersand issues (by @drdrang)
on tweetescape(tweet)
    set cmd to "
from urllib import quote
print quote(\"\"\"" & tweet & "\"\"\", \"/:\")
"
    return (do shell script "python -c " & (quoted form of cmd))
end tweetescape
 
-- additional scripting for Growlnotification
using terms from application "GrowlHelperApp"
    on growlRegister()
       tell application "GrowlHelperApp"
          register as application "Tweet" all notifications {"Alert"} default notifications {"Alert"} icon of application "Launchbar.app"
       end tell
    end growlRegister
    on growlNotify(grrTitle, grrDescription)
       tell application "GrowlHelperApp"
          notify with name "Alert" title grrTitle description grrDescription application name "Tweet"
       end tell
    end growlNotify
end using terms from
 
-- This uses the built in splitting in AppleScript.
-- Most of the code just restores the delimiters.
on split(theText, splitText)
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to splitText
    set theTextItems to text items of theText
    set AppleScript's text item delimiters to tid
    return theTextItems
end split
 
-- I tried the opposite of the split implementation but for some
-- reason it doesn't work reliably
on join(theList, joinText)
    set result to ""
    repeat with theToken in theList
       if length of result = 0 then
          set result to theToken
       else
          set result to result & joinText & theToken
       end if
    end repeat
    return result
end join
 
-- Send the url to tiny url for shortening
on shorten_url(theURL)
    set theURL to tweetescape(theURL)
    set results to do shell script "curl   http://tinyurl.com/api-create.php?url=" & theURL
    return results
end shorten_url
 
-- Find everything that looks like a URL and shorten it
-- The number 25 is the length of a tiny url, no point in
-- shortening a url if it's already below that.
on replace_http(theText)
    set tokens to split(theText, " ")
    set output to {}
    repeat with theToken in tokens
       if (theToken starts with "http://") and length of theToken > 25 then
          set the end of output to shorten_url(theToken)
       else
          set the end of output to theToken
       end if
    end repeat
    return join(output, " ")
end replace_http
 

kastorff
Rank 1
Rank 1
Posts: 37
Joined: Fri Dec 14, 2007 5:58 pm

Re: Post to Twitter with auto-shorten URLs (with code)

Post by kastorff » Tue Apr 14, 2009 8:23 pm

Anyone else get a syntax error about Splittext when you check this?

sjk
Wizard
Wizard
Posts: 315
Joined: Thu Sep 13, 2007 9:46 pm
Location: Eugene
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by sjk » Tue Apr 14, 2009 9:04 pm

Suggestion for obdev:

Rename LaunchBar Search Templates to LaunchBar Search Templates and Scripts, then encourage people to post scripts there so they're easier to find than under LaunchBar General.

ptujec
Wizard
Wizard
Posts: 321
Joined: Fri Dec 19, 2008 11:36 am
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by ptujec » Tue Apr 14, 2009 10:37 pm

If you prefer is.gd change the shortening section like this:

Code: Select all

-- Send the url to is for shortening
on shorten_url(theURL)
   set theURL to tweetescape(theURL)
   set results to do shell script "curl   http://is.gd/api.php?longurl=" & theURL
   return results
end shorten_url

Zettt
Rank 2
Rank 2
Posts: 45
Joined: Sat Mar 28, 2009 1:04 pm
Location: Stuttgart
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by Zettt » Fri Apr 24, 2009 11:10 am

Hi,

This script is exactly what i was looking for.

I made one little adjustment to it. What happens if the tweet is too long? It's lost -- if you're doing something else after executing the script.
Wouldn't it be better to copy it to the clipboard instead so it doen't get lost?!

This script now checks if there is a link on clipboard so you don't have to copy the link into your tweet in order to tweet a link and shorten and all that. Just enter "y" at the end of your tweet and hit return.

Code: Select all

--   This script was put together with the help of the following sources:
--   http://blog.codahale.com/2007/01/15/tweet-twitter-quicksilver/ by Coda Hale
--   http://i.grahamenglish.net/540/iquicktwitter-my-quicksilver-twitter-ichat-growl-hack/ by Graham English
--   http://www.leancrew.com/all-this/2009/02/url-shortening-scripts-fixed-i-think/ by @drdrang (fix for &ampersand issues)
--   put together and adapted by @ptujec to work with LaunchBar
--   minor changes to convert urls to tiny versions by @ctwise (http://tedwise.com)
--   Some additions by @zettt (http://www.zettt.de):
--       1. Copy the tweet to the clipboard if the tweet exceeds 140 character count. (for extra safeness)
--      2. Shorten links to https:// sites
--      3. Now you dont have to provide a link at the end of your tweet. This script checks if there is a link on your clipboard and pastes that one at the end of your tweet. In order to work you have to provide a "y" at the end of your tweet to check clipboard. "y" stands for "yes check clipboard" or similiar. ;)
-----------------------------------------------------------------------   

-- take string from LaunchBar
on handle_string(tweet)
   
   -- if last word is a y then clipboard should be checked for a url. If not ignore clipboard
   if last word of tweet is "y" then
      set tweet to (characters 1 thru ((length of tweet) - 2) of tweet) as string
      -- check if tweet contains a link already
      if tweet does not contain "http://" and tweet does not contain "https://" then
         set tweet to check_clipboard(tweet)
      end if
   end if
   
   -- shorten urls
   set tweet to replace_http(tweet)
   
   -- count words
   if length of tweet > 140 then
      -- notify when tweet contains more than 140 characters
      my growlRegister()
      growlNotify("Tweet too long", ("(" & length of tweet as text) & ") characters")
      set the clipboard to tweet as text
      return nothing
   end if
   
   --do tweetescape
   set tweet_new to tweetescape(tweet)
   
   -- take logininformation from keychain
   tell application "Keychain Scripting"
      set twitter_key to first Internet key of current keychain whose server is "twitter.com"
      set twitter_login to quoted form of (account of twitter_key & ":" & password of twitter_key)
   end tell
   
   -- update twitter
   set twitter_status to quoted form of ("source=launchbarat&status=" & tweet_new)
   set results to do shell script "curl --user " & twitter_login & " --data-binary " & twitter_status & " http://twitter.com/statuses/update.json"
   
   -- display dialog results
   my growlRegister()
   -- you can change "Tweet" into a diffent text e.g. "Zwitscher"
   my growlNotify("Tweet", tweet)
end handle_string

-- fix for &ampersand issues (by @drdrang)
on tweetescape(tweet)
   set cmd to "
from urllib import quote
print quote(\"\"\"" & tweet & "\"\"\", \"/:\")
"
   return (do shell script "python -c " & (quoted form of cmd))
end tweetescape

-- additional scripting for Growlnotification
using terms from application "GrowlHelperApp"
   on growlRegister()
      tell application "GrowlHelperApp"
         register as application "Tweet" all notifications {"Alert"} default notifications {"Alert"} icon of application "Launchbar.app"
      end tell
   end growlRegister
   on growlNotify(grrTitle, grrDescription)
      tell application "GrowlHelperApp"
         notify with name "Alert" title grrTitle description grrDescription application name "Tweet"
      end tell
   end growlNotify
end using terms from

-- This uses the built in splitting in AppleScript.
-- Most of the code just restores the delimiters.
on split(theText, splitText)
   set tid to AppleScript's text item delimiters
   set AppleScript's text item delimiters to splitText
   set theTextItems to text items of theText
   set AppleScript's text item delimiters to tid
   return theTextItems
end split

-- I tried the opposite of the split implementation but for some
-- reason it doesn't work reliably
on join(theList, joinText)
   set result to ""
   repeat with theToken in theList
      if length of result = 0 then
         set result to theToken
      else
         set result to result & joinText & theToken
      end if
   end repeat
   return result
end join

-- Send the url to is for shortening
on shorten_url(theURL)
   set theURL to tweetescape(theURL)
   set results to do shell script "curl http://is.gd/api.php?longurl=" & theURL
   return results
end shorten_url

-- Find everything that looks like a URL and shorten it
-- The number 25 is the length of a tiny url, no point in
-- shortening a url if it's already below that.
on replace_http(theText)
   set tokens to split(theText, " ")
   set output to {}
   repeat with theToken in tokens
      if (theToken starts with "http://") and length of theToken > 25 then
         set the end of output to shorten_url(theToken)
      else
         set the end of output to theToken
      end if
   end repeat
   return join(output, " ")
end replace_http

-- Check if there is a link on the clipboard already
-- If there is a link join it to the tweet
on check_clipboard(theTweet)
   set clipboard_contents to the clipboard as text
   if clipboard_contents contains "http://" or clipboard_contents contains "https://" then
      set theTweet to theTweet & " " & clipboard_contents
   end if
   return theTweet
end check_clipboard
Last edited by Zettt on Fri Jun 26, 2009 9:19 am, edited 7 times in total.

ptujec
Wizard
Wizard
Posts: 321
Joined: Fri Dec 19, 2008 11:36 am
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by ptujec » Fri Apr 24, 2009 11:42 am

Zettt wrote:Wouldn't it be better to copy it to the clipboard instead so it doen't get lost?!

Since LB keeps the last entry for every Aktion/Skript individually it isn't really lost ... not until the next Input.

Zettt
Rank 2
Rank 2
Posts: 45
Joined: Sat Mar 28, 2009 1:04 pm
Location: Stuttgart
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by Zettt » Fri Apr 24, 2009 1:23 pm

Yes, but i think it's better to have a something even my mom can use. ;)

ptujec
Wizard
Wizard
Posts: 321
Joined: Fri Dec 19, 2008 11:36 am
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by ptujec » Fri Apr 24, 2009 2:11 pm

Go here to watch a screencast on that by @zettt
http://www.zettt.de/2009/04/mac-launchbar-tutorial-5/

tinyURL has issues with some URLs (e.g. googlemap) in combination with this script, so you may want to replace ...

Code: Select all

http://tinyurl.com/api-create.php?url=


... with (is.gd)

Code: Select all

http://is.gd/api.php?longurl=


... or (tr.im)

Code: Select all

http://api.tr.im/api/trim_simple?url=


If tinyURL works for you be happy ;)

Zettt
Rank 2
Rank 2
Posts: 45
Joined: Sat Mar 28, 2009 1:04 pm
Location: Stuttgart
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by Zettt » Sat Apr 25, 2009 12:01 pm

Added support to shoertening links starting with https://. (I edited my script above so new users don't get confued.)

Zettt
Rank 2
Rank 2
Posts: 45
Joined: Sat Mar 28, 2009 1:04 pm
Location: Stuttgart
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by Zettt » Sat Apr 25, 2009 3:15 pm

Did some more improvement. Now you don't have to provide a link at the end of the Tweet. It takes any link that is already on your clipboard and puts it at the end of your Tweet.

Zettt
Rank 2
Rank 2
Posts: 45
Joined: Sat Mar 28, 2009 1:04 pm
Location: Stuttgart
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by Zettt » Mon May 04, 2009 8:56 am

lol ;)

Updated the script. Fixed an issue where http:// links were double tweeted at the end. Sorry my bad.

kastorff
Rank 1
Rank 1
Posts: 37
Joined: Fri Dec 14, 2007 5:58 pm

Re: Post to Twitter with auto-shorten URLs (with code)

Post by kastorff » Mon May 04, 2009 6:07 pm

I still can't get the poster's script to compile. I get a syntax error "splittext is illegal as a formal parameter." referencing this code:

Code: Select all

on split(theText, splitText)
    set tid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to splitText
    set theTextItems to text items of theText
    set AppleScript's text item delimiters to tid
    return theTextItems
end split

Hard to believe I'm the only person experiencing this.

Zettt
Rank 2
Rank 2
Posts: 45
Joined: Sat Mar 28, 2009 1:04 pm
Location: Stuttgart
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by Zettt » Fri Jun 26, 2009 9:22 am

Updated version:
- Clipboard doesn't get automatically checked anymore. You have to enter a "y" at the end of your tweet to auto insert a link at the end of your tweet. (The last two characters get removed! " y")

ptujec
Wizard
Wizard
Posts: 321
Joined: Fri Dec 19, 2008 11:36 am
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by ptujec » Fri Jun 26, 2009 9:58 am

Zettt wrote:Updated version:
- Clipboard doesn't get automatically checked anymore. You have to enter a "y" at the end of your tweet to auto insert a link at the end of your tweet. (The last two characters get removed! " y")


Good idea!
Prefer to use two seperate scripts for shortening and tweeting though. (Just to get the short Url: http://is.gd/1e0uL. To get both the title & a short Url: http://is.gd/1e0ak. The latter will return the string to LaunchBar as text, so you can edit it before tweeting.)
Different people, different taste. But I like your idea. Great improvement.

ptujec
Wizard
Wizard
Posts: 321
Joined: Fri Dec 19, 2008 11:36 am
Contact:

Re: Post to Twitter with auto-shorten URLs (with code)

Post by ptujec » Mon Nov 02, 2009 5:33 pm

Yet another version ☺
It automatically adds the url of Safaris frontmost window to your tweet (shortend with bit.ly). No copy&paste needed but also no option to tweet without URL. For this purpose I prefer this simpler version.

Code: Select all

--   This script was put together with the help of the following sources:
--   http://blog.codahale.com/2007/01/15/tweet-twitter-quicksilver/ by Coda Hale
--   http://i.grahamenglish.net/540/iquicktwitter-my-quicksilver-twitter-ichat-growl-hack/ by Graham English
--   http://www.leancrew.com/all-this/2009/02/url-shortening-scripts-fixed-i-think/ by @drdrang (fix for &ampersand issues)
--   put together and adapted by @ptujec to work with LaunchBar
--   minor changes to convert urls to tiny versions by @ctwise (http://tedwise.com)
--   Some additions by @zettt (http://www.zettt.de):
--      1. Copy the tweet to the clipboard if the tweet exceeds 140 character count. (for extra safeness)
--      2. Shorten links to https:// sites
--      3. Now you dont have to provide a link at the end of your tweet. This script checks if there is a link on your clipboard and pastes that one at the end of your tweet. In order to work you have to provide a "y" at the end of your tweet to check clipboard. "y" stands for "yes check clipboard" or similiar. ;)
--   adapted by @ptujec again 02/11/09:
--   - Now it takes the URL of frontmost window in Safari and adds it automatically shortened (via bit.ly) to your tweet
--   - "fixed" the wordcount

-----------------------------------------------------------------------   

on handle_string(tweet)
   
   -- count words
   if length of tweet > 119 then -- 21 less than 140 because of the shortURL & " "
      my growlRegister()
      growlNotify("Tweet too long", ("(" & (length of tweet) + 21 as text) & ") characters")
      return nothing
   end if
   
   -- add URL
   set tweet to get_url(tweet)
   
   -- shorten urls
   set tweet to replace_http(tweet)
   
   --do tweetescape
   set tweet_new to tweetescape(tweet)
   
   -- take logininformation from keychain
   tell application "Keychain Scripting"
      set twitter_key to first Internet key of current keychain whose server is "twitter.com"
      set twitter_login to quoted form of (account of twitter_key & ":" & password of twitter_key)
   end tell
   
   -- update twitter
   set twitter_status to quoted form of ("source=launchbarat&status=" & tweet_new)
   set results to do shell script "curl --user " & twitter_login & " --data-binary " & twitter_status & " http://twitter.com/statuses/update.json"
   
   -- notify via Growl
   my growlRegister()
   my growlNotify("Tweet", tweet)
end handle_string

---

-- fix for &ampersand issues (by @drdrang)
on tweetescape(tweet)
   set cmd to "\nfrom urllib import quote\nprint quote(\"\"\"" & tweet & "\"\"\", \"/:\")\n"
   return (do shell script "python -c " & (quoted form of cmd))
end tweetescape

-- additional scripting for Growlnotification
using terms from application "GrowlHelperApp"
   on growlRegister()
      tell application "GrowlHelperApp"
         register as application "Tweet" all notifications {"Alert"} default notifications {"Alert"} icon of application "Launchbar.app"
      end tell
   end growlRegister
   on growlNotify(grrTitle, grrDescription)
      tell application "GrowlHelperApp"
         notify with name "Alert" title grrTitle description grrDescription application name "Tweet"
      end tell
   end growlNotify
end using terms from

-- This uses the built in splitting in AppleScript.
-- Most of the code just restores the delimiters.
on split(theText, splitText)
   set tid to AppleScript's text item delimiters
   set AppleScript's text item delimiters to splitText
   set theTextItems to text items of theText
   set AppleScript's text item delimiters to tid
   return theTextItems
end split

-- I tried the opposite of the split implementation but for some
-- reason it doesn't work reliably
on join(theList, joinText)
   set result to ""
   repeat with theToken in theList
      if length of result = 0 then
         set result to theToken
      else
         set result to result & joinText & theToken
      end if
   end repeat
   return result
end join

-- Send the url to is for shortening
on shorten_url(theURL)
   set theURL to tweetescape(theURL)
   set cmd to "curl http://bit.ly/api?url=" & theURL & ""
   set results to do shell script cmd
   return results
end shorten_url

-- Find everything that looks like a URL and shorten it
-- The number 25 is the length of a tiny url, no point in
-- shortening a url if it's already below that.
on replace_http(theText)
   set tokens to split(theText, " ")
   set output to {}
   repeat with theToken in tokens
      if (theToken starts with "http://") and length of theToken > 25 then
         set the end of output to shorten_url(theToken)
      else
         set the end of output to theToken
      end if
   end repeat
   return join(output, " ")
end replace_http

-- Check if there is a link on the clipboard already
-- If there is a link join it to the tweet
on get_url(theTweet)
   tell application "Safari"
      set safari_url to URL of front document as text
   end tell
   set theTweet to theTweet & " " & safari_url
   return theTweet
end get_url

Post Reply