Create Image Post (User)

Create an image post on LinkedIn. [See the docs here](https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/images-api?view=li-lms-2023-09&tabs=http#uploading-an-image)

Script linkedin Verified

by hugo697 ยท 7/17/2024

The script

Submitted by hugo697 Typescript (fetch-only)
Verified 689 days ago
1
type Linkedin = {
2
	token: string
3
	apiVersion: string
4
}
5

6
type Base64 = string
7

8
async function initializeImageUpload(resource: Linkedin, owner: string) {
9
	const endpoint = 'https://api.linkedin.com/rest/images?action=initializeUpload'
10
	const response = await fetch(endpoint, {
11
		method: 'POST',
12
		headers: {
13
			Authorization: `Bearer ${resource.token}`,
14
			'X-Restli-Protocol-Version': '2.0.0',
15
			'Content-Type': 'application/json',
16
			'LinkedIn-Version': `${resource.apiVersion}`
17
		},
18
		body: JSON.stringify({
19
			initializeUploadRequest: {
20
				owner
21
			}
22
		})
23
	})
24

25
	if (!response.ok) {
26
		throw new Error(`HTTP error! status: ${response.status}`)
27
	}
28

29
	const data = await response.json()
30
	return data.value
31
}
32

33
async function uploadImage(uploadUrl: string, image: Base64) {
34
	const buffer = Buffer.from(image, 'base64')
35

36
	const response = await fetch(uploadUrl, {
37
		method: 'PUT',
38
		headers: {
39
			'Content-Type': 'application/octet-stream'
40
		},
41
		body: buffer
42
	})
43

44
	if (!response.ok) {
45
		throw new Error(`HTTP error! status: ${response.status}`)
46
	}
47
}
48

49
export async function main(
50
	resource: Linkedin,
51
	postData: {
52
		author: string
53
		commentary: string
54
		visibility: 'CONNECTIONS' | 'PUBLIC' | 'LOGGED_IN' | 'CONTAINER'
55
		distribution: {
56
			feedDistribution: 'NONE' | 'MAIN_FEED'
57
		}
58
		content: {
59
			media: {
60
				id: string
61
				title?: string
62
				altText?: string
63
			}
64
		}
65
		isReshareDisabledByAuthor: boolean
66
	},
67
	image: Base64
68
) {
69
	// Step 1: Initialize image upload
70
	const uploadData = await initializeImageUpload(resource, postData.author)
71
	const uploadUrl = uploadData.uploadUrl
72
	const imageUrn = uploadData.image
73

74
	// Step 2: Upload the image
75
	await uploadImage(uploadUrl, image)
76

77
	// Step 3: Create post with image
78
	postData.content.media.id = imageUrn
79

80
	const endpoint = 'https://api.linkedin.com/rest/posts'
81

82
	const response = await fetch(endpoint, {
83
		method: 'POST',
84
		headers: {
85
			Authorization: `Bearer ${resource.token}`,
86
			'X-Restli-Protocol-Version': '2.0.0',
87
			'Content-Type': 'application/json',
88
			'LinkedIn-Version': `${resource.apiVersion}`
89
		},
90
		body: JSON.stringify({ ...postData, lifecycleState: 'PUBLISHED' })
91
	})
92

93
	if (!response.ok) {
94
		throw new Error(`HTTP error! status: ${response.status}`)
95
	}
96

97
	const postId = response.headers.get('x-restli-id')
98
	const data = await response.json()
99
	return { ...data, postId }
100
}
101