Download the PHP package siberfx/linkedin-autopost without Composer
On this page you can find all versions of the php package siberfx/linkedin-autopost. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download siberfx/linkedin-autopost
More information about siberfx/linkedin-autopost
Files in siberfx/linkedin-autopost
Package linkedin-autopost
Short Description Connect one LinkedIn account to your Laravel app and share models to LinkedIn automatically when they go live, through the Posts API.
License MIT
Homepage https://github.com/siberfx/linkedin-autopost
Informations about the package linkedin-autopost
LinkedIn Autopost for Laravel
Connect one LinkedIn account to your Laravel app and share your models on LinkedIn — automatically when they go live, or whenever you choose. Posts go through LinkedIn's Posts API as link posts with a preview.
- One site-wide LinkedIn member account (the person who clicks Connect).
- Auto-post when a model becomes live, at most once, off until you switch it on.
- Ready-made connection card and share button (Tailwind or Bootstrap 5, Blade or Livewire), plus routes, JSON endpoints, Artisan commands and events if you prefer to build your own.
- Headless mode (
LINKEDIN_UI=false) when you want the package without any UI. - Optional Telegram, Slack and email messages on every post, failed share and expiring token, queued or sent at once.
Requires PHP 8.4+ and Laravel 12 or 13.
Contents
- Quick start
- 1. Set up the LinkedIn app
- 2. Install
- 3. Connect
- 4. Make a model shareable
- 5. Share on demand
- 6. Ready-made admin UI
- 7. Worked example: your own modules
- 8. Build your admin UI on the endpoints
- 9. Events
- 10. Commands and the 60-day token
- 11. Telegram, Slack and email notifications
- 12. Headless: no UI
- 13. Keeping the token somewhere else
- 14. LinkedIn API versions
- 15. Testing your app
- 16. Configuration reference
- 17. Troubleshooting
Quick start
The shortest path from composer require to a first post, with the Tailwind UI:
Open the settings page, click Connect LinkedIn, run php artisan queue:work, and publish an
article: it appears on LinkedIn. Each step is explained below.
1. Set up the LinkedIn app
- Create an app at https://www.linkedin.com/developers/apps.
- Products tab: add Share on LinkedIn and Sign In with LinkedIn using OpenID Connect. Both are self-serve.
- Auth tab → Authorized redirect URLs for your app: add your callback URL exactly, e.g.
https://example.com/linkedin/callback— scheme, host (with or withoutwww), path, no trailing slash. Add one per environment (https://myapp.test/linkedin/callbackfor local). - Copy the Client ID and Primary Client Secret.
"The redirect_uri does not match the registered value" on LinkedIn's page means the URL your app sent is not in that list character for character. Run
php artisan route:list --name=linkedin-autopost.callbackto see the URL, or setLINKEDIN_REDIRECT_URIto the one you registered.
2. Install
linkedin:install options:
It publishes config/linkedin-autopost.php and the two migrations, writes LINKEDIN_UI_THEME (or
LINKEDIN_UI=false) to .env when it is not there yet, and prints the redirect URI to register and
the gate to define. To publish pieces by hand:
Using UUID or ULID keys? Edit the published
create_linkedin_posts_tablemigration: replacemorphs('shareable')withuuidMorphs('shareable')/ulidMorphs('shareable')before migrating.
.env:
Required: say who may manage LinkedIn. Everything — connecting, disconnecting, seeing the
connection (including the member's email) and sharing — is guarded by the
manage-linkedin-autopost gate. The package defines it to deny everyone until your app defines
it, for example in AppServiceProvider::boot():
Any rule works — a role package, a policy-style check, a list of emails:
Your definition wins whatever the provider order. The routes sit behind
['web', 'auth', 'can:manage-linkedin-autopost']; the Livewire actions check the same gate, and the
components show the connection read-only and the share button disabled for people it refuses.
Change the middleware, the URL prefix or the page you come back to in config/linkedin-autopost.php:
Changing the prefix changes the callback URL: register the new one on your LinkedIn app.
3. Connect
Send an admin to route('linkedin-autopost.redirect'). After LinkedIn's consent screen they land on
after_connect with one of these query values:
?linkedin= |
Meaning |
|---|---|
connected |
Done. |
cancelled |
The person cancelled on LinkedIn. |
error&reason=… |
LinkedIn refused, e.g. Scope "profile" is not authorized for your application (add the OpenID Connect product). |
exchange_failed |
The code could not be exchanged; the reason is in your log. Usually a redirect URL mismatch. |
invalid_state |
The login attempt expired or was replayed. Connect again. |
missing_code |
LinkedIn came back without an authorization code. Connect again. |
not_configured |
Client id or secret missing. |
The connection card and <x-linkedin-autopost::flash /> turn these into messages for you. With your
own page, a plain link and a message are enough:
Check the connection anywhere:
connection() asks LinkedIn (token introspection and userinfo) at most once every
status_cache_ttl seconds (300 by default) and serves the cached status in between.
isConnected() only checks that a token is stored and never calls LinkedIn.
4. Make a model shareable
The two methods:
isLiveForLinkedIn()— whether the public can see the model right now. It decides when auto-post fires (the save on which it turns fromfalsetotrue) and whether a manual share is allowed. Use any rule: an enum, a boolean, dates.toLinkedInPost()— what to post.LinkPost::make($url, $title)is the link and its preview title;description()is the preview text below it;commentary()is the post text above the preview, where{title}and{url}are filled in (default:"{title}\n\n{url}").
LinkPost |
Limit | Default |
|---|---|---|
make(string $url, string $title) |
title cut to 200 characters | — |
->description(string) |
cut to 256 characters | empty |
->commentary(string $template) |
— | "{title}\n\n{url}" |
LinkPost is immutable: each method returns a copy.
More isLiveForLinkedIn() rules:
More toLinkedInPost() styles:
With LINKEDIN_AUTOPOST=true, an Article is queued for LinkedIn when it is created published
or changes from draft to published — once. Editing a published article does not post again.
Seeders and Artisan commands do not auto-post (set autopost.in_console to allow it). Auto-post
reacts to model saves through Eloquent events, so mass update() queries and saveQuietly() do not
auto-post.
Run a queue worker; the job is dispatched after the database transaction commits, is unique per
model while it waits, and retries 3 times when LinkedIn is busy or unreachable (429, 5xx, network).
A request LinkedIn refuses outright (401, 403, 422 …) or an invalid post fails at once, without
retries. With the sync queue the share runs inside the request that saved the model, so a
LinkedIn failure surfaces there — use a real queue.
URLs are normalised for you: a non-ASCII path such as /blog/çalışma is percent-encoded and an
internationalised host (şirket.com.tr) is converted to punycode when ext-intl is installed.
LinkPost::make() throws InvalidArgumentException for a relative or non-http(s) URL.
Write the commentary as plain text: characters LinkedIn reserves for mentions and hashtags
(# @ [ ] ( ) _ * …) are escaped for you, so they appear exactly as written. LinkedIn does not
fetch the link's own preview; the title and description you set are what it shows.
5. Share on demand
share() throws NotConnected, NotShareable (not live), LinkedInRequestFailed (LinkedIn's
message) or InvalidArgumentException (your toLinkedInPost() built an invalid URL). A post LinkedIn
accepted without returning its id is recorded as posted with a null post_urn.
A complete controller action with every outcome handled:
LinkedInRequestFailed carries the HTTP status ($e->status, 0 for a network error),
isUnauthorized() (401) and isPermanent() (a 4xx other than 429: retrying cannot help).
Share only once, from your own code:
Read the history:
| Column | Values |
|---|---|
status |
posted, failed |
trigger |
auto (auto-post), manual (button, endpoint, share()), console (linkedin:share) |
post_urn |
e.g. urn:li:share:7212345678901234567; open it at https://www.linkedin.com/feed/update/{post_urn}/ |
error |
LinkedIn's message for a failed automatic share |
6. Ready-made admin UI
Pick the theme your admin uses (LINKEDIN_UI_THEME=tailwind or bootstrap) and drop in the components.
Building your own UI, or none at all? See headless mode.
Settings page: the connection card
Not connected, it shows Connect LinkedIn. Connected, it shows the member, when the token was
issued and until when it is valid, a status badge (amber in the last 14 days, red when expired or
revoked), Reconnect and Disconnect, plus the result of the last connect. People the
manage-linkedin-autopost gate refuses see the status only, without the buttons.
A full settings page (Bootstrap layout shown; the Tailwind one is the same with your classes):
Remember to set routes.after_connect to this page's URL so the browser returns here after LinkedIn.
Lists and edit pages: the share button
Livewire: <livewire:linkedin-autopost.share-button :model="$article" :wire:key="'li-'.$article->id" />
(listen for the linkedin-autopost-shared browser event to react).
Props: label, size (sm / md), :confirm="false" to skip the confirmation. The button reads
Share again once something was posted, shows the last date as its tooltip, and is disabled,
with the reason, while the manage-linkedin-autopost gate refuses the viewer, LinkedIn is not
connected or the model is not live. It posts to a signed URL, so it works without a morph map.
More share-button samples:
Things to know:
- Signed share URLs do not expire. They are protected by your auth middleware, the gate and CSRF.
Behind a TLS-terminating proxy or load balancer, configure
TrustProxiesso the signature (which covers the scheme and host) validates. - Guard the page as well. The Livewire actions check the
manage-linkedin-autopostgate, but they run through Livewire's own endpoint, not the package routes, so any extra middleware you add toroutes.middlewaredoes not apply to them. Put the components on pages restricted to the same people. - Show form errors with the flash component. The Blade (form-based) share button flashes its
success and failure message to the session. Put
<x-linkedin-autopost::flash />on the page, as in the example above, or the person never sees why a share failed. - Boolean props need the colon. Write
:confirm="false". A plainconfirm="false"is the string"false", which is truthy, so the confirmation would stay on. - CSS versions. The Tailwind views use Tailwind 3.4+ or v4 utilities (for example
size-*). The Bootstrap views need Bootstrap 5.3 (text-bg-*,bg-primary-subtle,text-body-secondary).
The flash message is stored in the session under linkedin-autopost.flash as
['type' => 'success'|'error', 'message' => '…'], if you prefer to render it in your own layout:
Tailwind
Tailwind only generates classes it finds. Add the package views to your sources:
Bootstrap 5.3 needs nothing extra.
Restyling, or a theme of your own
Edit resources/views/vendor/linkedin-autopost/{tailwind,bootstrap}/, or copy one folder to e.g.
daisyui/ and set LINKEDIN_UI_THEME=daisyui. A theme is three views: connection, share-button, flash.
7. Worked example: your own modules
php artisan vendor:publish --tag=linkedin-autopost-stubs copies a commented example model to
stubs/linkedin-autopost/ShareableModel.stub. Two typical modules:
Give each module a morph-map alias so the share endpoint, linkedin:share and the history use short,
stable names instead of class names:
Scheduled publishing
Auto-post reacts to saves. A model that becomes live only because time passes (a future
published_at, an opening date) is never saved at that moment, so nothing posts it. Schedule a
small job that queues what has become live and was not posted yet:
The same idea as an invokable class, when you prefer it out of routes/console.php:
The queued job is unique per model and checks again that nothing was posted, so overlapping runs cannot post twice.
React when a post goes out, e.g. to log the link:
8. Build your admin UI on the endpoints
| Method | URL | Returns |
|---|---|---|
| GET | /linkedin/redirect |
Redirect to LinkedIn's consent screen |
| GET | /linkedin/callback |
Redirect to after_connect with ?linkedin=… |
| GET | /linkedin/connection |
{"data": {connected, status, name, email, picture, author_urn, scopes, connected_at, expires_at, days_left}} |
| DELETE | /linkedin/connection |
Revokes and forgets the token; {"message", "revoked", "data"} |
| POST | /linkedin/share/{type}/{id} |
201 {"data": {post_urn, posted_at}} (post_urn is null when LinkedIn accepted the post without returning its id), 422 not connected / not live / invalid post URL, 502 LinkedIn refused, 404 unknown |
Every endpoint answers 403 to people the manage-linkedin-autopost gate refuses. Route names:
linkedin-autopost.redirect, .callback, .connection.show, .connection.destroy, .share, .share.signed.
status is active, expired, revoked or unknown (LinkedIn unreachable). The share endpoint
accepts morph-map aliases only:
Without a morph map, call LinkedIn::share() from your own controller.
Sample responses:
The routes use the web middleware, so a browser client sends the session cookie and the CSRF token.
With fetch:
With axios (Laravel's default bootstrap.js sets the CSRF header for you):
A Vue/Inertia or React admin uses the same three calls; for a token-authenticated SPA or mobile
client, see headless mode to put the routes behind auth:sanctum.
9. Events
| Event | When |
|---|---|
Connected |
After a successful connect ($event->connection). |
Disconnected |
After disconnect ($event->revoked). |
Shared |
After every successful post ($event->shareable, $event->post). |
ShareFailed |
An automatic share gave up after its last attempt ($event->shareableType, $event->shareableId, $event->exception). |
TokenExpiringSoon |
From linkedin:check-token ($event->connection, $event->daysLeft). |
All live in Siberfx\LinkedInAutopost\Events.
More listeners:
Use updateQuietly() in a Shared listener: a normal save() fires the model's events again (it
will not post twice, but there is no reason to run the check).
10. Commands and the 60-day token
| Command | Does |
|---|---|
linkedin:status |
Table of the member, author URN, status, scopes, issue and expiry dates, days left. |
linkedin:share {model} {id} |
Shares now (trigger = console). model is a morph alias or a class name. Refuses an already posted model unless --force. |
linkedin:disconnect |
Revokes and forgets the token; asks first unless --force. |
linkedin:check-token |
Fires TokenExpiringSoon when fewer than --days (default expiry_warning_days) remain or the token is expired/revoked. |
linkedin:test-notification |
Sends a test message to the enabled Telegram/Slack/email/custom channels. |
linkedin:install |
See Install. |
LinkedIn member tokens last 60 days, and self-serve apps get no refresh token — someone has to
click Connect again before it runs out. Schedule the check and listen for TokenExpiringSoon:
With notifications switched on, that daily check also sends the expiry warning to Telegram, Slack or email — no listener needed.
11. Telegram, Slack and email notifications
Get a message when a post goes out, when an automatic share gives up, and when the token is about
to expire. Everything is off by default; each switch is in the notifications section of the config:
Turn on any combination of channels; each one gets every message. Choose which events send a message:
Then check the settings:
The test command always sends at once (not queued), even while LINKEDIN_NOTIFY is off, so you can
check the settings before switching notifications on.
Setting up Telegram
- Talk to @BotFather, send
/newbot, and copy the token (123456789:AAE…) intoLINKEDIN_TELEGRAM_BOT_TOKEN. - Add the bot to the group or channel that should receive the messages (in a channel, as an admin allowed to post). For messages to yourself, open the bot and press Start.
- Find the chat id: send any message in that chat, then open
https://api.telegram.org/bot<token>/getUpdatesand readmessage.chat.id— negative for groups (-100…for supergroups and channels). A public channel can also use@channelname. - Groups with topics: put the topic's
message_thread_idinLINKEDIN_TELEGRAM_THREAD_ID.
Setting up Slack
- Create an app at https://api.slack.com/apps → From scratch, pick the workspace.
- Incoming Webhooks → switch on → Add New Webhook to Workspace → choose the channel.
- Copy the URL (
https://hooks.slack.com/services/T…/B…/…) intoLINKEDIN_SLACK_WEBHOOK_URL.
Setting up email
Email goes through your app's own mailer, so configure config/mail.php (MAIL_MAILER,
MAIL_FROM_ADDRESS, …) as for any Laravel mail; the package adds nothing of its own.
tois one address or several, comma separated (or an array in the config file). Invalid addresses are ignored; with no valid address the channel is skipped.mailerpicks a mailer fromconfig/mail.php(e.g.ses,postmark,log); unset uses the default.- The subject is the headline (
✅ Shared on LinkedIn: …); the body is a short HTML email with the lines below it and links made clickable. It needs no views, so it works in headless mode too. - In local development,
MAIL_MAILER=logwrites the email tostorage/logs/laravel.log.
The email is the Siberfx\LinkedInAutopost\Notifications\NotificationMail mailable, so your tests can
assert it:
Need a different recipient list per environment, or your own template? Leave the mail channel off
and register your own mail channel (see A channel of your own).
What the messages look like
The headline is bold (HTML in Telegram and email, mrkdwn in Slack); titles are escaped, so <, >
and & in your content cannot break the formatting. In email the headline is also the subject.
Common setups
The event switches apply to every channel. To route events to different channels, keep only Slack
on here and send the failure email from a ShareFailed listener (section 9).
Queued or immediate
Notifications are queued by default (queued = true, LINKEDIN_NOTIFY_QUEUED):
queued = true (default) |
queued = false |
|
|---|---|---|
| How | One SendNotification job per channel |
Sent at once, one channel after the other |
| Where | Your queue worker | Inside the request, job or command that shared |
| Retries | tries times with backoff per channel |
None |
| A failure | Retried, then in failed_jobs |
Reported to your exception handler |
| Needs | A running queue worker (or QUEUE_CONNECTION=sync) |
Nothing |
Either way a failing channel never fails the share or blocks the other channels. Auto-posts already
run in a queued job, so with queued = false their notifications are sent from that job; a
manual share from the button waits for Telegram, Slack and the mail server before it answers (each
HTTP call is limited by http.timeout). On the sync queue connection the queued jobs also run at
once, and errors are reported the same way.
The token-expiry message needs the scheduled linkedin:check-token from the previous section.
Turning a switch off also drops messages that are already waiting in the queue.
A channel of your own
To add a channel (Teams, Discord, a webhook of your own…), implement
Siberfx\LinkedInAutopost\Contracts\NotificationChannel and list it; the container builds it with
its config array as $config:
Message has level (success, error, warning, info), headline, lines (a list of plain
strings) and emoji(). Throw NotificationFailed to have the job retry. Your channel gets the
master switch, per-event switches, queueing, retries and linkedin:test-notification for free.
Without the built-in channels
Prefer Laravel notifications, Mattermost, or a database log? Leave LINKEDIN_NOTIFY off and listen to
the events yourself:
12. Headless: no UI
Set LINKEDIN_UI=false (or install with php artisan linkedin:install --headless) to use the
package without any of its UI:
- no views, Blade components or Livewire components are registered, and there is no view publish tag;
- the share and disconnect endpoints always answer JSON, also to plain form posts;
- the OAuth routes, the
LinkedInfacade, auto-posting, events, commands and notifications work as before.
Connect by sending an admin to route('linkedin-autopost.redirect'); the callback returns to
routes.after_connect with ?linkedin=connected|cancelled|error|…. To drop the routes as well, set
routes.enabled to false and drive the OAuth flow yourself through LinkedIn::authorizationUrl()
and LinkedIn::completeConnection().
Three common headless setups:
a) Backend only: auto-post, nothing else
No admin screens at all; someone connects once, then models post themselves.
Connect from the browser by visiting /linkedin/redirect while logged in as someone the gate
allows, and check it from the terminal:
b) SPA or mobile app with Sanctum
Keep the package routes, but behind token auth and under your API prefix:
The OAuth redirect and callback routes need a session to keep the state value between them, so
an api-only middleware stack cannot start the connection. Either register the redirect URL of an
extra web route for connecting (option c), or keep a small web page for the one-off Connect click.
c) Your own routes and controllers
Turn the package routes off and write the few you need. The redirect URI must be set explicitly, because the package callback route no longer exists:
completeConnection() stores the token, fires Connected and returns the Connection;
disconnect() revokes the token at LinkedIn, forgets it and returns whether LinkedIn confirmed.
13. Keeping the token somewhere else
The token is stored encrypted (your APP_KEY) in linkedin_connections. Rotating APP_KEY makes it
unreadable; the package then reports not connected and you connect again. To store it elsewhere,
implement Siberfx\LinkedInAutopost\Contracts\TokenStore and set token_store in the config.
The package reads the store once per request (or queued job) and remembers the result; connect and
disconnect through the package so it stays in step.
For example, in an existing key-value settings table:
Always encrypt the token: it can post as the connected member.
The connection status is cached as plain data (never objects), so it works with Laravel 13's default
cache.serializable_classes = false.
14. LinkedIn API versions
Posts are sent with LinkedIn-Version: 202609. LinkedIn retires each version about a year after
release; when they announce a sunset, set LINKEDIN_API_VERSION to a newer YYYYMM.
15. Testing your app
Your own tests never need to reach LinkedIn, Telegram or Slack. Put a connection in the token store and fake the HTTP calls:
Tests run in the console, so set autopost.in_console to true in tests that check auto-posting.
Define the manage-linkedin-autopost gate (or act as a user it allows) in tests that call the routes.
16. Configuration reference
| Key | Env | Default | |
|---|---|---|---|
client_id, client_secret |
LINKEDIN_CLIENT_ID, LINKEDIN_CLIENT_SECRET |
— | Your LinkedIn app's credentials. |
redirect_uri |
LINKEDIN_REDIRECT_URI |
the callback route | Must match a registered redirect URL exactly. |
scopes |
openid profile email w_member_social |
||
api_version |
LINKEDIN_API_VERSION |
202609 |
LinkedIn-Version header. |
visibility |
LINKEDIN_VISIBILITY |
PUBLIC |
or CONNECTIONS. |
routes.enabled |
true |
false registers no routes. |
|
routes.prefix / routes.name |
linkedin / linkedin-autopost. |
||
routes.middleware |
web, auth, can:manage-linkedin-autopost |
||
routes.after_connect |
/ |
Where the OAuth callback returns. | |
autopost.enabled |
LINKEDIN_AUTOPOST |
false |
|
autopost.in_console |
false |
Auto-post from seeders and commands. | |
autopost.queue_connection / autopost.queue |
null |
||
ui.enabled |
LINKEDIN_UI |
true |
false = headless. |
ui.theme |
LINKEDIN_UI_THEME |
tailwind |
bootstrap or a published folder. |
notifications.enabled |
LINKEDIN_NOTIFY |
false |
Master switch. |
notifications.events.* |
all true |
shared, failed, token_expiring. |
|
notifications.queue_connection / .queue |
null |
||
notifications.queued |
LINKEDIN_NOTIFY_QUEUED |
true |
false sends at once, without retries. |
notifications.tries / .backoff |
3 / [30, 120] |
Queued mode only. | |
notifications.channels.telegram.* |
LINKEDIN_NOTIFY_TELEGRAM, LINKEDIN_TELEGRAM_BOT_TOKEN, LINKEDIN_TELEGRAM_CHAT_ID, LINKEDIN_TELEGRAM_THREAD_ID |
off | |
notifications.channels.slack.* |
LINKEDIN_NOTIFY_SLACK, LINKEDIN_SLACK_WEBHOOK_URL |
off | |
notifications.channels.mail.* |
LINKEDIN_NOTIFY_MAIL, LINKEDIN_NOTIFY_MAIL_TO, LINKEDIN_NOTIFY_MAILER |
off | Uses config/mail.php. |
token_store |
DatabaseTokenStore |
Any TokenStore class. |
|
http.timeout |
20 |
Seconds, for LinkedIn, Telegram and Slack calls. | |
job.tries / job.backoff |
3 / [60, 300] |
The auto-post job. | |
status_cache_ttl |
300 |
Seconds the connection status is cached. | |
expiry_warning_days |
7 |
Default for linkedin:check-token. |
17. Troubleshooting
| Symptom | Cause and fix |
|---|---|
403 on every LinkedIn route |
The manage-linkedin-autopost gate is not defined, or refuses this user. Define it (section 2). |
| redirect_uri does not match on LinkedIn | Register the exact URL from php artisan route:list --name=linkedin-autopost.callback, or set LINKEDIN_REDIRECT_URI. |
?linkedin=error&reason=Scope "profile" is not authorized |
Add Sign In with LinkedIn using OpenID Connect to the app's products. |
?linkedin=invalid_state |
The session was lost between redirect and callback: same domain for both, SESSION_DOMAIN, SESSION_SECURE_COOKIE on http. |
| Publishing does not post | LINKEDIN_AUTOPOST=true? A queue worker running? Saved through Eloquent (not a mass update())? Was it already live before this save? Saved from a command or seeder (autopost.in_console)? |
Status expired / share answers 401 |
The 60-day token ran out or was revoked: connect again. Schedule linkedin:check-token. |
Status unknown |
LinkedIn could not be reached for the status check; sharing may still work. |
| Share button disabled | Its tooltip/reason says why: not connected, not live, or the gate refuses you. |
Signed share URL answers 403 behind a proxy |
Configure TrustProxies so the scheme and host match. |
| Tailwind components unstyled | Add the @source line (section 6). |
| No Telegram/Slack/email message | php artisan linkedin:test-notification shows which switch or setting is missing; check failed_jobs for SendNotification, and that a queue worker runs (or set LINKEDIN_NOTIFY_QUEUED=false). |
| Email not arriving | Test the app's mail first (MAIL_MAILER, MAIL_FROM_ADDRESS); LINKEDIN_NOTIFY_MAIL_TO must hold a valid address. |
| Telegram chat not found | The bot is not in the chat, or the chat id is wrong (groups are negative). |
Not connected after rotating APP_KEY |
The stored token can no longer be decrypted: connect again. |
Testing
License
MIT. See LICENSE.
All versions of linkedin-autopost with dependencies
guzzlehttp/guzzle Version ^7.8
illuminate/auth Version ^12.0|^13.0
illuminate/bus Version ^12.0|^13.0
illuminate/cache Version ^12.0|^13.0
illuminate/console Version ^12.0|^13.0
illuminate/contracts Version ^12.0|^13.0
illuminate/database Version ^12.0|^13.0
illuminate/encryption Version ^12.0|^13.0
illuminate/events Version ^12.0|^13.0
illuminate/filesystem Version ^12.0|^13.0
illuminate/http Version ^12.0|^13.0
illuminate/log Version ^12.0|^13.0
illuminate/mail Version ^12.0|^13.0
illuminate/queue Version ^12.0|^13.0
illuminate/routing Version ^12.0|^13.0
illuminate/session Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
illuminate/view Version ^12.0|^13.0