Twitter Platform
@sociably/twitter platform enable your app to tweet, likes and send/receive direct messages on Twitter platform.
Install
Install the core, http and twitter packages:
npm install @sociably/core @sociably/http @sociably/twitter
Setup
First you need to apply a Twitter app and set up Account Activity API. You can follow the first 2 sections in this official guide for setup procedures.
Then set up the http and twitter modules like this:
import Sociably from '@sociably/core';
import Http from '@sociably/http';
import Twitter from '@sociably/twitter';
const {
TWITTER_APP_ID,
TWITTER_APP_KEY,
TWITTER_APP_SECRET,
TWITTER_BEARER_TOKEN,
TWITTER_ACCESS_TOKEN,
TWITTER_ACCESS_SECRET,
} = process.env;
const app = Sociably.createApp({
modules: [
Http.initModule({ port: 8080 }),
],
platforms: [
Twitter.intiModule({
webhookPath: '/webhook/twitter',
appId: TWITTER_APP_ID, // id of Twitter app
appKey: TWITTER_APP_KEY, // key of Twitter app
appSecret: TWITTER_APP_SECRET, // secret of Twitter app
bearerToken: TWITTER_BEARER_TOKEN, // bearer token of Twitter app
accessToken: TWITTER_ACCESS_TOKEN, // access token of agent user
accessSecret: TWITTER_ACCESS_SECRET, // token secret of agent user
}),
],
});
Usage
Here's an example to receive messages and send replies through direct messages.
import Sociably from '@sociably/core';
import * as Twitter from '@sociably/twitter/components';
import app from './app';
app.onEvent(async ({ platform, event, reply }) => {
if (platform === 'twitter' && event.type === 'text') {
await reply(
<Twitter.Expression
quickReplies={
<Twitter.QuickReply label="More" payload="catto" />
<Twitter.QuickReply label="I want 🐶" metadata="doggo" />
}
>
<p>Hello Twitter! 👋</p>
<Twitter.Photo url="https://cataas.com/cat" />
<p>You daily 🐱</p>
</Twitter.Expression>
);
}
});
Check API references for the details of events and components.
Webview
Auth Setup
To use webviews in Twitter, configure the app with these steps:
- Add auth provider to the
webviewplatform and set app info at thebasicAuth. And make sure you have a state provider installed. Like this:
import Webview from '@sociably/webview';
import RedisState from '@machiniat/redis';
import TwitterAuth from '@sociably/twitter/webview';
const app = Sociably.createApp({
platforms: [
Webview.initModule({
authPlatforms:[
TwitterAuth
],
basicAuth: {
appName: 'My Foo App',
appIconUrl: './webview/img/logo.png'
},
// ...
}),
],
modules: [
RedisState.initModule({
clientOptions: { url: REDIS_URL },
}),
],
});
- Expose your Twitter agent user id in
next.config.js:
const { TWITTER_ACCESS_TOKEN } = process.env;
module.exports = {
publicRuntimeConfig: {
TWITTER_AGENT_ID: TWITTER_ACCESS_TOKEN.split('-', 1)[0],
},
// ...
};
- Set up the
WebviewClientin the webview:
import getConfig from 'next/config';
import WebviewClient from '@sociably/webview/client';
import TwitterAuth from '@sociably/twitter/webview/client';
const {
publicRuntimeConfig: { TWITTER_AGENT_ID },
} = getConfig();
const client = new WebviewClient({
authPlatforms: [
new TwitterAuth({ agentId: TWITTER_AGENT_ID }),
],
});
Open the Webview
The webview can be opened with a WebviewButton in the chatroom.
For example:
import * as Twitter from '@sociably/twitter/components';
import { WebviewButton as TwitterWebviewButton } from '@sociably/twitter/webview';
app.onEvent(async ({ reply }) => {
await reply(
<Twitter.DirectMessage
buttons={
<TwitterWebviewButton label="Open 📤" />
}
>
Hello Webview!
</Twitter.DirectMessage>
);
});
The user will be asked to enter a login code sent in the chat. After login, webview can communicate to the server as the authenticated user.
Check the webview platform document to learn more.
Assets Manager
TwitterAssetsManager
service helps you to manage resources on the Twitter platform,
like media, webhook, custom profile and welcome message.
To use it, you have to install a state provider first.
Then register TwitterAssetsManager like this:
import RedisState from '@machiniat/redis';
import TwitterAssetsManager, { saveUploadedMedia } from '@sociably/twitter/asssets';
const app = Sociably.createApp({
services: [
TwitterAssetsManager,
],
platforms: [
Twitter.initModule({
dispatchMiddlewares: [
saveUploadedMedia,
]
// ...
}),
],
modules: [
RedisState.initModule({
clientOptions: { url: REDIS_URL },
}),
],
});
Here's an example to upload a reusable media from an external URL:
import fs from 'fs';
import { makeContainer } from '@sociably/core';
import * as Twitter from '@sociably/twitter/components';
import TwitterAssetsManager from '@sociably/twitter/asssets';
app.onEvent(makeContainer({ deps: [TwitterAssetsManager] })(
(assetsManager) =>
async ({ reply }) => {
const fooImageId = await assetsManager.getMedia('foo.image');
if (fooImageId) {
await reply(
<Twitter.Photo mediaId={fooImageId} />
);
} else {
await reply(
<Twitter.Photo
shared
url="https://image.from.web/url.jpg"
/>
);
}
}
));
If you upload a media with shared and assetTag props,
the saveUploadedMedia middleware will save the returned media id.
You can reuse the saved id for the next time.
Resources
Here are some resources for further reading: