Using Tines to Broadcast Your Half-Baked Blog
Introduction
While writing can be rewarding, sharing your own posts on social media feels as embarrassing as it is time-consuming. So why not relegate social media manager duties to automation and let Tines and ChatGPT handle the less glamorous labor?
In this guide, I’ll walk you through setting up a hands-off system to broadcast your work to LinkedIn and X (formerly Twitter). We'll use Flask to trigger a webhook when new content goes live, ChatGPT to automatically generate post summaries, and Tines to broadcast our subpar writing to the world - All without risking any undue self-promotion.
Flask
First things first, we'll configure our app to notify Tines whenever a new post is published. Here's the snippet we've added to the content creation route to make this possible:
def notify_tines_of_post(title, content, slug, tags_str):
"""Load the Tines config and notify Tines of a new post."""
tines_webhook = os.getenv('TINES_WEBHOOK')
tines_secret = os.getenv('TINES_SECRET')
# Send the notification
try:
requests.post(
tines_webhook,
headers={"Authorization": f"Bearer {tines_secret}"},
json={"title": title, "content": content, "slug": slug, "tags": tags_str},
timeout=10
)
except requests.exceptions.RequestException:
pass # Fail silently for now
From here, Tines will take over and handle the rest - But first, we need to set up our OAuth credentials for LinkedIn and X.
The Lowdown on LinkedIn
If we want Tines to share our posts automatically on LinkedIn, we need to acquaint ourselves with their API. Here's the game plan:
Step-by-Step: LinkedIn Setup
- Create a LinkedIn Developer Account
Head over to the LinkedIn Developer page and create a new app. This gives you access to LinkedIn's API and lets you generate the credentials needed to let Tines do its thing.
-
Enable Products
-
Generate OAuth 2.0 Credentials
-
You'll need to generate a client ID and client secret - Keep these as discrete as your own username and password.
-
Your callback URI will be your Tines tenant name + `/oauth2/callback`
-
Set Your Scopes
The scopes we'll need are:
- w_member_social: This allows Tines to post on behalf of the user.
- profile and openid: To fetch the LinkedIn URN.

Retrieving Your LinkedIn URN
Once authenticated, we'll need the user's URN to post on their behalf. To get it, start by querying the /v2/userinfo endpoint. Here's what that request could look like:
curl -X GET "https://api.linkedin.com/v2/userinfo" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
With this, you'll get an object containing our sub field...
{
"sub": "abcd12345", // <- This is the field we need
"email_verified": true,
"name": "Tyler Talaga",
"locale": {
"country": "US",
"language": "en"
},
"given_name": "Tyler",
"family_name": "Talaga",
"email": "[email protected]",
"picture": "https://img.com/profile_picture.png"
}
Which we'll use to build our completed URN:
urn:li:person:{sub}
Example Request to LinkedIn's API
curl -X POST https://api.linkedin.com/v2/ugcPosts \
-H "Authorization: Bearer <<YOUR_ACCESS_TOKEN>>" \
-H "Content-Type: application/json" \
-d '{
"author": "urn:li:person:<<RESOURCE.linkedin_urn>>",
"lifecycleState": "PUBLISHED",
"specificContent": {
"com.linkedin.ugc.ShareContent": {
"shareCommentary": {
"text": "[AUTOMATED] A new article is available on Lambdas and Lapdogs!"
},
"shareMediaCategory": "ARTICLE",
"media": [
{
"status": "READY",
"description": {
"text": "<<summarize_blog_post.body.choices[0].message.content>>"
},
"originalUrl": "https://www.lambdasandlapdogs.com/blog/<<receive_new_blog_posts.body.slug>>",
"title": {
"text": "<<receive_new_blog_posts.body.title>>"
}
}
]
}
},
"visibility": {
"com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
}
}'
X's API
Now onto X. The process is similar to LinkedIn's, but certain aspects are a bit murkier. Here's how to get X's API set up:
Step-by-Step: X Setup
- Create a Developer Account on X
Swing by the X Developer Portal and create a new app. This is where we'll generate the necessary credentials and configure our Oauth settings.
-
Enable `User Authentication Settings`
-
Navigate to 'Settings', then toggle 'User authentication set up'.
- Under User authentication settings, select 'Read and write'.
-
Your callback URI will be your Tines tenant name + `/oauth2/callback`
-
Necessary Scopes
You don't have to worry about these just yet, but we'll need the following scopes when setting up our credentials in Tines:
- tweet.read, tweet.write: So Tines can read and post tweets.
- offline.access: To keep the token refreshed without constant re-authentication.

Tines
With our apps configured, it's time to set up their corresponding Oauth credentials in Tines. We'll also tackle using OpenAI's API to summarize our posts while we're here.
Configuring OAuth 2.0 in Tines
- Client ID and Client Secret: These will be the credentials we obtained in the previous section
- Scopes:
w_member_social,profile,openid - Grant Type:
Authorization Code - Authorization URL:
https://www.linkedin.com/oauth/v2/authorization - PKCE Challenge Method:
None - Token URL:
https://www.linkedin.com/oauth/v2/accessToken
X
- Client ID and Client Secret: These will be the credentials we obtained in the previous section
- Scopes:
tweet.read,tweet.write,offline.access - Grant Type:
Authorization Code - Authorization URL:
https://twitter.com/i/oauth2/authorize - PKCE Challenge Method:
SHA-256 - Token URL:
https://api.twitter.com/2/oauth2/token
OpenAI's API
Now for the fun part - automagically summarizing your writing with ChatGPT. Check out the sample request below - We're using gpt-4o-mini for this example, but feel free to experiment with other models:
curl -X POST https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer {{CREDENTIAL.openai_credential}}" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4o-mini",
"messages": [
{
"role": "system",
"content": "You are a professional content writer who specializes in creating engaging and concise summaries for social media platforms like LinkedIn."
},
{
"role": "user",
"content": "Summarize the following blog post in one engaging, conversational sentence for LinkedIn that highlights the main insight in a way that sparks interest and encourages readers to learn more: <<receive_new_blog_posts.body.content>>"
}
]
}
Complete Tines Story
Now let's put it all together in a single, cohesive Tines story (check it out here):
- Receive the Notification
This agent listens for the Flask webhook and processes the post data.
- Summarize the Post
OpenAI's GPT API works its wizardry here.
- Post on LinkedIn and X
Tines will fire off requests to both APIs, sharing your summarized post and a link to the original article.

Wrapping Up
There you have it - No more fiddling with social media logins, repeatedly pasting the same link, or figuring out your own engaging summaries. Now, every time you hit “publish,” Tines and ChatGPT handle the oversharing on your behalf, freeing you up to focus on writing (for better or worse).
For the full code and configuration details, check out the companion GitHub repository, Automated Oversharing. Inside, you’ll find everything from an example, self-contained Flask app to the complete Tines story.