{
  "name": "Douban To TG",
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "url": "https://www.douban.com/feed/people/pseudo-yu/interests"
      },
      "name": "RSS Feed Read",
      "type": "n8n-nodes-base.rssFeedRead",
      "typeVersion": 1,
      "position": [
        160,
        140
      ]
    },
    {
      "parameters": {
        "functionCode": "/* only return new items */\nconst staticData = getWorkflowStaticData('global');\nconst lastItemId = staticData.lastItemId;\n\nconsole.log('lastItemId', lastItemId);\nconst firstItem = items[0];\nlet newItems = [];\n\nfunction getId(item) {\n  return item.json.guid;\n}\n\nif (lastItemId) {\n  for (const item of items) {\n    if (getId(item) === lastItemId) {\n      break;\n    }\n    newItems.push(item)\n  }\n} else {\n  newItems = [firstItem]\n}\n\nstaticData.lastItemId = getId(firstItem)\nreturn newItems.reverse();"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        540,
        160
      ]
    },
    {
      "parameters": {
        "chatId": "@pseudoyulife",
        "text": "={{$json[\"tgTitle\"]}}\n\n{{$json[\"link\"]}}",
        "additionalFields": {
          "parse_mode": "HTML"
        }
      },
      "name": "Telegram",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1,
      "position": [
        720,
        20
      ],
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "interval": 30,
        "unit": "minutes"
      },
      "name": "Interval",
      "type": "n8n-nodes-base.interval",
      "typeVersion": 1,
      "position": [
        -120,
        180
      ]
    },
    {
      "parameters": {
        "functionCode": "/* filter items */\nconst newItems = [];\n\nconst SYMBOL_MOVIE = '\ud83d\udcfa'\nconst SYMBOL_BOOK = '\ud83d\udcd6'\n\nconst tagInfoMap = {\n  watched: { re: /\u770b\u8fc7/, symbol: SYMBOL_MOVIE },\n  watching: { re: /\u5728\u770b/, symbol: SYMBOL_MOVIE },\n  read: { re: /\u8bfb\u8fc7/, symbol: SYMBOL_BOOK },\n  reading: { re: /\u5728\u8bfb/, symbol: SYMBOL_BOOK },\n}\n\nfor (const item of items) {\n  const title = item.json.title\n  let tag, symbol\n\n  for (const key in tagInfoMap) {\n    const tagInfo = tagInfoMap[key]\n    if (tagInfo.re.test(title)) {\n      tag = key\n      symbol = tagInfo.symbol\n      break\n    }\n  }\n\n  if (tag) {\n    item.json.tag = tag\n    item.json.tgTitle = `${symbol} ${title} #douban #${tag}`\n    newItems.push(item)\n  }\n}\n\nreturn newItems"
      },
      "name": "Function filter",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        360,
        0
      ]
    }
  ],
  "connections": {
    "RSS Feed Read": {
      "main": [
        [
          {
            "node": "Function filter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function": {
      "main": [
        [
          {
            "node": "Telegram",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Interval": {
      "main": [
        [
          {
            "node": "RSS Feed Read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function filter": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": true,
  "settings": {
    "saveExecutionProgress": "DEFAULT",
    "errorWorkflow": "9"
  },
  "id": 4,
  "tags": []
}