diff --git a/argoCD/base/cronjob.yaml b/argoCD/base/cronjob.yaml index 6f0fd3e..c861a98 100644 --- a/argoCD/base/cronjob.yaml +++ b/argoCD/base/cronjob.yaml @@ -3,7 +3,7 @@ kind: CronJob metadata: name: rss spec: - schedule: "* * * * *" + schedule: "*/10 * * * *" concurrencyPolicy: Forbid failedJobsHistoryLimit: 5 successfulJobsHistoryLimit: 1 diff --git a/argoCD/overlays/sub/env.yaml b/argoCD/overlays/sub/env.yaml index 6ec4659..d3e76e5 100644 --- a/argoCD/overlays/sub/env.yaml +++ b/argoCD/overlays/sub/env.yaml @@ -22,15 +22,15 @@ metadata: namespace: unibot-sub spec: encryptedData: - CONFIG_ADMIN_GUILD_ID: AgAphjNxLLZ5/xyfeiNJ/3CUNUKWZ776jvXGgf/+mGqxlia4JGIBZ/Etgk3v0JJmt1SSUjDUAPkhebmF2w9J6bQUiUoj5s9aNWs5ALaXiSPLH2lU3bfwoSpk534UYT/xcA4C5nYKkokwlBaDFXjp/z+fYqzwZUWYScYo6vBwoZpzBieo+xqdD9JE3UE10v9lJLfNZuZwBNS6V/eQ6HxIA5x1WVAKfEAWjnMcgW9AlG1IvHnBBATQsBJTZEF8ua+aN9catyiG1iIvodtlOuFmDnnwTNbxzhcec0PefO7TreAdBGu76bLDPbcGO+upJmDKR6nIOolq5p+BJhovskgn8p5O+IPfTL6UTBGspjy6kcWdWn03rYyUVbwWByTVezWxYcNpnAS6marF3KYZcJXfEPv/kRyVgRuxxsno3TjBTz7beHjYLOiGpibwFr8iqWHYBZUewS0C44iN3lSAed7ZxoqTYMTWw0gHDn1cXfQtH0wNh0A6o/ecqZvYqmwKIQ1iLggbWaUBH1YX1fGf4jNLQ8hiaMpPJfMIOWWNbbzr53FhBfK0hLf9CzR6WjUBV+yjf0xO4BRnX4rU5KdWywwrgKTL5w8YPkOlVd6SUUIFzlSYNoTlRyGoLrwoIXv4o+qs+9dtwqNeRVYMyu71B8sL9YdhFvhLgyUHRruO1gUnCYE8l0zKcXa3kqIhZ1WVS0/kNXRatLO9u+Kv88GPDNmugdBcUmd2 - CONFIG_ADMIN_ROLE_ID: AgBig5YCGVDZF1VxS8DvS5v9QxP92Xb2WdUDJ6oJHxZOo49NUxTHuzdnegeqw+2QAUuvswehU/NeggXBxQsVZ58ZBjKga6tiHsP+nytc1N84F+fGS/vVfNIw0aW+ruYGV6BTH/JMVyrK7T+yo2gO0HwCaHcFeTTsl9we2vhDpd+cPwK57OPrK8Kpr59TF6sRufu9pIVrYdjbP52J/8XKj7gL2xttJoTK8l+50u9di8K/0GPMwMcR3/5av6f2bDmFuG7CS7olNKy9KNmck6OYkRWiKG/HULiu01tuQYNMwyvwSLbSVYAxQwsH0I0TC84S6LJQ8uKu8C45sxpCMGMNYldxYaYAkDVjj9EJiUCWqWV36mr8dVt0qF+1gXkDdR0Wk2dSLHM8LiCN2AEz03RCymh6337p5Fy/CsHe8hZ9cs1YJdVREw7AaBv7xQfmjUG5vU52pS7CdfzwOxh7mCKtPv7buttOFMPKBu3vaWxhQVbqZsxExjEggUEMD15jtjpUCDZDGl5d3m71Fk9r5oSj8J1aYeqaon+MAPWN4Joyq4CKNicskSyXZWM9NIGboBvw5xfghQdaAaq6uVmWydQaKM/PmJ1jXb1lrV8Hw/cZKlRz227TLfeT2uOgLY6IE4kFFSHfs/rOuvepDTT4uL54qB34q4YeKbV5I69ihaa585gfyuHGHzoCrlmBD9WvnnQm0jyv0b/tIDc6gI38lRcuPnsWB3UI - DISCORD_TOKEN: AgBMSAHxUAqIUcQ0mkD4VF0LtJUW4Aj1m8b9JQRli5D3qv4L/UGNcPM0Afga24ViDl4P4zQLlFTk7G+lYMpjgT90XLsgJ+dT5sYnon5SPImq3+qauocPuQ4FXt4cHCSjClqyxL8EHJIjynk1XlvTkJy4er9CUTM8ucBn+Nm8AQOmCeBIYU1EFLgxsWX8XYiIkllARJ/hCqTeapNBv4Q5NHK/coNWY2VX1u+hmo0VRiC1gmEr+HGuIwGJvB/zDjYUusZomBjjlPPVT7GFEBC/JRxmPdH1hY0yl7+By+lNnWgWMNhmpfRMoCTNTT9VmTkIdCqsUPp6mADuC3oiVUAiuU1drJPQMPMmVbVgX3tqX8Yrd7heErytRruGiiA4H+q4ecGxbTrDnYr+Z51iGK3o8SqdkjkenVBTEIa04hcOxcmb15hFPS3ZzLB6MKl4+NXDTrdGHWVOJ5H8dMa3nOqLAM0uO44YeHIstvieE0GJlZ84rBUDPRX7FlBsILJWHWmER4lVAFkSrowWlNNNLvPqnOlbE+lXgS58DuQPX7q36zWzcYRZ98m0od0RRgByKYUBE9MY+W/jkjf+iUQQ2w+7J/fU3UKCTL9MYYmLafrBH1RtilYcTOTz02eh0anKIfN5pIsl24KzPacZFJp9C5l6L6D7tQCmRskNIsSMU2xM5sxqlYaOc+/m9h3kDBZBEefr1jtkEirKkMU8MTXPNNaG06EY8b3qNM/YBwuaFDfGu8+bcASRy2mjgYf4fOBJFo6+wn+YiTjsV9AlxLu74lr4wq+EGWGPqfzNnX4= - GITHUB_OAUTH_ID: AgAeZnUnnpnz2TMBRjghlw7exDGqcreob2JsmK3RUdYPwP/ZhDsWqN2X+S1LLHqIWpqDVJlE//HLMTMXKkN4cMq+Bguq0Br5MQbebs6vZH5NvLvKvZ+VOu91REAnXZ8QNpz30+9pQQA8VNazSCVRdpD+hgffEB/y9XTSiI6FWz6LMEzKHZAdlK4m7csa1ANNG2pnKNqljgyH1KmF7lPxEoYK26gCwfsZH8DKS/bXUXOicAs/nX3IZQQvm3MleJTR9Pi1w6u2hsdkjDRpvzKkmLXshrVmc+N+svMFsrCZMWSUWXePiKW6k9wYHBREEJNMtZMz31+NpWjgUaZUWRyxz2aw4aALEBDgetpREI0KdyXhzIQSm48ipraSNbkDJylPiTdTMfA9hefMPq22WtumtbKWsJTwtZFLvQht+N5WdL8dNyh+Y2p6d2yHHMnLUC94TZekrsdVLNpMcdd8PotCf2jj28w4qCogSRerB8/eN/TCztOuQ+mMdQdw4LAWYhFqOvLzFyhEqsbEoZIOI3/JymKNozaexPtabRgZVxu9BeCryK4DW2/wKpQOaGePHCCFeIMFNRgVlIlMM7D5DS1Tde1Em4GrC209NDr/flNjMEwTH+mVX4soHfDOhJd8hTtqbC53neHffvpROvJg3PoNTa5QVu3/He+x9rauYpBy89Q82AMaukEvC4pnY547Xkz9HGnUs8o/DPl871pK4PpyjQf0rQ415Q== - GITHUB_OAUTH_SECRET: AgBx7YMvTSXIbmNt5q2K3JBrHZhcbqaDCG7/2nqr9ov7yzOFhP+EoNMjwnxsHGNy49iAgwJ0vTtl/nnbDg+wMvPMnEfrZhG2a6KNDq0QScpCXHPbO24YMpyYsz7Ieb+Uzhy8EfZ1RPj1yOkF0nrpocFPgvgNq3QLCfBTnjLjf1jeemJpRXgz1rJTLKD5PORu6BGz03GswRW5c25H5QXXjf93zcgrdiQSrtf7dW8t46ME1Zg6+MVHVenSfiJO+NzWvCr4K1sq8OrpxexwYg0Lo5x5yiuiliS8A9wv4gOOM9DUeEVbIhODTBvfBejDa6tQwCKhhpfshUQNt6KdV22NPmr7N5ch9ocw+h2K4SoWRKVxCLElJ4ZHopCijP4UMXfLvE2o5QSBeX/Nvm9VYBRWZG/JKrlLXP2dNI+txXUYW3tiat9Id6R7WVKBUYxDvTgQAEPgxfe2ZlVPAXYOZaKhM8vFh8CesUGlnc7THyzVRo6Ncc7DWQ5CzkDwSnaueTuvor5B09YbQd7ikjF6DZ9K6EWzSKIpxsYIIb5GKpgDG/2SsDKHHILSf6WjuSKz0hWzm/bGkpovGhwcyGKi3PcT8MUHeCCWeCD6Mn04gjwIh00ZAtJcumpZlYhuVdfFPuzw5xkMqZackh2APhYHmLeg6KwijnmbtjV9mXPrkE7Te6leqHTUrgCHHOrbtx21LXZaZdE11ajxdG5E7UStME6OIuQGvLL6RGwr9kdHHihLqrhRWm2/RdGus6FW - PG_DSN: AgAaDGjtCM1rnh1ZmeGUR3d2HNul7ZCaboEvOMn6UGTZusmsxmRBr/bZTq9jy+BModMNJiRLjYGZyCQtoxZsOVS5nc4CWFuZ2KLmZQHahCBfCHs15WYt15AzdYMQKwerboILHxgHWiL3rxn3VP73K7rRuod2VNjb8jqAIacKtvNTg8Gj2RLErbsRfVaHE3tavw4pTZZpY8eNhKoEdvPiAiy8Y+GWbnUnZEabHxhHTHYbqHhneMbhu2BARXXG4NtQGL6A0/faR7ZaNr0yqqLNDbyZlVX/9gFIbFmEiHTtR9QSDcbNZGHbIEfzsc3OGS+m3M0Tsspw5044DfVQfxxSTtmh83Lva/XShs5eqvZizyWUoPEkpg53M+mSHgQBk9mGpQW4g2pelmc/vDCKOzyvIacsWbFdGMl8ALSMX0VY5hr5T7y1PTq0Uy3rwpO9Z+peQq4Q5V5ddxBfLC2swH51JEwSW5VR02pmrmpGJRY20BBVlrm3nTYgEPMC2oxxlgXhQiK2t/NRYxZGe8Db00DUhLx842jr2utb6Z51sKKNU81TZfgsKuuor3+KtnxoAgX4nvLb6DgWX29ErnVXX/91+3ewl/JPDdPdB9kwy5z4LqnOQKNaw9zCs+atL/B3nQXuyEUS/TD4XupNR6pd0N1mGoGyQSrvPDqMSXUjucQ9aiTF6+pvWVfuMaB8Ymyufx9HvcynqOuo+1q9psJ8boxoMyo3ehW81qNWTSzQGt/zskMjLB5jEM/mgaH91JgibekfxBb80PgO3XpFFjusmJDUNZs+SdqGGOl9i/+2CrPrYmY= - VOICEVOX_API_KEY: AgAdOUM56g21K8gkMQCoPeyYLXsQgUC9wjGv61ViILuAhILM7ubhewuGLe8j/u2oXO6UYGBJ8X0SW6TB5LsYO/0WgJNchd1WLFX8Rpx9Dzif93uPPZRFdmlAZE9zktS4Y1GLWLRkADJbuCXPktHhVnOXj3ns5ZyM0SfOwgVCIBnI4wm+c3sogQwb2b91gESaT5I89LFHyS/UptDki7+Qb5VM570iOyRxLMHF/mLgUAmMr19xONJp3QoU77mhSXPLxOdUTvL04tswJBb7dgW8Oj6dfcOsxFsP/TiDYPfVQRUx8g+Y57lrHLg6DDc2+3y/3lS4AyuA/wO2QvHMV68I8kmmzbMQGWsRSf1rvPxU0nSmW2GFIeSK3wsLsxr2GBlxe0LKIqiuKoE5ZY0jL3XjLeisVpJV0l21MQpCCva9VpFBlzaEsYY7RReTSfDoNgyf+97mgj3xxKlGZhZ5UOQo7Ccuykz3SG8L1judKq7aKUq81jl6+TVSwU41qOK2dCzvrLaKSrGCALhA0DHGDr6coTUksZnH+9xdMqDDfcv3qkhLJsdWUm8RoS7N6bDw0MnhlsroS7Fr6ae082QTX4qQEtNNDleGHIhIdQpL4Zeob4bWc7XDvVoQh1FzNnZ2pWvESDQQX0KVXhy/WWdrvK/OVONRBlHX7KonoJqFH5jUO6cey6Jbd5tyhVMKcKcVG0OFLFoBzDDZ/v3ik04H46A2 - VOICEVOX_RESTRICT_ADMIN: AgA5iGx6a0xckYizqsu41+cJ1c54TnoF8/zaaRKgWg9LmvT6xfFvp99RR4fyrxqpcl6RQ3I8eunAmjQKfhO3EFSZ/sG70pYIFHA8Fo0IVUL4iQnn99AvoTTBXtN7apugsal8byRRYWwCj9IXA9QR2fZxtVhBczdacLWpziymdSLeP73YtqPwzsDFzX9Q4uyf3R7MQ+gHP9F12zFkRHYxYC8/fr0AszvYKuLnotVBMIxdG6RgFz+sEWu4iKB0jeuoBCZ23jagd3BsvCbq6Z0j93jc2NWBBXcN874d7UqeNPwbqm72U9Qf1xA/x9ApyCPBHqtOehV4/hdzL+jIhK5ZoK4+jQpcMflNYAcS5UNOyU9BaSXoSMK8E/GuIwR9+WRIvsV56DfZeYtVQz5yCXE4M8R5z1eSqO61y3L2yCYyz1ac6XqTSpvoGBHfz2SQBLcpic/yQI1Ua08UmQ1H/S+fdDZajMtNLWKqXinxPRS30R/t4gHxs6W7uw27DsSG21tH9knCtmDR+dK3x980aFTNhKgRh3kAlySgZVy782CN0GnUZlPdLvFjy01rkQjyyCVUPiJ3lzF2Lr3IODwN8u5rAEnWriF+9ge7gUBNk2hTB4UEab3ShhmgQYY6IZtLkUR3NioGPoR7wryq4nT4nQi7nY7x0Uqjh4pHTwfsfe+dM8X/f/vSn2KaA/AwP0IWs0TyRzs2ev1S - VOICEVOX_URI: AgBvUT339YN/V4Js0lzbjpd3HTwshwrS0wDpr2yvluhJxNSQfYHyPhr6iBZbFr0TPKBw/jUWj8EldiX5yvmPOL3dTgdWDd8ZcALBYbobHebd+Pje0I6PFnHpFFbF/aHwKuxYEUsarFjTll9uOdfgL1+t8zlxRE7cT9TzQc16wPc+BGoF4l+00uoXzge9SAwZwUgrWNq5nkqzNND18QDtGZaQWNRkOvPjactv2y0jORU5za1jI+sEkqO3sUalJ574oBFwXjTPdsYOyql/PBKuI4+MmRmrOpgFmN3nD+7Ex5uUxQPM7LnUezrQ8oLlX4IObjkfaY29djkzNIRelGkn7XxPIsqqBcNzJM1Qr9aThUP6nbOOVTEecpDp8wecX2cfM9OrM0MTb47ayf24mRWbNOED0dVAskRmmE9pecKbCBWouSk2/+mRuxs3UuUl6W18dJMfmz+B3WWA/ZJjUVc57ZzOk7nF/bSK3Kf3PY9pdcqULAqMwYdtIUFiBlDiDA31+mlcmFfZQ2vPBm6xVC0AKgJhxNwfmyHvghHZ4Gry3zRUtvtFX3hHqfqn9nMfQ10JMPPTOVyROsLLmiwT1ei+jgJ29j1zTa4LsRkLypPucNzy/Bcrmxn/AOhC87n5gdZ7QffnYmM3RaDItlD91dUNcPNkeM1anK+W65k32YJVo1+g1DIVMzQfhQeVuGK39qYYXu7GGcv3c/0JWAVbZF+QVf9TrwxvzOWK2TrCpBPic9thczwL + CONFIG_ADMIN_GUILD_ID: AgCTDL8b54YL+co9nWyiCR/VKDmDR9hLg4BqQykDf0jIF8nodnBP8clor08cVxyEmHML0a/65PXcdC8C273yyVOyC5cxXY5lxXbR+NE5YwkU9Xj8N+78xMMFGTLwygshwnSfKGpi/TJSx5f2USWVy8rCAh5EnHf1wIGdhiSQLX9Yc484B8HfHniDsN7oNEuYFYF2NNU32Eo0lijU6o2IPfvUMGF0mu8qfBZ5Nh5MvcFxVklgqF+i7njPaPPr1Q0jODzxKJ++NNm0Wb9kJO1O1UwV7eMY8tUdcN2H/8XBWTm8U4CDb9TQ/3SBizsYhnQfZ0QR8QqIwjBNooZWgOhGdE2Ciu165pK3FMOuKfgY4agXsLjrbnRrE77Jdv9dtqxZaGUiR4fVi4Z39NKtxCHh2rPxGiD2LM9ga2sPh55RO98iB7gqGOzonOC/ts2M3xlFXLFD7FlN7tJBEOymdeNt4alpZyT5JbJSACTW+2NO3i9OpsJglgx7MuLYyyUQg1h2DE0XI3ZExIZ/49QNC7XHkzTsEGptpaSeC/odGGc6MX4yJN0FAg5QUaW1pApQPzXqiTmVWp1fnWBEzV5H7dx94Pppqp1ANECM3FJ2poUDtFKKMXRKnNdsJY5StwB2/g5ShwrnXSbshA472ei53tJFMuwrRjww36ys/Mh0Q20a57/AR3AvMHzx5LIRVAsfhQ24+8hg7QME369aPawM2inGmiTuj7d5 + CONFIG_ADMIN_ROLE_ID: AgAW0kfBnP8oOOda2MrxvZCb02CuJAmrpsBK1COZyUAnCyqXc5aDu31OjYuQWjiqjXluQPWA1EpEzHfQFZ5W32Bf87f8qMcrrxNiOzDDktJ9DpwyQGag8mdf8KP/CyK8mOqDFqjqt8VcQrD0E+kRys4oUO18TCjH+yv/glpSLJ0UE8NUMvl5b+rmmmWBq1qC3kc+Y8jiit7bhoneU0JSZcCO1a4dtWtNdgJqrHJ/X5ul4o8rMeeW8xpUrgX9OM+AjOPN4UzxfQcoW7S6BFroiyX7lZuMmvgh/6JVoIu5SwjYupDPryXH0tEQmpwDyZy8wTAySskcI6otU6jWaT22ZGWSX0d+I35NYFpzNH2cbuw6gNcXCnsOgMREPxliVD3OShD7YrLPYdSG7AXPV1JLFa1acYgT939i1FOr1LB407Oy+NqLGOzzmteLC14Lqm64B48v9fg75lM9RiF+ZyFgCjqgzIZsQj9yG4Ak0Jbg/vW+JQ+F5rmAfS5yWhsLWg85abVM9pB39XZup0Hq2QSuVDHDdDVEJBl1/zO7JBz9/Nb1uqqoUfcUHv9Wn/bLy3dvW8Uo//7S8xykmIuE2yHVn6FRhyeYY5rJZ7hOpyjudtcKqW6Gi/3sHSVzjrI2DIrP3pmBl76pvzf+18x+zBTg9r1BLG9qKlyeLgVdFzB/8LX+vVETG1qAE7bKOPzRvYVsrDI2bexLfzBATdZmukVXmQTC4AvW + DISCORD_TOKEN: AgBSoPyauYDxsa5vrOOcaiWhl6FiD1pLJBKjOef4leQPLS9olXUe0EfEJI+CMLBU565BqhGb7C/f0KPKrRJkdEkM6+yzANfz0xciFPmjt83ZnyF8Yl4owV6sDCQQboxTADJbWOlTEkuGMLz6DkvVyu0NBhmkJBt8j10kkjFyX43yZFWWx/kYbrzbg+XwkR5u8GdDvtmFRpC6VVg0h+x6reLqgUtDvpjJKlBG6NekfbtV5Z1EE1JT38IwCKkvbBxgrDTwqINs25WKQn3AWAaj4D7+vacx7lqKcGklTyaLjrQOcOdVDYGRgN3T88RVJGNODKLQZFtRm5Teea/qRU2qU2VB4EcS7+xmUSvYSYZpewIkYJBd9Fotyg7HdROnfexW5HSOgfe/TLNZUNjq/hMkZHTcivert8ie8zc6Q2940A/M/DI610cqQgGz4uD2NIe1zbDpucdS4neUjGtaNBw8GlLJdFdaX7VNcv5rytRkqcTLSJHIMf9E28vfaTAA7edX48Pfrt4RetcjaGchFlYoavT72y5EUILiXe/1DjMIRxf6XhNDDWceB/XtqIaKkQoO/J6IEaaYMpAiddFlDJDSc4qUn1wJsgWtYQQPrqtcC8Hc7cyWzoZUlpqzGgpMEISNHobwiwz526npkLjieat6OIuCzhRGgF70CxqtrWwJApuXXdQeprlZeih8bwmVdgqZJ40IeMRCOnAktTtQ+e8/ELce+VGEi5M0ZuMudbVo7/KqGrNzaR+ZCUHFAWM2U2MlVzdu84jCb/DdHCqR+zqL+VpMj6IzsHAmbjQ= + GITHUB_OAUTH_ID: AgBSu7+r19g/NWIP4KU8RK8rKOCGRU5otU72oCeSifu638RaFGh6mMBuzICphAjcnCXmdU6VUGnzbAA4XWN6Bucnrpz7e/xIgxePRGODyXNLd8/O1bdmnFKyssAzOMs9xzUXmo+Ulivhu6FRZpgMgQR1lw5D3/iMHqdha1R8Eau6V1YH1jQYv1z15KTONsWzqf/DMsAi3H4ZnetilW9uSuabjR9Cyp8laOlnFgaYf7qxXUDVoAwUZnEKlkMr/ujRXyPepgD5VCxL63IUfJ/sEnyZJFgrw17HyjOJ8Yi+NRBDpWsVxXKl2TIVD79bJ5UJMbvTCNGHuxg5A3SNfMUrfVNFQOyzKWxTYLkLMz0Arffc3SIp2mQQDW30c4FMZDP52xY65lbaORi3UJJnoBrTQGKD6+e3sl/kH8Ya/qsXEQE5LnBoEwoH2q/2UTM8jPmkpDzJ4FU/L1gWnpR8cKmNsjANdVtBfvUa8leguYeL1ofvPPykyOup6T9sfreL/YMSpt7pqKKA5nUhl5x76h0xofcFMeveStgKhrhPmSlSJq7xv7WHOhN7klqlp9PSipZkloFsxDGk3pjKgOa/OLFgO8UH0UuGoLYtVhwUpw0RKLDi4Ib/sKZnbZqLdTlhEFWUGMr126bMHFFS3r9zj6XXiRpCfFbxwVHYR9OK/kyz3ApkkNkM4XK7KJCabTFnUjccjoq92MxNVopdwWodkuhGYkbLunqrnA== + GITHUB_OAUTH_SECRET: AgAZ1+Y4pA16YHDHpqxCrbO1tCJqDyjrc+r7DjZblivj7aLhiiCVzvIryd+y/gOFDQReuI/vVKoSaX/QUuv9KMD27QICFQFjaJ0lBTVFipAjNxEfxjZZk+Zt31fQiPTisXwEdNA3h2aD01SxmrVUzCuEkTfUHHJT8cB4x8hVLXC9F8YE1lu79vH6TV/7kwSH+ZHlI5Vi0wuQ6fyVeU9y4FRw+U2jL9ATMn+neCHkoEtrb1aVeCmJ8xnKAbFAR/HL85Z7dPkO8EBhpgqW/oIG+vH3qzEc1iawWDZpCOtv5iWpTimB++dh8eDxxLlcShPc67T5cCgJpWTtKqjr1yqK3ao1u1ub6CsnSrdYC1Olj43PS+M8Ns6S2/uH0FxxuthRJ8N3OcYFbh0Vx+ypLpGmw+h6Gw0+NniwtM2+fn5/OyMplyVaB7cvrWK+lMgpUoVux2/Q7R79opS+SqqUiq9IlLrPh1ojzhJPxPr5F9NgB6vVs2CqyHyl/4EdwqV2YUcyC4Z6rxokxqGXfZM2RAnhVGwCGbVLfU+LUtpMiaONDv5+EljgzWmYd5kuV9c2Snjb5j/6H7lC8aYW/t0ry24IWqyB1CXDtvxrifI3AwCjpYfWg1AE5g10k2TwOp21G5K6rKGuKSTcKaGsUt59TXnRg4R6/AmUfB+kUERMdhkw32USH6ulAd2HUwVrlYIsn0SkgwOE5wrMaKPo8eBd+qapDD4eAiFrrCpWcv+/chpgS14q6gMm9HN1GQ7+ + PG_DSN: AgAKrnOwMHjGGn8zwtazzbPi9qNkCSCPzl5Dooai9hRQk0ZpdJUCGNyd2WGv0Cc18RoTEVO2n/XNrpiDxUVFMh0bcsScbOFAlFnSgI+Qya4WFo5pKZwYYYT42IVS7zRjAhyB+UIzty/kJSLVrcF94yBaQM2+8aSQYjnkgf3oFd7hTyEOMDWi+fpqDv37dPvVPpg6EfK9VSXwkTt08BsWk+jWP91CKkBOghZxwofFxM9mQU23p8gbE+IW0Z4dC2jsaB6j5J907ujcLOLMWED/wh4xaqCI9LqQms2iuV3d7IbJ1Z1fmrNO2f1u17tR0FSJo5ILy6KvKFL5LssDPAkah5zKUspldSFxsSyggbGe2xmVhSthKNPuUp+iIE4qM+nrEIxrXJfv16HUHvaDPN81mydXprutzUjXHbpHkP38fahhAVAkb41QAovuENf2U5oSyTfNbPA5NFKvvJvQI1o7To0aoH0fGLajOr4YRwU7BMLNARRAsutX9zgSRK9B+XpWWj20K5BxOHnJaWbpgvEWGcbHpYBcApYXypqQrdFxmkXNyd54oku0fpeOCCAYzI4KKhVjeqHBCXVnXmQB5eqGbawKtxC8LljkesRFHKnq0iIpWCz5Sg3wZ/hRJ7PRGXLHVfqKlMue9Mt4/rM+UszPeoBIvKhkPCltElZDguwxaY0LEyinH23bLS3/DCmJ4a65jw1uVCXHiRrWZ8to2YE5JWWfGK/9Y2QIzawSTE2DDGTlCNVl3NfO8V6OR/PuXpajv3MYD9Pa8i4AgagSi4bU1HTwzajMzXlY11cBipVGT78= + VOICEVOX_API_KEY: AgAhCsySEHIdNKe0nZA6oVB6wEptM91dqugsUpOcVN/viAOG8npHjCOEB3vYCB4l7xpgzKy0NIeFxXt9IF0EiVK5P/OYG0/1Krq7M17Aqiv6QxzKxKN0PfKTvbBeESynoLBy7UFIie0U7Bnhi+81tzYpyeu3yXMFwcdg4Tiw6GkWka56bKzCZUZV73J3xYk4ILM/R//7WazejFPV4vTqCmUhEYO0Ymt2yqhY4W8Vss4XJlWaOQD64jzhVryn/08eiWdCF5ICiALyfHnHHFQybAVRwOtNQfr3p/zPWiRVxJVKP5jOoNCXqMMuUpIg8WS+uITWc9PlGlg0lp55UFuntbw63+IHz5v/PSSRm/6J8vOBMhuXhuZtOKqgaBryaSSFRQHbnjoSeXCAtd9zI5Lvqvr2yRkmsz2QmxGTKawR/P+5HHWcSOuK7b4Df339ewSGd7IUyp3eEgpxxwV6H4pyZORAIE5Nn3txNVwkK60KFfxulpNLUvRd99UMWTgh/6t0H+v9v4YDSqbnf4pTdUtFIsXqIe82NHhZ9mGxeUTQJLp5l80SpJ77e6pfHaDLvw59Sdlltw5EFj23if6ec493SGvzHksYFk9TrOx5ycu9pNQ0f7a/iQT7jhDSFNSi2t8NH68EP+LqiHHcqtujGa6r/dkrUN8N0xPS0t5aPQQrAYa7cX+jE9jZE9Tapk40bsclSVpOZf14j7Fow/HjR3te + VOICEVOX_RESTRICT_ADMIN: AgAgqSTZ4VuEvhtguDCv45LjvbHlkkExA5MzCIImEgGlDPCO/XxZngyzbpVYwIPUd0whtNF8SUZqQPdbXWcs85JCtG+1odEcbEygSn0Wbd1Ks87Ju2xFzz3P0+UD4jyySUCkqR7CIYK6eBdegq1cn1oeI2h94h4NfLJ6cJdrhdW68Xo2nhGwf52QM0k1n/t/uvLxGAJ5qPwh19wpxkes1WlOWU/CYjaxFY9MCXMTw7EZUqYjXk+hACQjHn8l5ZJylxeNOK2PyVqYmlrj6bbPD2/1RLHSx4KRnFszrnvbj+8+it38+Avsjk5+u2lTzvXFDacsgn8l0cQN9r2S2Iw10fS/Uc5MkflWRRbyEjxOCyC1dopi2f9xC6sCRH36IGdmL34j9nAzf0EjXpc+560/yPqAj6aYlNI5zzVagzdMcaB7jqk/ZjgbIbasEydYimuqYEJlDNvNNVS5BVYqhVsry1u9EH4RwuTwAhRQtIPOjrYjIJwqW5x3vUAqG/HSqKPdGPvM7lFDgyqt6ASNEDOFrOw2G5dTpIiq+xBGfJec1UPlE4pKCkGbjmQ8Ll/g1/MfpEIijj5ANrdXvih0igG9Nr9KVG4CpCVnbA0duuSVjWuJlzPAN6HTi0o37cmcOQ4xGVNBmOGVlVqbUohPN3aTYM3eKOwq8MEWpOrv4QzKleBTvi+8ukJE8qWKmWfsKqgnAnG/Kyy5 + VOICEVOX_URI: AgAdioFSO95zRMX9f3JNBuVOHnrlcc0byFWHXPiw9NtnMA4SpX2CKC+EP1k6kwb92/cUGwoAblu13rGHySRNxqCFc8RU3VIAYbYT4hwehTGRMktmDWrMNl3WHy12T5GKpp5awi8TEhX6f2SHBaYqkRfr32bUxTC2gyt65HtfDgFV1SZkfG6CCz14Cu0JZcr6jXF9wtExpfC0f4xmOdu5tRjEoY9T/p8XUiACzpH/6J9k9LoMkeEvGIKJFxlFwsARRNF6Wr0OxNi1JMuW7likpdJ3WPWfTyUHscZO7LWjwdo4gFKBXgXaikiyP98rjGRUJSlhFzedKM4clTWSVBQbTj3OhSJNmQFudDeg3HARE0/IhUQ8LvhFHxG+VWYbhXutDtiMjdIebviU1GM3zAvNsTsNgFHQfZyiK8lcj8mSwQOf0l9HpwpMhFcFrzEx14cpevc86vf8esoMfSacoSU8W9HGHd770lYua1Yqiy5x8xX/DtwPEw4P1dJpBX+oj0VFsIpOJyZ83k/M4nLaeuppSgTFqS+koOuCyVltDsKAk+WYlLwu++M4DRd/zBveJ+cXG3yZwHlEJL4m5Yjrt4mmV0nxokZe2LSbOfH2oriqUqGtNfLDDl//ajsL0tiyYHkvZe9oG/kopmXlLGtUvCv2Q/4OIJldT2yC+cQUeQrbE9zAK9iBdql8WCHhQLOpCRFMdrTm0H1UnGUel1e8b0irHCMWBzofaOdKJ2mv35mO/buzlPH9 template: metadata: name: unibot-env diff --git a/src/cmd/rss_cron/main.go b/src/cmd/rss_cron/main.go index f803358..8266b36 100644 --- a/src/cmd/rss_cron/main.go +++ b/src/cmd/rss_cron/main.go @@ -1,11 +1,9 @@ package main import ( - "context" "encoding/base64" "fmt" "log" - "os" "slices" "sort" "unibot/internal/db" @@ -14,68 +12,25 @@ import ( "github.com/mmcdole/gofeed" - "github.com/disgoorg/disgo" - "github.com/disgoorg/disgo/bot" - "github.com/disgoorg/disgo/cache" - "github.com/disgoorg/disgo/discord" - "github.com/disgoorg/disgo/events" - "github.com/disgoorg/disgo/gateway" - "github.com/disgoorg/snowflake/v2" + "github.com/disgoorg/disgo/webhook" "gorm.io/gorm" "gorm.io/gorm/logger" ) func main() { - token := os.Getenv("DISCORD_TOKEN") - if token == "" { - log.Fatal("DISCORD_TOKEN is not set") - } - dbConnection, err := db.NewDB() if err != nil { log.Fatal(err) } dbConnection.Logger = dbConnection.Logger.LogMode(logger.Info) - client, err := disgo.New(token, - //bot.WithDefaultGateway(), - bot.WithGatewayConfigOpts( - // Intents - gateway.WithIntents( - gateway.IntentsNonPrivileged, - ), - ), - // Cache - bot.WithCacheConfigOpts( - cache.WithCaches(cache.FlagVoiceStates), - cache.WithCaches(cache.FlagChannels), - cache.WithCaches(cache.FlagMessages), - cache.WithCaches(cache.FlagRoles), - cache.WithCaches(cache.FlagMembers), - cache.WithCaches(cache.FlagGuilds), - ), - // Event Handler - bot.WithEventListenerFunc(func(e *events.Ready) { - Ready(dbConnection, e) - }), - ) - if err != nil { - log.Fatal("error while building disgo instance: ", err) - } - - defer client.Close(context.TODO()) - - // 接続開始 - if err = client.OpenGateway(context.TODO()); err != nil { - log.Fatal("error while connecting to gateway: ", err) - } - log.Println("Bot is running...") + + Ready(dbConnection) } -func Ready(db *gorm.DB, e *events.Ready) { +func Ready(db *gorm.DB) { log.Println("Bot is ready 🚀") - log.Printf("Logged in as: %v#%v", e.User.Username, e.User.Discriminator) repo := repository.NewRSSSettingRepository(db) rssSubscribeList, err := repo.List() @@ -127,8 +82,15 @@ func Ready(db *gorm.DB, e *events.Ready) { // 古い→新しい順に送信 slices.Reverse(targetItems) - channelID := snowflake.MustParse(rssSetting.ChannelID) - client := e.Client() + client, err := webhook.NewWithURL(rssSetting.WebhookURL) + if err != nil { + log.Print("Message create error:", err) + rssSetting.IsFailed = true + if err := repo.Update(rssSetting); err != nil { + log.Print("Update Record Failed", err) + } + continue + } for _, item := range targetItems { itemTitle := item.Title if itemTitle == "" { @@ -150,7 +112,7 @@ func Ready(db *gorm.DB, e *events.Ready) { "# %s に新しい記事が追加されました!\n## %s\n%s\nURL: %s", *feedTitle, itemTitle, itemDescription, itemLink, ) - _, err := client.Rest.CreateMessage(channelID, discord.NewMessageCreate().WithContent(message)) + _, err := client.CreateContent(message) if err != nil { log.Print("Message create error:", err) } diff --git a/src/internal/bot/handlers/interaction/command/general/rss/subscribe.go b/src/internal/bot/handlers/interaction/command/general/rss/subscribe.go index 9f2da91..5a7cbe6 100644 --- a/src/internal/bot/handlers/interaction/command/general/rss/subscribe.go +++ b/src/internal/bot/handlers/interaction/command/general/rss/subscribe.go @@ -3,6 +3,9 @@ package rss import ( "encoding/base64" "fmt" + "io" + "net/http" + "slices" "sort" "time" "unibot/internal" @@ -10,6 +13,7 @@ import ( "unibot/internal/repository" "unibot/internal/util" + "github.com/disgoorg/disgo/bot" "github.com/disgoorg/disgo/discord" "github.com/disgoorg/disgo/handler" ) @@ -35,6 +39,7 @@ func LoadSubscribeCommandContext() discord.ApplicationCommandOption { func Subscribe(ctx *internal.BotContext) func(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error { return func(data discord.SlashCommandInteractionData, e *handler.CommandEvent) error { + client := e.Client() config := ctx.Config if e.Channel().Type() == discord.ChannelTypeDM || e.Channel().Type() == discord.ChannelTypeGroupDM { @@ -51,7 +56,7 @@ func Subscribe(ctx *internal.BotContext) func(data discord.SlashCommandInteracti return &t }(), } - _, err := e.Client().Rest.CreateFollowupMessage(e.ApplicationID(), e.Token(), discord.NewMessageCreate().WithEmbeds(responseEmbed).WithEphemeral(true)) + _, err := client.Rest.CreateFollowupMessage(e.ApplicationID(), e.Token(), discord.NewMessageCreate().WithEmbeds(responseEmbed).WithEphemeral(true)) return err } @@ -72,7 +77,7 @@ func Subscribe(ctx *internal.BotContext) func(data discord.SlashCommandInteracti feed, err := util.FetchFeed(url) if err != nil { - return errorSubscribeResponse(config, e) + return errorSubscribeResponse(config, e, client) } if feed.Title != "" && title == nil { @@ -102,6 +107,50 @@ func Subscribe(ctx *internal.BotContext) func(data discord.SlashCommandInteracti }() } + var feedImage *discord.Icon + var feedImageURL string + if feed.Image != nil { + feedImageURL = feed.Image.URL + } + if feedImageURL != "" { + resp, err := util.HttpGet(feedImageURL) + if err != nil { + return errorSubscribeResponse(config, e, client) + } + defer resp.Body.Close() + imageBytes, err := io.ReadAll(io.LimitReader(resp.Body, 10*1024*1024)) + if err == nil { + mimeType := http.DetectContentType(imageBytes) + registeredMIME := []string{ + "image/jpeg", + "image/png", + "image/webp", + "image/avif", + "image/gif", + } + if slices.Contains(registeredMIME, mimeType) { + feedImage = discord.NewIconRaw(discord.IconType(mimeType), imageBytes) + } + } + } + + var webhookCreateOptions discord.WebhookCreate + if title != nil { + webhookCreateOptions = discord.WebhookCreate{ + Name: fmt.Sprintf("RSS - %s", *title), + Avatar: feedImage, + } + } else { + webhookCreateOptions = discord.WebhookCreate{ + Name: "RSSフィード", + Avatar: feedImage, + } + } + webhookURL, err := client.Rest.CreateWebhook(e.Channel().ID(), webhookCreateOptions) + if err != nil { + return errorSubscribeResponse(config, e, client) + } + db := ctx.DB guildRepo := repository.NewGuildRepository(db) if _, err := guildRepo.GetOrCreate(guildID.String()); err != nil { @@ -111,10 +160,12 @@ func Subscribe(ctx *internal.BotContext) func(data discord.SlashCommandInteracti if err := rssRepo.Create(&model.RSSSetting{ GuildID: guildID.String(), ChannelID: e.Channel().ID().String(), + WebhookURL: webhookURL.URL(), URL: url, Title: title, LastItemTitleDescriptionHash: hash, }); err != nil { + err := client.Rest.DeleteWebhook(webhookURL.ID()) return err } @@ -138,12 +189,12 @@ func Subscribe(ctx *internal.BotContext) func(data discord.SlashCommandInteracti return &t }(), } - _, err = e.Client().Rest.CreateFollowupMessage(e.ApplicationID(), e.Token(), discord.NewMessageCreate().WithEmbeds(responseEmbed).WithEphemeral(true)) + _, err = client.Rest.CreateFollowupMessage(e.ApplicationID(), e.Token(), discord.NewMessageCreate().WithEmbeds(responseEmbed).WithEphemeral(true)) return err } } -func errorSubscribeResponse(config *internal.Config, e *handler.CommandEvent) error { +func errorSubscribeResponse(config *internal.Config, e *handler.CommandEvent, client *bot.Client) error { responseEmbed := discord.Embed{ Title: "RSS購読", Description: "RSSフィードの取得に失敗しました。", @@ -157,6 +208,6 @@ func errorSubscribeResponse(config *internal.Config, e *handler.CommandEvent) er return &t }(), } - _, err := e.Client().Rest.CreateFollowupMessage(e.ApplicationID(), e.Token(), discord.NewMessageCreate().WithEmbeds(responseEmbed).WithEphemeral(true)) + _, err := client.Rest.CreateFollowupMessage(e.ApplicationID(), e.Token(), discord.NewMessageCreate().WithEmbeds(responseEmbed).WithEphemeral(true)) return err } diff --git a/src/internal/model/rss_setting.go b/src/internal/model/rss_setting.go index 62d0ac5..5addaa5 100644 --- a/src/internal/model/rss_setting.go +++ b/src/internal/model/rss_setting.go @@ -4,6 +4,7 @@ type RSSSetting struct { ID string `gorm:"primaryKey;size:255"` URL string `gorm:"not null"` ChannelID string `gorm:"not null"` + WebhookURL string `gorm:"not null"` Title *string `gorm:"null"` IsFailed bool `gorm:"default:false"` LastItemTitleDescriptionHash *string `gorm:"null"` diff --git a/src/internal/util/http.go b/src/internal/util/http.go new file mode 100644 index 0000000..c5faaff --- /dev/null +++ b/src/internal/util/http.go @@ -0,0 +1,154 @@ +package util + +import ( + "context" + "errors" + "fmt" + "net" + "net/http" + "net/url" + "time" +) + +func HttpGet(feedURL string) (*http.Response, error) { + parsedURL, err := url.Parse(feedURL) + if err != nil { + return nil, err + } + + if err := validateURL(parsedURL); err != nil { + return nil, err + } + + dialer := &net.Dialer{} + + transport := &http.Transport{ + DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { + host, port, err := net.SplitHostPort(addr) + if err != nil { + return nil, err + } + + ips, err := net.LookupIP(host) + if err != nil { + return nil, err + } + + if len(ips) == 0 { + return nil, errors.New("no ip found") + } + + for _, ip := range ips { + if isPrivateIP(ip) { + return nil, fmt.Errorf("private ip detected: %s", ip) + } + } + + return dialer.DialContext( + ctx, + network, + net.JoinHostPort(ips[0].String(), port), + ) + }, + } + defer transport.CloseIdleConnections() + + client := &http.Client{ + Timeout: 10 * time.Second, + Transport: transport, + CheckRedirect: func(req *http.Request, via []*http.Request) error { + if len(via) >= MaxRedirect { + return errors.New("too many redirects") + } + + return validateURL(req.URL) + }, + } + + resp, err := client.Get(feedURL) + if err != nil { + return nil, err + } + + if resp.StatusCode != http.StatusOK { + resp.Body.Close() + return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) + } + return resp, nil +} + +func validateURL(u *url.URL) error { + if u == nil { + return errors.New("nil url") + } + + if u.Scheme != "http" && u.Scheme != "https" { + return errors.New("invalid scheme") + } + + host := u.Hostname() + if host == "" { + return errors.New("missing host") + } + + ips, err := net.LookupIP(host) + if err != nil { + return err + } + + if len(ips) == 0 { + return errors.New("no ip found") + } + + for _, ip := range ips { + if isPrivateIP(ip) { + return fmt.Errorf("private address: %s", ip) + } + } + + port := u.Port() + if port != "" && port != "80" && port != "443" { + return fmt.Errorf("invalid port: %s", port) + } + + return nil +} + +func isPrivateIP(ip net.IP) bool { + if ipv4 := ip.To4(); ipv4 != nil { + ip = ipv4 + } + + privateCIDRs := []string{ + "0.0.0.0/8", + "127.0.0.0/8", + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + "169.254.0.0/16", + + "100.64.0.0/10", + "198.18.0.0/15", + "224.0.0.0/4", + "240.0.0.0/4", + + "::/128", + "::1/128", + "fc00::/7", + "ff00::/8", + "fe80::/10", + } + + for _, cidr := range privateCIDRs { + _, network, err := net.ParseCIDR(cidr) + if err != nil { + continue + } + + if network.Contains(ip) { + return true + } + } + + return false +} diff --git a/src/internal/util/rss_fetch.go b/src/internal/util/rss_fetch.go index 2a28bac..e832509 100644 --- a/src/internal/util/rss_fetch.go +++ b/src/internal/util/rss_fetch.go @@ -1,14 +1,7 @@ package util import ( - "context" - "errors" - "fmt" "io" - "net" - "net/http" - "net/url" - "time" "github.com/mmcdole/gofeed" ) @@ -19,70 +12,10 @@ const ( ) func FetchFeed(feedURL string) (*gofeed.Feed, error) { - parsedURL, err := url.Parse(feedURL) - if err != nil { - return nil, err - } - - if err := validateURL(parsedURL); err != nil { + resp, err := HttpGet(feedURL) + if err != nil || resp == nil { return nil, err } - - dialer := &net.Dialer{} - - transport := &http.Transport{ - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - host, port, err := net.SplitHostPort(addr) - if err != nil { - return nil, err - } - - ips, err := net.LookupIP(host) - if err != nil { - return nil, err - } - - if len(ips) == 0 { - return nil, errors.New("no ip found") - } - - for _, ip := range ips { - if isPrivateIP(ip) { - return nil, fmt.Errorf("private ip detected: %s", ip) - } - } - - return dialer.DialContext( - ctx, - network, - net.JoinHostPort(ips[0].String(), port), - ) - }, - } - defer transport.CloseIdleConnections() - - client := &http.Client{ - Timeout: 10 * time.Second, - Transport: transport, - CheckRedirect: func(req *http.Request, via []*http.Request) error { - if len(via) >= MaxRedirect { - return errors.New("too many redirects") - } - - return validateURL(req.URL) - }, - } - - resp, err := client.Get(feedURL) - if err != nil { - return nil, err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) - } - parser := gofeed.NewParser() feed, err := parser.Parse( @@ -94,79 +27,3 @@ func FetchFeed(feedURL string) (*gofeed.Feed, error) { return feed, nil } - -func validateURL(u *url.URL) error { - if u == nil { - return errors.New("nil url") - } - - if u.Scheme != "http" && u.Scheme != "https" { - return errors.New("invalid scheme") - } - - host := u.Hostname() - if host == "" { - return errors.New("missing host") - } - - ips, err := net.LookupIP(host) - if err != nil { - return err - } - - if len(ips) == 0 { - return errors.New("no ip found") - } - - for _, ip := range ips { - if isPrivateIP(ip) { - return fmt.Errorf("private address: %s", ip) - } - } - - port := u.Port() - if port != "" && port != "80" && port != "443" { - return fmt.Errorf("invalid port: %s", port) - } - - return nil -} - -func isPrivateIP(ip net.IP) bool { - if ipv4 := ip.To4(); ipv4 != nil { - ip = ipv4 - } - - privateCIDRs := []string{ - "0.0.0.0/8", - "127.0.0.0/8", - "10.0.0.0/8", - "172.16.0.0/12", - "192.168.0.0/16", - "169.254.0.0/16", - - "100.64.0.0/10", - "198.18.0.0/15", - "224.0.0.0/4", - "240.0.0.0/4", - - "::/128", - "::1/128", - "fc00::/7", - "ff00::/8", - "fe80::/10", - } - - for _, cidr := range privateCIDRs { - _, network, err := net.ParseCIDR(cidr) - if err != nil { - continue - } - - if network.Contains(ip) { - return true - } - } - - return false -}