Skip to main content

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:

  1. Add auth provider to the webview platform and set app info at the basicAuth. 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 },
}),
],
});
  1. 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],
},
// ...
};
  1. Set up the WebviewClient in 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: