What do you mean by "too long"? I've written much longer ones myself.
I don't see a whole lot that can be done with this, offhand, since there's only a single loop and test. Significant shortening can usually only be done in places where you can reliably repeat operations.
In this case I'd probably create a function or two for the code commands instead of writing each one out separately. Something like this:
# $1 = url ($i) , $2 = statuscode , $3 = code name
echo "$timevar $1 $2 $3" >> /log.txt
# $1 = url ($i) , $2 = statuscode
echo "Status $2 found" | mail -s "Check of $1 failed" email@example.com
Then use them in the case statement like this:
200) logfunction "$i" 200 "okay" ;;
400) logfunction "$i" 400 "Bad Request"
mailfunction "$i" "400" ;;
But the case statement itself is pretty much necessary as-is, since you do have to test for every possible error code*. So you don't really save a whole lot of space in the end.
The only other real suggestions I have are:
a) $(..) is recommended instead of `..`
b) You can use get_contents=$(</urls.txt)
instead of calling on the external cat command.
*Assuming you actually do need all of them. You asked this question, but only you can answer it. Do you?