bottender-compose
Version:
An utility library for bottender and higher-order handlers
714 lines (529 loc) • 12.9 kB
Markdown
# 0.14.0 / 2019-09-20
- [new] add better name to the return functions
# 0.13.0 / 2019-02-19
- [breaking] rename param to props in effects and template (#95)
`params` is deprecated. Use `props` instead.
In `effect`:
```js
effect(
// function has side effects
async context => {
await doSomeSideEffects();
return {
derivedState: {
x: 1,
},
derivedProps: {
y: 2,
},
};
},
// action
async (context, props) => {
console.log(context.state.x); // 1
console.log(props.y); // 2
}
);
```
In template: `Hi, {{ props.name }}`
# 0.12.7 / 2019-02-01
- [new] support isMemberJoined, isMemberLeft predicates (#94)
```js
B.isMemberJoined();
B.isMemberLeft();
```
# 0.12.6 / 2018-12-11
- [fix] support Chinese variable (#92)
# 0.12.5 / 2018-09-18
- [new] support facebook `sendLike`
# 0.12.4 / 2018-09-06
- [fix] pass required otherArgs to compileTemplate
# 0.12.3 / 2018-09-06
- [improve] improve warning when compiling template #82
##### Before:
```
Properties accessors in template is invalid -- expected return a string but got: object
```
##### After:
```
Properties accessors (context.session.user) in template is invalid -- expected return a non-empty string but got: object
```
# 0.12.2 / 2018-09-05
- [new] add param support for template string:
use `param` to access object values that provided as sencond argument when calling action:
```js
B.sendText('User: {{param.name}}')(context, { name: 'Super User' });
```
# 0.12.1 / 2018-09-05
- [fix] add missing export for `attachOptions`.
# 0.12.0 / 2018-09-05
- [new] add `attachOptions`:
### `attachOptions`
Attaches additional options to the action.
```js
const { attachOptions, sendText } = require('bottender-compose');
bot.onEvent(
attachOptions({ tag: 'ISSUE_RESOLUTION' }, sendText('Issue Resolved'))
);
// curry function
const attachIssueResolutionTag = attachOptions({ tag: 'ISSUE_RESOLUTION' });
bot.onEvent(attachIssueResolutionTag(sendText('Issue Resolved')));
```
# 0.11.0 / 2018-08-27
- [new] add predicates:
### `isTextMatch`
Creates a predicate function to return true when text matches.
```js
const { isTextMatch } = require('bottender-compose');
isTextMatch('abc')(context); // boolean
isTextMatch(/abc/)(context); // boolean
```
### `isPayloadMatch`
Creates a predicate function to return true when payload matches.
```js
const { isPayloadMatch } = require('bottender-compose');
isPayloadMatch('abc')(context); // boolean
isPayloadMatch(/abc/)(context); // boolean
```
### `hasStateEqual`
Creates a predicate function to return true when state matches.
```js
const { hasStateEqual } = require('bottender-compose');
hasStateEqual('x', 1)(context); // boolean
hasStateEqual('x.y.z', 1)(context); // boolean
hasStateEqual('x', { y: { z: 1 } })(context); // boolean
```
### `not`
Creates a predicate function with **not** condition.
```js
const { not, hasStateEqual } = require('bottender-compose');
const predicate = not(hasStateEqual('x', 1));
predicate(context); // boolean
```
### `and`
Creates a predicate function with **and** condition.
```js
const { and, hasStateEqual } = require('bottender-compose');
const predicate = and([
isTextMatch('abc'),
hasStateEqual('x', 1))
]);
predicate(context) // boolean
```
### `or`
Creates a predicate function with **or** condition.
```js
const { or, hasStateEqual } = require('bottender-compose');
const predicate = or([
isTextMatch('abc'),
hasStateEqual('x', 1))
]);
predicate(context) // boolean
```
### `alwaysTrue`
Creates a predicate function that always return `true`.
```js
const { alwaysTrue } = require('bottender-compose');
const predicate = alwaysTrue();
predicate(context); // true
```
### `alwaysFalse`
Creates a predicate function that always return `false`.
```js
const { alwaysFalse } = require('bottender-compose');
const predicate = alwaysFalse();
predicate(context); // false
```
#### Messenger
- `isMessage`
- `isText`
- `hasAttachment`
- `isImage`
- `isAudio`
- `isVideo`
- `isLocation`
- `isFile`
- `isFallback`
- `isSticker`
- `isLikeSticker`
- `isQuickReply`
- `isEcho`
- `isPostback`
- `isGamePlay`
- `isOptin`
- `isPayment`
- `isCheckoutUpdate`
- `isPreCheckout`
- `isRead`
- `isDelivery`
- `isPayload`
- `isPolicyEnforcement`
- `isAppRoles`
- `isStandby`
- `isPassThreadControl`
- `isTakeThreadControl`
- `isRequestThreadControl`
- `isRequestThreadControlFromPageInbox`
- `isFromCustomerChatPlugin`
- `isReferral`
- `isBrandedCamera`
#### LINE
- `isMessage`
- `isText`
- `isImage`
- `isVideo`
- `isAudio`
- `isLocation`
- `isSticker`
- `isFollow`
- `isUnfollow`
- `isJoin`
- `isLeave`
- `isPostback`
- `isPayload`
- `isBeacon`
- `isAccountLink`
#### Slack
- `isMessage`
- `isChannelsMessage`
- `isGroupsMessage`
- `isImMessage`
- `isMpimMessage`
- `isText`
- `isInteractiveMessage`
- `isAppUninstalled`
- `isChannelArchive`
- `isChannelCreated`
- `isChannelDeleted`
- `isChannelHistoryChanged`
- `isChannelRename`
- `isChannelUnarchive`
- `isDndUpdated`
- `isDndUpdated_user`
- `isEmailDomainChanged`
- `isEmojiChanged`
- `isFileChange`
- `isFileCommentAdded`
- `isFileCommentDeleted`
- `isFileCommentEdited`
- `isFileCreated`
- `isFileDeleted`
- `isFilePublic`
- `isFileShared`
- `isFileUnshared`
- `isGridMigrationFinished`
- `isGridMigrationStarted`
- `isGroupArchive`
- `isGroupClose`
- `isGroupHistoryChanged`
- `isGroupOpen`
- `isGroupRename`
- `isGroupUnarchive`
- `isImClose`
- `isImCreated`
- `isImHistoryChanged`
- `isImOpen`
- `isLinkShared`
- `isMemberJoinedChannel`
- `isMemberLeftChannel`
- `isPinAdded`
- `isPinRemoved`
- `isReactionAdded`
- `isReactionRemoved`
- `isStarAdded`
- `isStarRemoved`
- `isSubteamCreated`
- `isSubteamMembersChanged`
- `isSubteamSelfAdded`
- `isSubteamSelfRemoved`
- `isSubteamUpdated`
- `isTeamDomainChange`
- `isTeamJoin`
- `isTeamRename`
- `isTokensRevoked`
- `isUrlVerification`
- `isUserChange`
#### Telegram
- `isMessage`
- `isText`
- `isAudio`
- `isDocument`
- `isGame`
- `isPhoto`
- `isSticker`
- `isVideo`
- `isVoice`
- `isVideoNote`
- `isContact`
- `isLocation`
- `isVenue`
- `isEditedMessage`
- `isChannelPost`
- `isEditedChannelPost`
- `isInlineQuery`
- `isChosenInlineResult`
- `isCallbackQuery`
- `isPayload`
- `isShippingQuery`
- `isPreCheckoutQuery`
#### Viber
- `isMessage`
- `isText`
- `isPicture`
- `isVideo`
- `isFile`
- `isSticker`
- `isContact`
- `isURL`
- `isLocation`
- `isSubscribed`
- `isUnsubscribed`
- `isConversationStarted`
- `isDelivered`
- `isSeen`
- `isFailed`
#### Facebook
- `isFeed`
- `isStatus`
- `isStatusAdd`
- `isStatusEdited`
- `isPost`
- `isPostRemove`
- `isComment`
- `isCommentAdd`
- `isCommentEdited`
- `isCommentRemove`
- `isLike`
- `isLikeAdd`
- `isLikeRemove`
- `isReaction`
- `isReactionAdd`
- `isReactionEdit`
- `isReactionRemove`
# 0.10.3 / 2018-08-08
- [fix] fallback to empty string when template getting falsy value
# 0.10.2 / 2018-07-25
- [new] Support user accessor: `{{user.xxx}}` in template.
# 0.10.1 / 2018-05-16
- [fix] run babel compilation before publish.
# 0.10.0 / 2018-05-16
- [new] build source with babel to have real support for node >= 7.6
# 0.9.1 / 2018-05-07
- Add new logger methods:
```js
B.series([
B.log('sending hello'),
B.info('sending hello'),
B.warn('sending hello'),
B.error('sending hello'),
B.sendText('hello'),
]);
```
It supports template too.
```js
B.series([
B.log('user: {{ session.user.id }} x: {{ state.x }}'),
B.sendText('hello'),
]);
```
You can use your owner adapter for the logger:
```js
const { log, info, warn, error } = B.createLogger({
log: debug('log'),
info: debug('info'),
warn: debug('warn'),
error: debug('error'),
});
B.series([log('sending hello'), B.sendText('hello')]);
```
# 0.9.0 / 2018-05-06
- [new] `effect`:
```js
const { effect } = require('bottender-compose');
bot.onEvent(
effect(
// function has side effects
async context => {
await doSomeSideEffects();
return {
derivedState: {
x: 1,
},
derivedParam: {
y: 2,
},
};
},
// action
async (context, param) => {
console.log(context.state.x); // 1
console.log(param.y); // 2
}
)
);
```
# 0.8.4 / 2018-04-26
- [new] also overwrite name in `setDisplayName`
# 0.8.3 / 2018-04-12
- [fix] pass extra args to match value function (#58)
- [fix] pass extra args to all of context fns (#59)
# 0.8.2 / 2018-04-09
- [new] Add `setDisplayName`:
Assigns to the `displayName` property on the action.
```js
const { setDisplayName, sendText } = require('bottender-compose');
setDisplayName('sayHello', sendText('hello'));
// curry function
setDisplayName('sayHello')(sendText('hello'));
```
# 0.8.1 / 2018-04-02
- [fix] warning condition on compileTemplate method.
# 0.8.0 / 2018-04-02
- [new] Use Template in String:
You can use `context`, `session`, `event`, `state` to access values in your template string:
```js
B.sendText('Hi, {{session.user.first_name}} {{session.user.last_name}}');
B.sendText('Received: {{event.text}}');
B.sendText('State: {{state.xxx}}');
```
- [new] Support `match`:
Create a function that encapsulates value matching logic.
```js
const { match, sendText } = require('bottender-compose');
bot.onEvent(
match('a', [
['a', sendText('You got a A')],
['b', sendText('You got a B')],
['c', sendText('You got a C')],
])
);
```
It accepts function with `context` argument:
```js
bot.onEvent(
match(context => context.state.answer, [
['a', sendText('You got a A')],
['b', sendText('You got a B')],
['c', sendText('You got a C')],
])
);
// curry function
const matchAnswer = match(context => context.state.answer);
bot.onEvent(
matchAnswer([
['a', sendText('You got a A')],
['b', sendText('You got a B')],
['c', sendText('You got a C')],
])
);
```
To assign default action, use `_` as pattern:
```js
const { _, match, sendText } = require('bottender-compose');
bot.onEvent(
match('a', [
['a', sendText('You got a A')],
['b', sendText('You got a B')],
['c', sendText('You got a C')],
[_, sendText('You got something')],
])
);
```
# 0.7.0 / 2018-03-31
- [new] Curry branch, repeat and tryCatch:
```js
// curry branch
const trueConditionBranch = branch(context => true);
bot.onEvent(
trueConditionBranch(sendText('You are the lucky one.'), sendText('Too bad.'))
);
// curry repeat
const repeatFiveTimes = repeat(5);
bot.onEvent(repeatFiveTimes(sendText('This will be sent 5 times.')));
// curry tryCatch
const mayFailTryCatch = tryCatch(doSomethingMayFail());
bot.onEvent(mayFailTryCatch(sendText('Error Happened~~~~~~~~~~~!')));
```
- [new] support otherArgs:
```js
const action = (context, ...otherArgs) => {};
```
# 0.6.2 / 2018-03-22
- [new] Support new methods:
telegram:
- `editMessageText`
- `editMessageCaption`
- `editMessageReplyMarkup`
- `deleteMessage`
- `editMessageLiveLocation`
- `stopMessageLiveLocation`
- `forwardMessageFrom`
- `forwardMessageTo`
- [removed] remove useless
messenger:
- `getAssociatedLabels`
line:
- `getLinkedRichMenu`
# 0.6.1 / 2018-03-21
- [new] Support new methods:
messenger:
- `requestThreadControl`
slack:
- `postEphemeral`
telegram:
- `kickChatMember`
- `unbanChatMember`
- `restrictChatMember`
- `promoteChatMember`
- `exportChatInviteLink`
- `setChatPhoto`
- `deleteChatPhoto`
- `setChatTitle`
- `setChatDescription`
- `setChatStickerSet`
- `deleteChatStickerSet`
- `pinChatMessage`
- `unpinChatMessage`
- `leaveChat`
- `answerShippingQuery`
- `answerPreCheckoutQuery`
- `answerInlineQuery`
# 0.6.0 / 2018-03-21
- [new] Support passing function as argument to context methods:
You can pass function as argument to handle time-specified or context-specified case, for example:
```js
// Lazy execution
B.sendText(() => `Now: ${new Date()}`);
// Use user information on context
B.sendText(
context =>
`${context.session.user.first_name} ${context.session.user.last_name}, You are the lucky one.`
);
// Use event information
B.sendText(context => `Received: ${context.event.text}`);
```
# 0.5.1 / 2017-12-20
- [new] Support methods:
- `passThreadControl`
- `passThreadControlToPageInbox`
- `takeThreadControl`
- `sendMediaGroup`
- `sendInvoice`
- `sendGame`
- `setGameScore`
# 0.5.0 / 2017-12-20
- [new] Support `repeat` and `delay`.
# 0.4.0 / 2017-12-14
- [new] Support `weight` and `doNothing`.
# 0.3.1 / 2017-12-13
- [fix] Fix `random` runtime bug
# 0.3.0 / 2017-12-11
- [new] Support `platform` and `tryCatch`.
- [new] Export `typing`.
- [new] Export Viber, FB methods.
# 0.2.0 / 2017-12-07
- [new] Support `branch` and `condition`.
# 0.1.1 / 2017-11-30
- [fix] Export `series`, `parallel` api methods.
# 0.1.0 / 2017-11-30
- [new] Support `series`, `parallel`, `random`, and most of api methods.