type Linkedin = {
	token: string
	apiVersion: string
}
type Base64 = string
async function initializeImageUpload(resource: Linkedin, owner: string) {
	const endpoint = 'https://api.linkedin.com/rest/images?action=initializeUpload'
	const response = await fetch(endpoint, {
		method: 'POST',
		headers: {
			Authorization: `Bearer ${resource.token}`,
			'X-Restli-Protocol-Version': '2.0.0',
			'Content-Type': 'application/json',
			'LinkedIn-Version': `${resource.apiVersion}`
		},
		body: JSON.stringify({
			initializeUploadRequest: {
				owner
			}
		})
	})
	if (!response.ok) {
		throw new Error(`HTTP error! status: ${response.status}`)
	}
	const data = await response.json()
	return data.value
}
async function uploadImage(uploadUrl: string, image: Base64) {
	const buffer = Buffer.from(image, 'base64')
	const response = await fetch(uploadUrl, {
		method: 'PUT',
		headers: {
			'Content-Type': 'application/octet-stream'
		},
		body: buffer
	})
	if (!response.ok) {
		throw new Error(`HTTP error! status: ${response.status}`)
	}
}
async function uploadThumbnail(resource: Linkedin, owner: string, thumbnail: Base64) {
	const uploadData = await initializeImageUpload(resource, owner)
	const uploadUrl = uploadData.uploadUrl
	const imageUrn = uploadData.image
	await uploadImage(uploadUrl, thumbnail)
	return imageUrn
}
export async function main(
	resource: Linkedin,
	postData: {
		author: string
		commentary: string
		visibility: 'CONNECTIONS' | 'PUBLIC' | 'LOGGED_IN' | 'CONTAINER'
		distribution: {
			feedDistribution: 'NONE' | 'MAIN_FEED'
		}
		content?: {
			article: {
				source: string
				title: string
				description?: string
				thumbnail?: string
				thumbnailAltText?: string
			}
		}
		isReshareDisabledByAuthor: boolean
	},
	thumbnail?: Base64
) {
	if (postData.content?.article && thumbnail) {
		const thumbnailUrn = await uploadThumbnail(resource, postData.author, thumbnail)
		postData.content.article.thumbnail = thumbnailUrn
	}
	// Can use unversioned API too, but using versioned one to introduce consistency with Create_a_Simple_Post__Organization_
	const endpoint = 'https://api.linkedin.com/rest/posts'
	const response = await fetch(endpoint, {
		method: 'POST',
		headers: {
			Authorization: `Bearer ${resource.token}`,
			'X-Restli-Protocol-Version': '2.0.0',
			'LinkedIn-Version': `${resource.apiVersion}`,
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({ ...postData, lifecycleState: 'PUBLISHED' })
	})
	if (!response.ok) {
		throw new Error(`HTTP error! status: ${response.status}`)
	}
	const postId = response.headers.get('x-restli-id')
	const data = await response.json()
	return { ...data, postId }
}
 Submitted by hugo697 475 days ago
type Linkedin = {
	token: string
	apiVersion: string
}
type Base64 = string
async function initializeImageUpload(resource: Linkedin, owner: string) {
	const endpoint = 'https://api.linkedin.com/rest/images?action=initializeUpload'
	const response = await fetch(endpoint, {
		method: 'POST',
		headers: {
			Authorization: `Bearer ${resource.token}`,
			'X-Restli-Protocol-Version': '2.0.0',
			'Content-Type': 'application/json',
			'LinkedIn-Version': `${resource.apiVersion}`
		},
		body: JSON.stringify({
			initializeUploadRequest: {
				owner
			}
		})
	})
	if (!response.ok) {
		throw new Error(`HTTP error! status: ${response.status}`)
	}
	const data = await response.json()
	return data.value
}
async function uploadImage(uploadUrl: string, image: Base64) {
	const buffer = Buffer.from(image, 'base64')
	const response = await fetch(uploadUrl, {
		method: 'PUT',
		headers: {
			'Content-Type': 'application/octet-stream'
		},
		body: buffer
	})
	if (!response.ok) {
		throw new Error(`HTTP error! status: ${response.status}`)
	}
}
async function uploadThumbnail(resource: Linkedin, owner: string, thumbnail: Base64) {
	const uploadData = await initializeImageUpload(resource, owner)
	const uploadUrl = uploadData.uploadUrl
	const imageUrn = uploadData.image
	await uploadImage(uploadUrl, thumbnail)
	return imageUrn
}
export async function main(
	resource: Linkedin,
	postData: {
		author: string
		commentary: string
		visibility: 'CONNECTIONS' | 'PUBLIC' | 'LOGGED_IN' | 'CONTAINER'
		distribution: {
			feedDistribution: 'NONE' | 'MAIN_FEED'
		}
		content?: {
			article: {
				source: string
				title: string
				description?: string
				thumbnail?: string
				thumbnailAltText?: string
			}
		}
		isReshareDisabledByAuthor: boolean
	},
	thumbnail?: Base64
) {
	if (postData.content?.article && thumbnail) {
		const thumbnailUrn = await uploadThumbnail(resource, postData.author, thumbnail)
		postData.content.article.thumbnail = thumbnailUrn
	}
	// Can use unversioned API too, but using versioned one to introduce consistency with Create_a_Simple_Post__Organization_
	const endpoint = 'https://api.linkedin.com/rest/posts'
	const response = await fetch(endpoint, {
		method: 'POST',
		headers: {
			Authorization: `Bearer ${resource.token}`,
			'X-Restli-Protocol-Version': '2.0.0',
			'LinkedIn-Version': `${resource.apiVersion}`,
			'Content-Type': 'application/json'
		},
		body: JSON.stringify({ ...postData, lifecycleState: 'PUBLISHED' })
	})
	if (!response.ok) {
		throw new Error(`HTTP error! status: ${response.status}`)
	}
	const postId = response.headers.get('x-restli-id')
	const data = await response.json()
	return { ...data, postId }
}
 Submitted by hugo697 476 days ago