Backend Development 9 min read

Automate Daily Joke SMS with Python: From API to Cron Job

This tutorial shows how to fetch a joke via a free API using Python's urllib2, split the short joke to fit a 140‑character SMS limit, send it through a QQ email to a 139 mailbox, and schedule the script with a Linux crontab entry for daily delivery.

Python Programming Learning Circle
Python Programming Learning Circle
Python Programming Learning Circle
Automate Daily Joke SMS with Python: From API to Cron Job

The article explains how to keep a girlfriend happy by automatically sending her a daily joke via SMS, using a Python script that fetches jokes from a free API, sends them through email, and schedules the task with cron.

Fetching jokes via API

It uses the 易源笑话大全 API with urllib2 to retrieve jokes in JSON format.

<code>appkey = "your_appkey"
url = 'http://apis.baidu.com/showapi_open_bus/showapi_joke/joke_text?page=1' # API address
req = urllib2.Request(url) # initialize request
req.add_header("apikey", appkey) # add header
resp = urllib2.urlopen(req) # send request
content = resp.read() # JSON string
if content:
    json_result = json.loads(content)
    content_list = json_result['showapi_res_body']['contentlist']
    first_title = content_list[0]['title'].encode('utf8')
    first_text = content_list[0]['text'].encode('utf8')
    print '标题:' + first_title
    print '内容:' + first_text
else:
    print "error"
</code>

Briefly describes urllib2 capabilities such as fetching web pages, validating HTTP servers, handling GET/POST data, exception handling, and non‑HTTP protocols like FTP.

Fetch web pages

Validate remote HTTP servers

Data requests (GET/POST)

Exception handling

Non‑HTTP protocols (FTP)

Sending the joke via email

Because the 139 mailbox forwards received emails to SMS for free, the script sends the joke via QQ's SMTP server.

<code>import smtplib, sys
from email.mime.text import MIMEText

mail_host = "smtp.qq.com"    # SMTP server
mail_user = "your_qq_email"
mail_pass = "your_qq_password"

def send_mail(to_list, sub, content):
    me = "Joke<" + mail_user + ">"
    msg = MIMEText(content, _subtype='html', _charset='utf-8')
    msg['Subject'] = sub
    msg['From'] = me
    msg['To'] = ";".join(to_list)
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user, mail_pass)
        s.sendmail(me, to_list, msg.as_string())
        s.close()
        return True
    except Exception as e:
        print str(e)
        return False
</code>

The 139 mailbox limits messages to 140 characters, so the joke is split into three parts (sender name, subject, body) to stay within the limit.

Selecting the shortest joke

<code>json_result = json.loads(content)
content_list = json_result['showapi_res_body']['contentlist']
minlen = 10000
for item in content_list:
    if len(item['text']) < minlen:
        title = item['title']
        text = item['text']
        minlen = len(item['text'])
</code>

Full script (joke.py)

<code># -*- coding: utf-8 -*-
'''
Created on 2019-10-18
@author: Kang
'''
import urllib2, json, sys, smtplib
from email.mime.text import MIMEText

reload(sys)
sys.setdefaultencoding('utf-8')

mail_host = "smtp.qq.com"
mail_user = "************"
mail_pass = "*********"
mailto_list = ['*******']

def send_mail(to_list, part1, sub, content):
    me = part1 + "<" + mail_user + ">"
    msg = MIMEText(content, _subtype='plain', _charset='utf-8')
    msg['Subject'] = sub
    msg['From'] = me
    msg['To'] = ";".join(to_list)
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user, mail_pass)
        s.sendmail(me, to_list, msg.as_string())
        s.close()
        return True
    except Exception as e:
        print str(e)
        return False

if __name__ == '__main__':
    appkey = "e2376cfbe3b27dff923ed61698839a67"
    url = 'http://apis.baidu.com/showapi_open_bus/showapi_joke/joke_text?page=1'
    req = urllib2.Request(url)
    req.add_header("apikey", appkey)
    resp = urllib2.urlopen(req)
    content = resp.read()
    if content:
        json_result = json.loads(content)
        content_list = json_result['showapi_res_body']['contentlist']
        minlen = 10000
        for item in content_list:
            if len(item['text']) < minlen:
                first_title = item['title']
                first_text = item['text']
                minlen = len(item['text'])
        print 'title:' + first_title
        print 'content:' + first_text
        length = len(first_text)
        part1 = first_text[0:10]
        part2 = first_text[10:22]
        part3 = first_text[22:length]
        if send_mail(mailto_list, part1, part2, part3):
            print "send msg succeed"
        else:
            print "send msg failed"
    else:
        print "get joke error"
</code>

Scheduling with cron

On Linux, add a crontab entry to run the script every day at 7:30 am.

<code>30 7 * * * root python /root/joke.py</code>

Finally, the article encourages readers to apply similar automation ideas, such as sending weather forecasts to elders who lack internet access.

pythonautomationAPICronsmtpliburllib2
Python Programming Learning Circle
Written by

Python Programming Learning Circle

A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.