Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env.dist
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ FAIRPOST_REQUEST_PORT=8000
# FAIRPOST_TWITTER_OA1_API_KEY_SECRET=xxx
# FAIRPOST_TWITTER_OA1_ACCESS_TOKEN=xxx
# FAIRPOST_TWITTER_OA1_ACCESS_SECRET=xxx
# FAIRPOST_TWITTER_OA1_ADDITIONAL_OWNER=xxx
# twitter auth
# FAIRPOST_TWITTER_ACCESS_TOKEN=xxx
# FAIRPOST_TWITTER_REFRESH_TOKEN=xxx
Expand Down
58 changes: 52 additions & 6 deletions docs/Facebook.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
The `facebook` platform manages a facebook **page** (not your feed)
using the plain graph api - no extensions installed.


## Setting up the Facebook platform


Expand All @@ -23,27 +24,72 @@ using the plain graph api - no extensions installed.
### Enable the platform
- Add 'facebook' to your `FAIRPOST_FEED_PLATFORMS` in `.env`


### Get a (long lived) Page Access Token for the page you want the app to manage

This token should last forever. It involves getting a user access token,
exchanging it for a long-lived user token and
then requesting the 'accounts' for your 'app scoped user id';
but this app provides a tool to help you do that:
but this app provides a tool to help you do that.

Requesting access tokens only works
- in dev mode and for users that can manage the app
- or in live mode if the app has advanced access permissions

To get advanced access permissions, the app has to go
through a review. Below, I will assume you use dev
mode when requesting the tokens. Once you have the
tokens, you can turn on Live mode and start posting.


- call `./fairpost.js setup-platform --platform=facebook`
- follow instructions from the command line
- set your app back in dev mode
- go to https://developers.facebook.com/
- select your app, edit it
- set App Mode to 'dev'
- call `./fairpost.js setup-platform --platform=facebook`
- follow instructions from the command line

### Test the platform
- call `./fairpost.js test-platform --platform=facebook`

### Make the app live
- before you use the app, set the App Mode to 'Live'
- use https://github.com/commonpike/fairpost/blob/master/public/privacy-policy.md for the privacy policy url
### Set the App to Live Mode
before you use the app, set the App Mode to 'Live'
- go to https://developers.facebook.com/
- select your app, edit it
- set App Mode to 'live'
- use https://github.com/commonpike/fairpost/blob/master/public/privacy-policy.md for the privacy policy url

### Other settings

`FAIRPOST_FACEBOOK_PUBLISH_POSTS` - if false, posts will be posted but not be published

## Manage additional pages with the same app

One fairpost `.env` can only manage one page. If you create a second `.env-foo`, you can use the same app id to manage a different page. The app is registered on your account, so if you can manage the other page, so can the app.

### Enter credentials for your other installation

- set the `FAIRPOST_FACEBOOK_APP_ID` in your .env-foo
- set the `FAIRPOST_FACEBOOK_APP_SECRET` in your .env-foo

### Enable the app on the other page

- Go to https://www.facebook.com/settings/?tab=business_tools
- edit the app and check the boxes of the other pages you want to manage.

### Get a access token for the other page

- set your app back in dev mode
- go to https://developers.facebook.com/
- select your app, edit it
- set App Mode to 'dev'
- call `./fairpost.js setup-platform --platform=facebook --config=.env-foo`
- follow instructions from the command line
- put your app back in live mode

### Test the platform for the other page
- call `./fairpost.js test-platform --platform=facebook --config=.env-foo`

# Limitations

## Images
Expand Down
64 changes: 59 additions & 5 deletions docs/Instagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ It uses the related facebook account to
upload temporary files, because the instagram
api requires files in posts to have an url.



## Setting up the Instagram platform


Expand All @@ -31,8 +33,7 @@ api requires files in posts to have an url.
### Find your instagram user id
- go to https://www.instagram.com/web/search/topsearch/?query={username}
- find your fbid_v2
- note the user id
- save this as `FAIRPOST_INSTAGRAM_USER_ID` in your .env
- save this as `FAIRPOST_INSTAGRAM_USER_ID` in your .env

### Enable the platform
- Add 'instagram' to your `FAIRPOST_FEED_PLATFORMS` in `.env`
Expand All @@ -42,14 +43,67 @@ api requires files in posts to have an url.
This token should last forever. It involves getting a user access token,
exchaning it for a long-lived user token and
then requesting the 'accounts' for your 'app scoped user id';
but this app provides a tool to help you do that:
but this app provides a tool to help you do that.

Requesting access tokens only works
- in dev mode and for users that can manage the app
- or in live mode if the app has advanced access permissions

To get advanced access permissions, the app has to go
through a review. Below, I will assume you use dev
mode when requesting the tokens. Once you have the
tokens, you can turn on Live mode and start posting.

- call `./fairpost.js setup-platform --platform=instagram`
- follow instructions from the command line

- set your app back in dev mode
- go to https://developers.facebook.com/
- select your app, edit it
- set App Mode to 'dev'
- call `./fairpost.js setup-platform --platform=instagram`
- follow instructions from the command line

### Test the platform
- call `./fairpost.js test-platform --platform=instagram`

### Set the App to Live Mode
before you use the app, set the App Mode to 'Live'
- go to https://developers.facebook.com/
- select your app, edit it
- set App Mode to 'live'
- use https://github.com/commonpike/fairpost/blob/master/public/privacy-policy.md for the privacy policy url

## Manage additional pages with the same app

One fairpost `.env` can only manage one page. If you create a second `.env-foo`, you can use the same app id to manage a different page. The app is registered on your account, so if you can manage the other page, so can the app.

### Enter credentials for your other installation

- set the `FAIRPOST_INSTAGRAM_APP_ID` in your .env-foo
- set the `FAIRPOST_INSTAGRAM_APP_SECRET` in your .env-foo

### Find your other instagram user id
- go to https://www.instagram.com/web/search/topsearch/?query={username}
- find your fbid_v2
- save this as `FAIRPOST_INSTAGRAM_USER_ID` in your .env-foo

### Enable the app on the other page
- Go to https://www.facebook.com/settings/?tab=business_tools
- edit the app and check the boxes of the other pages you want to manage.

### Get a access token for the other page

- set your app back in dev mode
- go to https://developers.facebook.com/
- select your app, edit it
- set App Mode to 'dev'
- call `./fairpost.js setup-platform --platform=instagram --config=.env-foo`
- follow instructions from the command line
- put your app back in live mode

### Test the platform for the other page
- call `./fairpost.js test-platform --platform=instagram --config=.env-foo`


# Limitations

## Images
Expand Down
21 changes: 20 additions & 1 deletion docs/LinkedIn.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ The LinkedIn platform posts to your companies feed.

### Create a new App in your linkedin account
- create an company your account can manage
- find your company id (like , 93841222)
- find your company id (in the url, like , 93841222)
- save this as `FAIRPOST_LINKEDIN_COMPANY_ID` in your .env
- create an app to manage the company page \
https://www.linkedin.com/developers/apps/new
Expand Down Expand Up @@ -38,6 +38,25 @@ The refresh token (if given) lasts for 1 year.
### Test the platform
- call `./fairpost.js test-platform --platform=linkedin`

## Manage additional pages with the same app

One fairpost `.env` can only manage one page. If you create a second `.env-foo`, you can use the same app id to manage a different page. The app is registered on your account, so if you can manage the other page, so can the app.

### Enter credentials for your other installation

- set the `FAIRPOST_LINKEDIN_CLIENT_ID` in your .env-foo
- set the `FAIRPOST_LINKEDIN_CLIENT_SECRET` in your .env-foo
- find your company id (in the url, like , 93841222)
- save this as `FAIRPOST_LINKEDIN_COMPANY_ID` in your .env-foo

### Get an OAuth2 Access Token for your other page

- call `./fairpost.js setup-platform --platform=linkedin --config=.env-foo`
- follow instructions from the command line

### Test the other installation
- call `./fairpost.js test-platform --platform=linkedin --config=.env-foo`

# Limitations

## Images
Expand Down
29 changes: 29 additions & 0 deletions docs/Twitter.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ This token should last forever (?)
- call `./fairpost.js setup-platform --platform=twitter`
- follow instructions from the command line

### Test the platform
- call `./fairpost.js test-platform --platform=twitter`

## Manage additional feeds with the same app

One fairpost `.env` can only manage one feed. If you create a second `.env-foo`, you can use the same app to manage a different feed. OAuth2 allows you to enable the app for your second account, but the OAuth1 part is tied to your first
account and requires you to specify an 'additional_owner' for the uploaded media.

### Enter credentials for your other installation

- set the `FAIRPOST_TWITTER_CLIENT_ID` in your .env-foo
- set the `FAIRPOST_TWITTER_CLIENT_SECRET` in your .env-foo
- set the `FAIRPOST_TWITTER_OA1_API_KEY` in your .env-foo
- set the `FAIRPOST_TWITTER_OA1_API_KEY_SECRET` in your .env-foo
- set the `FAIRPOST_TWITTER_OA1_ACCESS_TOKEN` in your .env-foo
- set the `FAIRPOST_TWITTER_OA1_ACCESS_SECRET` in your .env-foo

### Get an OAuth2 Access Token for your other page

- call `./fairpost.js setup-platform --platform=twitter --config=.env-foo`
- follow instructions from the command line

### Test the other installation
- call `./fairpost.js test-platform --platform=twitter --config=.env-foo`

### Set the 'additional owner'
- from the previous `test-platform` result, copy the `oauth2:id`
- set this as the `FAIRPOST_TWITTER_OA1_ADDITIONAL_OWNER` in your .env-foo

# Random documentation

https://github.com/twitterdev/twitter-api-typescript-sdk/blob/main/src/gen/Client.ts#L889
Expand Down
4 changes: 2 additions & 2 deletions src/platforms/LinkedIn/LinkedIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export default class LinkedIn extends Platform {
// https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/videos-api?view=li-lms-2023-10&tabs=http#sample-response-4
const body = {
author: this.POST_AUTHOR,
commentary: post.getCompiledBody("!title"),
commentary: post.getCompiledBody(),
visibility: this.POST_VISIBILITY,
distribution: this.POST_DISTRIBUTION,
content: {
Expand Down Expand Up @@ -282,7 +282,7 @@ export default class LinkedIn extends Platform {
// https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/videos-api?view=li-lms-2023-10&tabs=http#sample-response-4
const body = {
author: this.POST_AUTHOR,
commentary: post.getCompiledBody("!title"),
commentary: post.getCompiledBody(),
visibility: this.POST_VISIBILITY,
distribution: this.POST_DISTRIBUTION,
content: {
Expand Down
26 changes: 23 additions & 3 deletions src/platforms/Twitter/Twitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,18 @@ export default class Twitter extends Platform {
accessToken: Storage.get("settings", "TWITTER_OA1_ACCESS_TOKEN"),
accessSecret: Storage.get("settings", "TWITTER_OA1_ACCESS_SECRET"),
});
const creds1 = await client1.v1.verifyCredentials();
Logger.trace("Twitter.test: get oauth2 api");
const client2 = new TwitterApi(Storage.get("auth", "TWITTER_ACCESS_TOKEN"));
const creds2 = await client2.v2.me();
return {
oauth1: await client1.v1.verifyCredentials(),
oauth2: await client2.v2.me(),
oauth1: {
id: creds1["id"],
name: creds1["name"],
screen_name: creds1["screen_name"],
url: creds1["url"],
},
oauth2: creds2["data"],
};
}

Expand Down Expand Up @@ -177,11 +184,24 @@ export default class Twitter extends Platform {
});
const mediaIds = [];

const additionalOwner = Storage.get(
"settings",
"TWITTER_OA1_ADDITIONAL_OWNER",
);
for (const image of post.getFiles("image")) {
const path = post.getFilePath(image.name);
Logger.trace("Uploading " + path + "...");
try {
mediaIds.push(await client1.v1.uploadMedia(path));
mediaIds.push(
await client1.v1.uploadMedia(path, {
// mimeType : '' //MIME type as a string. To help you across allowed MIME types, enum EUploadMimeType is here for you. This option is required if file is not specified as string.
// target: 'tweet' //Target type tweet or dm. Defaults to tweet. You must specify it if you send a media to use in DMs.
// longVideo : false //Specify true here if you're sending a video and it can exceed 120 seconds. Otherwise, this option has no effet.
// shared: false //Specify true here if you want to use this media in Welcome Direct Messages.
additionalOwners: additionalOwner ? [additionalOwner] : [], //List of user IDs (except you) allowed to use the new media ID.
// maxConcurrentUploads: 3 //Number of concurrent chunk uploads allowed to be sent. Defaults to 3.
}),
);
} catch (e) {
throw Logger.error("Twitter.publishPost uploadMedia failed", e);
}
Expand Down