/rumors-line-bot

Line bot that checks if a message contains internet rumor.

Primary LanguageJavaScriptMIT LicenseMIT

rumors-line-bot

Line bot that checks if a message contains internet rumor.

Build Status Coverage Status

State diagram & Documents

This is a one of the sub-project of 真的假的

This state diagram describes how the LINE bot talks to users:

The state diagram

Development

Developing rumors-line-bot requires you to finish the following settings.

LINE@ account & Developer accounts

Please follow all the steps in LINE official tutorial.

Environment variables

First, install heroku toolbelt.

Create .env file from .env.sample template, at least fill in:

API_URL=https://cofacts-api.g0v.tw/graphql
LINE_CHANNEL_SECRET=<paste LINE@'s channel secret here>
LINE_CHANNEL_TOKEN=<paste LINE@'s channel token here>
LIFF_URL=<paste LIFF app's LiFF URL>

Other customizable env vars are:

  • REDIS_URL: If not given, redis://127.0.0.1:6379 is used.
  • PORT: Which port the line bot server will listen at.
  • GOOGLE_DRIVE_IMAGE_FOLDER: Google drive folder id is needed when you want to test uploading image.
  • GOOGLE_CREDENTIALS: will be populated by authGoogleDrive.js. See "Upload image/video" section below.
  • GA_ID: Google analytics universal analytics tracking ID, for tracking events
  • IMAGE_MESSAGE_ENABLED: Default disabled. To enable, please see "Process image message" section below.

Redis server

We use Redis to store conversation context / intents. Please run a Redis server on your machine, or use the Heroku Redis's REDIS_URL directly if you happen to deploy the bot to Heroku.

Node Dependencies

You will need Node.JS 8+ to proceed.

$ npm i

Get the bot server running on your local machine

$ npm run dev

and the server will be started on localhost:5001. (Or the PORT you specified in your .env file.)

Get LINE messages to your local machine

We recommend using ngrok to create a public address that directs the traffic from LINE server to your local machine. With ngrok in your path, just

$ ngrok http 5001

ngrok will give you a public URL. Use this to set the webhook URL of your Channel (See the section "Channel Console" in LINE official tutorial).

We recommend using ngrok configuration file to setup a tunnel with a fixed subdomain. In this way the public URL can be fixed (means no repeatitive copy-pasting to LINE Channel settings!) as long as the subdomain is not occupied by others.

LIFF setup

We are using LIFF to collect user's reason when submitting article & negative feedbacks.

This would require a separate HTTPS server serving liff/index.html, and some setup on LINE developer console.

Process image message(using Tesseract-OCR)

Install tesseract-ocr binary and set IMAGE_MESSAGE_ENABLED to true. If you are going to deploy linebot on heroku, you should use buildpack.

Note : Linebot will temporarily save both image and tesseract output file in tmp_image_process folder every time image message sends in. If you develop through npm run dev, you should set autorestart and watch in ecosystem.dev.config.js to false.

Upload image/video

First, follow the step1 in this url to get client_secret.json and save it to project root.

Second, run:

$ node authGoogleDrive.js

Visit the given url provided above. Get the auth code and paste it to console. Then the program will save your google drive access_token locally at GOOGLE_CREDENTIALS in .env.

Make sure you've also set GOOGLE_DRIVE_IMAGE_FOLDER = folderID in .env file.

ref:

OAuth2 Protocols

Googleapi Nodejs Client P.S. This page provide the newest api usage then this.

Translation

We use ttag to support build-time i18n for the chatbot.

Please refer to ttag documentation for annotating strings to translate.

To extract annotated strings to translation files, use:

$ npm run i18n:extract

Translation files

The translation files are located under i18n/, in Gettext PO format.

  • en_US.po: Since the language used in code is already English, this empty translation file exists to simplify settings.
  • zh_TW.po: Traditional Chinese translation.

Supporting other languages

You can replace this with any language you want to support, by leveraging Gettext msginit command.

You will need to change i18n:extract and i18n:validate script in package.json to reflect the locale change.

Building in different languages

By default, the chatbot will be built under en_US locale.

On Heroku, please set LOCALE to one of en_US, zh_TW or any other language code that exists under i18n/ directory.

If you want to build using docker instead, you may need to modify Dockerfile to include the desired LOCALE.


Production Deployment

If you would like to start your own LINE bot server in production environment, this section describes how you can deploy the line bot to your own Heroku account.

Get the server running

You can deploy the line bot server to your own Heroku account by creating a Heroku app and push to it.

Despite the fact that we don't use Procfile, Heroku still does detection and installs the correct environment for us.

Provision add-on "Heroku Redis"

Provision a Heroku Redis addon to get redis. It sets the env var REDIS_URL for you.

Tesseract-ocr on heroku

Install heroku tesseract buildpack and set var IMAGE_MESSAGE_ENABLED to true.

Configurations

You will still have to set the following config vars manually:

$ heroku config:set API_URL=https://cofacts-api.g0v.tw/graphql
$ heroku config:set SITE_URL=https://cofacts.g0v.tw
$ heroku config:set LINE_CHANNEL_SECRET=<Your channel secret>
$ heroku config:set LINE_CHANNEL_TOKEN=<Your channel token>
$ heroku config:set GOOGLE_CREDENTIALS=<Your google credential (optional)>
$ heroku config:set LIFF_URL=<LIFF URL>
$ heroku config:set IMAGE_MESSAGE_ENABLED=true

Google Analytics Events table

Sent event format: Event category / Event action / Event label

  1. User sends a message to us
  • UserInput / MessageType / <text | image | video | ...>

  • For the time being, we only process message with "text" type. The following events only applies for text messages.

  • If we found a articles in database that matches the message:

    • UserInput / ArticleSearch / ArticleFound
    • Article / Search / <article id> for each article found
  • If the message does not look like those being forwarded in instant messengers:

    • UserInput / ArticleSearch / NonsenseText
  • If nothing found in database:

    • UserInput / ArticleSearch / ArticleNotFound
  1. User chooses a found article
  • Article / Selected / <selected article id>
  • If there are replies:
    • Reply / Search / <reply id> for each replies
  • If there are no replies:
    • Article / NoReply / <selected article id>
  1. User chooses a reply
  • Reply / Selected / <selected reply id>
  • Reply / Type / <selected reply's type>
  1. User votes a reply
  • UserInput / Feedback-Vote / <articleId>/<replyId>
  1. User want to submit a new article
  • Article / Create / Yes
  1. User does not want to submit an article
  • Article / Create / No